Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package soapy-uhd for openSUSE:Factory checked in at 2026-10-05 16:18:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/soapy-uhd (Old) and /work/SRC/openSUSE:Factory/.soapy-uhd.new.3698736 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "soapy-uhd" Mon Oct 5 16:18:55 2026 rev:13 rq:1382552 version:0.4.1git20261004 Changes: -------- --- /work/SRC/openSUSE:Factory/soapy-uhd/soapy-uhd.changes 2026-09-01 15:48:04.430164423 +0200 +++ /work/SRC/openSUSE:Factory/.soapy-uhd.new.3698736/soapy-uhd.changes 2026-10-05 16:19:15.125841220 +0200 @@ -1,0 +2,35 @@ +Mon Oct 5 08:03:53 UTC 2026 - Martin Pluskal <[email protected]> + +- Update to 0.4.1git20261004 (a6134ed1), 14 new commits: + * Require UHD >= 4.0; upstream dropped the UHD 3.x code paths but + never landed its find_package(UHD 4.0) gate, so the spec's + pkgconfig(uhd) >= 4.0 floor is the only guard (SoapyUHD#72) + * Advertise the UHD 4.10 'mtu' stream argument (SoapyUHD#67), + handle UHD 4.10's EVENT_CODE_OK (SoapyUHD#70) and define + get_stream_info for UHD >= 4.11 (SoapyUHD#78) + * Map ERROR_CODE_LATE_COMMAND to SOAPY_SDR_TIME_ERROR instead of + SOAPY_SDR_STREAM_ERROR, so callers can tell timing failures + from generic stream errors (SoapyUHD#69) + * Fix hasIQBalanceMode() falling back to hasDCOffsetMode() + (SoapyUHD#69) + * Cache the stream channel count instead of making a virtual call + per packet in the read/write path (SoapyUHD#68) + * CMake: minimum 3.10, SoapySDR >= 0.7, target-scoped instead of + global compile flags (SoapyUHD#71) +- Drop boost.patch, boost-lexical-cast.patch and cxx17.patch: all + three adopted upstream (SoapyUHD#64, #69 and #70 respectively) +- Require pkgconfig(uhd) >= 4.0 and pkgconfig(SoapySDR) >= 0.7 +- BuildRequires: libboost_headers-devel replaces + libboost_chrono-devel, libboost_date_time-devel and + libboost_thread-devel; find_package(Boost) no longer requests + components +- Drop the CMAKE_POLICY_VERSION_MINIMUM=3.5 workaround: upstream + raised cmake_minimum_required to 3.10 +- Add a _service pinning the upstream git commit, and replace + soapy-uhd-0.4.1git20250213.tar.gz with + soapy-uhd-0.4.1git20261004.tar.gz: the GitHub archive Source URL + 404s for a date-based version +- Enable %check: run upstream's unit tests (15 hardware-free + cases), the package's only rpmlint warning + +------------------------------------------------------------------- Old: ---- boost-lexical-cast.patch boost.patch cxx17.patch soapy-uhd-0.4.1git20250213.tar.gz New: ---- _service soapy-uhd-0.4.1git20261004.tar.gz ----------(Old B)---------- Old: global compile flags (SoapyUHD#71) - Drop boost.patch, boost-lexical-cast.patch and cxx17.patch: all three adopted upstream (SoapyUHD#64, #69 and #70 respectively) Old: global compile flags (SoapyUHD#71) - Drop boost.patch, boost-lexical-cast.patch and cxx17.patch: all three adopted upstream (SoapyUHD#64, #69 and #70 respectively) Old: global compile flags (SoapyUHD#71) - Drop boost.patch, boost-lexical-cast.patch and cxx17.patch: all three adopted upstream (SoapyUHD#64, #69 and #70 respectively) ----------(Old E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ soapy-uhd.spec ++++++ --- /var/tmp/diff_new_pack.aQkgib/_old 2026-10-05 16:19:16.339891876 +0200 +++ /var/tmp/diff_new_pack.aQkgib/_new 2026-10-05 16:19:16.343892043 +0200 @@ -20,28 +20,27 @@ %define soapy_modver 0.8-3 %define soapy_modname soapysdr%{soapy_modver}-module-uhd Name: soapy-uhd -Version: 0.4.1git20250213 +Version: 0.4.1git20261004 Release: 0 Summary: Soapy SDR plugins for UHD supported SDR devices # The three built sources carry the deprecated SPDX id GPL-3.0, which maps -# to GPL-3.0-only; the only or-later grant is in CMakeLists.txt, not shipped. +# to GPL-3.0-only. Upstream set that id deliberately in commit ac3ce7f ("The +# intended license is GPL-3 to match libuhd license"); the files were +# BSL-1.0 before it. The only or-later wording in the tree is GNU Radio's, +# inherited into CMakeLists.txt, which is neither built nor shipped. License: GPL-3.0-only URL: https://github.com/pothosware/SoapyUHD/wiki #Git-Clone: https://github.com/pothosware/SoapyUHD.git -Source: https://github.com/pothosware/SoapyUHD/archive/%{name}-%{version}.tar.gz -Patch0: boost.patch -# PATCH-FIX-UPSTREAM cxx17.patch pothosware/SoapyUHD#75 - build with C++17 (UHD 4.x headers use std::optional / std::is_convertible_v) -Patch1: cxx17.patch -# PATCH-FIX-UPSTREAM boost-lexical-cast.patch pothosware/SoapyUHD#76 - include boost/lexical_cast.hpp explicitly (newer boost dropped the transitive include) -Patch2: boost-lexical-cast.patch +Source: %{name}-%{version}.tar.gz BuildRequires: cmake BuildRequires: gcc-c++ -BuildRequires: libboost_chrono-devel -BuildRequires: libboost_date_time-devel -BuildRequires: libboost_thread-devel +# upstream dropped BOOST_REQUIRED_COMPONENTS; only the headers are used now +BuildRequires: libboost_headers-devel BuildRequires: pkgconfig -BuildRequires: pkgconfig(SoapySDR) -BuildRequires: pkgconfig(uhd) +# CMakeLists.txt: find_package(SoapySDR "0.7" NO_MODULE REQUIRED) +BuildRequires: pkgconfig(SoapySDR) >= 0.7 +# SoapyUHD#72 dropped all UHD < 4.0 code paths +BuildRequires: pkgconfig(uhd) >= 4.0 %description Soapy UHD - Soapy SDR devices for UHD. @@ -63,15 +62,15 @@ A UHD module that supports Soapy devices within the UHD API. %prep -%autosetup -p1 -n SoapyUHD +%autosetup -p1 -n %{name}-%{version} %build -# Remove cmake4 error due to not setting -# min cmake version - sflees.de -export CMAKE_POLICY_VERSION_MINIMUM=3.5 %cmake %cmake_build +%check +%ctest + %install %cmake_install ++++++ _service ++++++ <services> <!-- upstream's newest tag is soapy-uhd-0.4.1 (2020-09-20); everything since then is unreleased, so pin a commit --> <service name="tar_scm" mode="manual"> <param name="url">https://github.com/pothosware/SoapyUHD.git</param> <param name="scm">git</param> <param name="revision">a6134ed1360df65e1bb4a52ac523efad9e39ab2f</param> <param name="versionformat">0.4.1git%cd</param> <param name="filename">soapy-uhd</param> <param name="changesgenerate">disable</param> </service> <service name="recompress" mode="manual"> <param name="file">*.tar</param> <param name="compression">gz</param> </service> </services> (No newline at EOF) ++++++ soapy-uhd-0.4.1git20250213.tar.gz -> soapy-uhd-0.4.1git20261004.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/.github/workflows/build.yml new/soapy-uhd-0.4.1git20261004/.github/workflows/build.yml --- old/SoapyUHD/.github/workflows/build.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/soapy-uhd-0.4.1git20261004/.github/workflows/build.yml 2026-10-04 19:53:23.000000000 +0200 @@ -0,0 +1,65 @@ +name: Build check +on: + push: + pull_request: + workflow_dispatch: + +jobs: + macos_macports_build_job: + strategy: + fail-fast: false + matrix: + os: [macos-15, macos-26] + runs-on: ${{ matrix.os }} + name: Build on ${{ matrix.os }} (macports) + steps: + - uses: actions/checkout@v7 + - uses: melusina-org/setup-macports@v1 + - name: Install ports + run: port install SoapySDR py310-setuptools uhd-devel + # Note: MacPorts uhd-devel depends on non-default boost181 + - name: Configure + run: BOOST_ROOT=/opt/local/libexec/boost/1.81 cmake -B build + - name: Build + run: cmake --build build + - name: Test + run: ctest --test-dir build --output-on-failure + + macos_homebrew_build_job: + strategy: + fail-fast: false + matrix: + os: [macos-15, macos-26] + runs-on: ${{ matrix.os }} + name: Build on ${{ matrix.os }} (homebrew) + steps: + - uses: actions/checkout@v7 + - name: Setup tools + run: brew install soapysdr uhd + - name: Configure + run: cmake -B build + - name: Build + run: cmake --build build + - name: Test + run: ctest --test-dir build --output-on-failure + + linux_build_job: + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04, ubuntu-24.04] + runs-on: ${{ matrix.os }} + name: Build on ${{ matrix.os }} + steps: + - uses: actions/checkout@v7 + - name: Setup tools + run: | + sudo apt-get update -q -y + sudo apt-get install -y --no-install-recommends cmake ninja-build + sudo apt-get install -q -y libsoapysdr-dev libuhd-dev + - name: Configure + run: cmake -GNinja -B build + - name: Build + run: cmake --build build + - name: Test + run: ctest --test-dir build --output-on-failure diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/.gitignore new/soapy-uhd-0.4.1git20261004/.gitignore --- old/SoapyUHD/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/soapy-uhd-0.4.1git20261004/.gitignore 2026-10-04 19:53:23.000000000 +0200 @@ -0,0 +1 @@ +/build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/.travis.yml new/soapy-uhd-0.4.1git20261004/.travis.yml --- old/SoapyUHD/.travis.yml 2021-05-01 11:16:23.067447504 +0200 +++ new/soapy-uhd-0.4.1git20261004/.travis.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,60 +0,0 @@ -######################################################################## -## Travis CI config for SoapyUHD -## -## * installs UHD from PPA -## * installs SoapySDR from source -## * matrix tests multiple UHD versions -## * confirms build and install -## * checks that drivers load -######################################################################## - -sudo: required -dist: focal - -language: cpp -compiler: gcc - -env: - global: - - INSTALL_PREFIX=/usr/local - - SOAPY_SDR_BRANCH=master - matrix: - - BUILD_TYPE=Debug - - BUILD_TYPE=Release - -before_install: - # regular ubuntu packages - - sudo add-apt-repository main - - sudo add-apt-repository universe - - # driver development files from ppa - - sudo add-apt-repository -y ppa:ettusresearch/uhd - - # update after package changes - - sudo apt-get update - -install: - #boost development files - - sudo apt-get install -qq libboost-all-dev - - #sdr development files - - sudo apt-get install --no-install-recommends -q -y libuhd-dev - - # install SoapySDR from source - - git clone https://github.com/pothosware/SoapySDR.git - - pushd SoapySDR - - git checkout ${SOAPY_SDR_BRANCH} - - mkdir build && cd build - - cmake ../ -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_PYTHON=OFF -DENABLE_PYTHON3=OFF - - make && sudo make install - - popd - -script: - - mkdir build && cd build - - cmake ../ -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} - - make && sudo make install - # print info about the install - - export LD_LIBRARY_PATH=${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH} - - export PATH=${INSTALL_PREFIX}/bin:${PATH} - - SoapySDRUtil --info - - SoapySDRUtil --check=uhd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/CMakeLists.txt new/soapy-uhd-0.4.1git20261004/CMakeLists.txt --- old/SoapyUHD/CMakeLists.txt 2021-11-16 23:31:11.009881523 +0100 +++ new/soapy-uhd-0.4.1git20261004/CMakeLists.txt 2026-10-04 19:53:23.000000000 +0200 @@ -21,23 +21,40 @@ ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 3.10...3.30) project(SoapyUHD CXX C) enable_testing() -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) + +option(BUILD_UHD_SUPPORT "Build the SoapySDR-side module exposing UHD devices to SoapySDR" ON) +option(BUILD_SOAPY_SUPPORT "Build the UHD-side module exposing Soapy devices to UHD" ON) + +if(NOT BUILD_UHD_SUPPORT AND NOT BUILD_SOAPY_SUPPORT) + message(FATAL_ERROR "Both BUILD_UHD_SUPPORT and BUILD_SOAPY_SUPPORT are OFF -- nothing to build.") +endif() #select the release build type by default to get optimization flags if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release") - message(STATUS "Build type not specified: defaulting to release.") + set(CMAKE_BUILD_TYPE "Release") + message(STATUS "Build type not specified: defaulting to release.") endif(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") ######################################################################## +# Setup SoapySDR and set default modules location +######################################################################## +find_package(SoapySDR "0.7" NO_MODULE REQUIRED) + +get_filename_component(_SoapySDR_ROOT "${SoapySDR_INCLUDE_DIRS}/.." ABSOLUTE) +message(STATUS "SoapySDR root directory: ${_SoapySDR_ROOT}") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND NOT "${_SoapySDR_ROOT}" STREQUAL "/usr") + set_property(CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE ${_SoapySDR_ROOT}) +endif() + +######################################################################## # Dependencies ######################################################################## -find_package(SoapySDR "0.6" NO_MODULE REQUIRED) find_package(UHD NO_MODULE) #try old-style find script @@ -47,8 +64,7 @@ endif() if (NOT UHD_FOUND) - message(WARNING "UHD not found -- required for Soapy UHD support") - return() + message(FATAL_ERROR "UHD not found -- required for Soapy UHD support") endif() if (NOT UHD_ROOT) @@ -57,10 +73,9 @@ message(STATUS "UHD root directory: ${UHD_ROOT}") message(STATUS "UHD include directories: ${UHD_INCLUDE_DIRS}") message(STATUS "UHD libraries: ${UHD_LIBRARIES}") +message(STATUS "UHD version: ${UHD_VERSION}") -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${SoapySDR_INCLUDE_DIRS}) -include_directories(${UHD_INCLUDE_DIRS}) +set(UHD_FEATURE_DEFS "") message(STATUS "Checking uhd::device::register_device() API...") message(STATUS " Reading ${UHD_INCLUDE_DIRS}/uhd/device.hpp...") @@ -69,7 +84,7 @@ if ("${has_device_filter}" STREQUAL "-1") message(STATUS " has original API") else() - add_definitions(-DUHD_HAS_DEVICE_FILTER) + list(APPEND UHD_FEATURE_DEFS UHD_HAS_DEVICE_FILTER) message(STATUS " has filter API") endif() @@ -80,7 +95,7 @@ if ("${has_set_rx_agc}" STREQUAL "-1") message(STATUS " missing set_rx_agc() API") else() - add_definitions(-DUHD_HAS_SET_RX_AGC) + list(APPEND UHD_FEATURE_DEFS UHD_HAS_SET_RX_AGC) message(STATUS " has set_rx_agc() API") endif() @@ -91,80 +106,75 @@ if ("${has_set_publisher}" STREQUAL "-1") message(STATUS " missing set_publisher() API") else() - add_definitions(-DUHD_HAS_SET_PUBLISHER) + list(APPEND UHD_FEATURE_DEFS UHD_HAS_SET_PUBLISHER) message(STATUS " has set_publisher() API") endif() if (EXISTS "${UHD_INCLUDE_DIRS}/uhd/utils/msg.hpp") - add_definitions(-DUHD_HAS_MSG_HPP) + list(APPEND UHD_FEATURE_DEFS UHD_HAS_MSG_HPP) message(STATUS " use msg.hpp for logging") else() message(STATUS " use log.hpp for logging") endif() ######################################################################## -# Setup boost +# Setup Boost ######################################################################## MESSAGE(STATUS "Configuring Boost C++ Libraries...") -# Although not required on my system, some users have linking issues without -SET(BOOST_REQUIRED_COMPONENTS - thread - system -) - if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix endif(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") -set(Boost_ADDITIONAL_VERSIONS - "1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39" - "1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44" - "1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49" - "1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54" - "1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59" - "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64" - "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69" -) - -find_package(Boost COMPONENTS ${BOOST_REQUIRED_COMPONENTS}) +find_package(Boost) if(NOT Boost_FOUND) - message(WARNING "Boost required to build -- ignoring uhd support") - return() + message(FATAL_ERROR "Boost not found -- required for Soapy UHD support") endif() -ADD_DEFINITIONS(-DBOOST_ALL_DYN_LINK) - -include_directories(${Boost_INCLUDE_DIRS}) -link_directories(${Boost_LIBRARY_DIRS}) +list(APPEND UHD_FEATURE_DEFS BOOST_ALL_DYN_LINK) message(STATUS "Boost include directories: ${Boost_INCLUDE_DIRS}") message(STATUS "Boost library directories: ${Boost_LIBRARY_DIRS}") message(STATUS "Boost libraries: ${Boost_LIBRARIES}") +set(SOAPY_UHD_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + ${SoapySDR_INCLUDE_DIRS} + ${UHD_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} +) + ######################################################################## # Build a Soapy module to support UHD devices ######################################################################## -SOAPY_SDR_MODULE_UTIL( - TARGET uhdSupport - SOURCES SoapyUHDDevice.cpp - LIBRARIES - ${UHD_LIBRARIES} - ${Boost_LIBRARIES} -) +if(BUILD_UHD_SUPPORT) + SOAPY_SDR_MODULE_UTIL( + TARGET uhdSupport + SOURCES SoapyUHDDevice.cpp + LIBRARIES + ${UHD_LIBRARIES} + ${Boost_LIBRARIES} + ) + target_include_directories(uhdSupport PRIVATE ${SOAPY_UHD_INCLUDE_DIRS}) + target_compile_definitions(uhdSupport PRIVATE ${UHD_FEATURE_DEFS}) +endif() ######################################################################## # Build a UHD module to support Soapy devices ######################################################################## -add_library(soapySupport MODULE UHDSoapyDevice.cpp) -target_link_libraries(soapySupport - ${UHD_LIBRARIES} - ${SoapySDR_LIBRARIES} - ${Boost_LIBRARIES}) -install(TARGETS soapySupport - DESTINATION ${UHD_ROOT}/lib${LIB_SUFFIX}/uhd/modules -) +if(BUILD_SOAPY_SUPPORT) + add_library(soapySupport MODULE UHDSoapyDevice.cpp) + target_include_directories(soapySupport PRIVATE ${SOAPY_UHD_INCLUDE_DIRS}) + target_compile_definitions(soapySupport PRIVATE ${UHD_FEATURE_DEFS}) + target_link_libraries(soapySupport + ${UHD_LIBRARIES} + ${SoapySDR_LIBRARIES} + ${Boost_LIBRARIES}) + install(TARGETS soapySupport + DESTINATION ${UHD_ROOT}/lib${LIB_SUFFIX}/uhd/modules + ) +endif() ######################################################################## # rpath setup - http://www.cmake.org/Wiki/CMake_RPATH_handling @@ -194,6 +204,11 @@ endif() ######################################################################## +# Tests +######################################################################## +add_subdirectory(tests) + +######################################################################## # Print Summary ######################################################################## MESSAGE(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/README.md new/soapy-uhd-0.4.1git20261004/README.md --- old/SoapyUHD/README.md 2019-12-14 15:05:27.038913815 +0100 +++ new/soapy-uhd-0.4.1git20261004/README.md 2026-10-04 19:53:23.000000000 +0200 @@ -1,9 +1,5 @@ # Soapy SDR plugins for UHD devices -## Build Status - -- Travis: [](https://travis-ci.org/pothosware/SoapyUHD) - ## Dependencies * UHD - https://github.com/EttusResearch/uhd/wiki diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/SoapyUHDDevice.cpp new/soapy-uhd-0.4.1git20261004/SoapyUHDDevice.cpp --- old/SoapyUHD/SoapyUHDDevice.cpp 2021-11-11 19:48:36.308031092 +0100 +++ new/soapy-uhd-0.4.1git20261004/SoapyUHDDevice.cpp 2026-10-04 19:53:23.000000000 +0200 @@ -12,14 +12,11 @@ #include <SoapySDR/Logger.hpp> #include <uhd/version.hpp> #include <uhd/device.hpp> -#ifdef UHD_HAS_MSG_HPP -#include <uhd/utils/msg.hpp> -#else #include <uhd/utils/log_add.hpp> -#endif #include <uhd/usrp/multi_usrp.hpp> #include <uhd/property_tree.hpp> #include <uhd/version.hpp> +#include <boost/lexical_cast.hpp> #include <cctype> #include <iostream> @@ -30,6 +27,7 @@ { uhd::rx_streamer::sptr rx; uhd::tx_streamer::sptr tx; + size_t num_channels = 0; }; /*********************************************************************** @@ -219,6 +217,17 @@ streamArgs.push_back(underflowPolicyArg); } +#if UHD_VERSION >= 4100000 + SoapySDR::ArgInfo mtuArg; + mtuArg.key = "mtu"; + mtuArg.value = "0"; + mtuArg.name = "Override link MTU"; + mtuArg.description = "Override the auto-detected link MTU (UHD >= 4.10). 0 = use detected value."; + mtuArg.units = "bytes"; + mtuArg.type = SoapySDR::ArgInfo::INT; + streamArgs.push_back(mtuArg); +#endif + return streamArgs; } @@ -242,8 +251,16 @@ //create streamers SoapyUHDStream *stream = new SoapyUHDStream(); - if (dir == SOAPY_SDR_TX) stream->tx = _dev->get_tx_stream(stream_args); - if (dir == SOAPY_SDR_RX) stream->rx = _dev->get_rx_stream(stream_args); + if (dir == SOAPY_SDR_TX) + { + stream->tx = _dev->get_tx_stream(stream_args); + stream->num_channels = stream->tx->get_num_channels(); + } + if (dir == SOAPY_SDR_RX) + { + stream->rx = _dev->get_rx_stream(stream_args); + stream->num_channels = stream->rx->get_num_channels(); + } return reinterpret_cast<SoapySDR::Stream *>(stream); } @@ -300,11 +317,12 @@ int readStream(SoapySDR::Stream *handle, void * const *buffs, const size_t numElems, int &flags, long long &timeNs, const long timeoutUs) { - uhd::rx_streamer::sptr &stream = reinterpret_cast<SoapyUHDStream *>(handle)->rx; + SoapyUHDStream *streamObj = reinterpret_cast<SoapyUHDStream *>(handle); + uhd::rx_streamer::sptr &stream = streamObj->rx; //receive into buffers and metadata uhd::rx_metadata_t md; - uhd::rx_streamer::buffs_type stream_buffs(buffs, stream->get_num_channels()); + uhd::rx_streamer::buffs_type stream_buffs(buffs, streamObj->num_channels); int ret = stream->recv(stream_buffs, numElems, md, timeoutUs/1e6, (flags & SOAPY_SDR_ONE_PACKET) != 0); //parse the metadata @@ -320,7 +338,7 @@ case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: return SOAPY_SDR_TIMEOUT; case uhd::rx_metadata_t::ERROR_CODE_BAD_PACKET: return SOAPY_SDR_CORRUPTION; case uhd::rx_metadata_t::ERROR_CODE_ALIGNMENT: return SOAPY_SDR_CORRUPTION; - case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: return SOAPY_SDR_STREAM_ERROR; + case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: return SOAPY_SDR_TIME_ERROR; case uhd::rx_metadata_t::ERROR_CODE_BROKEN_CHAIN: return SOAPY_SDR_STREAM_ERROR; } return ret; @@ -328,7 +346,8 @@ int writeStream(SoapySDR::Stream *handle, const void * const *buffs, const size_t numElems, int &flags, const long long timeNs, const long timeoutUs) { - uhd::tx_streamer::sptr &stream = reinterpret_cast<SoapyUHDStream *>(handle)->tx; + SoapyUHDStream *streamObj = reinterpret_cast<SoapyUHDStream *>(handle); + uhd::tx_streamer::sptr &stream = streamObj->tx; //load metadata uhd::tx_metadata_t md; @@ -337,7 +356,7 @@ md.time_spec = uhd::time_spec_t::from_ticks(timeNs, 1e9); //send buffers and metadata - uhd::tx_streamer::buffs_type stream_buffs(buffs, stream->get_num_channels()); + uhd::tx_streamer::buffs_type stream_buffs(buffs, streamObj->num_channels); int ret = stream->send(stream_buffs, numElems, md, timeoutUs/1e6); flags = 0; @@ -361,6 +380,9 @@ switch (md.event_code) { +#if UHD_VERSION >= 4100000 + case uhd::async_metadata_t::EVENT_CODE_OK: break; +#endif case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: flags |= SOAPY_SDR_END_BURST; break; case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: return SOAPY_SDR_UNDERFLOW; case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR: return SOAPY_SDR_CORRUPTION; @@ -507,7 +529,7 @@ return __doesMBoardFEPropTreeEntryExist(dir, channel, "iq_balance/enable"); } - return SoapySDR::Device::hasDCOffsetMode(dir, channel); + return SoapySDR::Device::hasIQBalanceMode(dir, channel); } void setIQBalanceMode(const int dir, const size_t channel, const bool automatic) @@ -545,21 +567,17 @@ bool hasGainMode(const int dir, const size_t channel) const { - #ifdef UHD_HAS_SET_RX_AGC if (dir == SOAPY_SDR_TX) return false; if (dir == SOAPY_SDR_RX) { return __doesDBoardFEPropTreeEntryExist(dir, channel, "gain/agc/enable"); } - #endif return SoapySDR::Device::hasGainMode(dir, channel); } void setGainMode(const int dir, const size_t channel, const bool automatic) { - #ifdef UHD_HAS_SET_RX_AGC if (dir == SOAPY_SDR_RX) return _dev->set_rx_agc(automatic, channel); - #endif return SoapySDR::Device::setGainMode(dir, channel, automatic); } @@ -1043,11 +1061,7 @@ uhd::property_tree::sptr _get_tree(void) const { - #if UHD_VERSION >= 4000000 return _dev->get_tree(); - #else - return _dev->get_device()->get_tree(); - #endif } uhd::usrp::multi_usrp::sptr _dev; @@ -1058,20 +1072,6 @@ /*********************************************************************** * Register into logger **********************************************************************/ -#ifdef UHD_HAS_MSG_HPP -static void SoapyUHDLogger(uhd::msg::type_t t, const std::string &s) -{ - if (s.empty()) return; - if (s[s.size()-1] == '\n') return SoapyUHDLogger(t, s.substr(0, s.size()-1)); - switch (t) - { - case uhd::msg::status: SoapySDR::log(SOAPY_SDR_INFO, s); break; - case uhd::msg::warning: SoapySDR::log(SOAPY_SDR_WARNING, s); break; - case uhd::msg::error: SoapySDR::log(SOAPY_SDR_ERROR, s); break; - case uhd::msg::fastpath: SoapySDR::log(SOAPY_SDR_SSI, s); break; - } -} -#else static void SoapyUHDLogger(const uhd::log::logging_info &info) { //build a log message formatted from the information @@ -1101,7 +1101,6 @@ default: break; } } -#endif /*********************************************************************** * Registration @@ -1114,11 +1113,7 @@ args[SOAPY_UHD_NO_DEEPER] = ""; //perform the discovery - #ifdef UHD_HAS_DEVICE_FILTER const uhd::device_addrs_t addrs = uhd::device::find(kwargsToDict(args), uhd::device::USRP); - #else - const uhd::device_addrs_t addrs = uhd::device::find(kwargsToDict(args)); - #endif //convert addrs to results std::vector<SoapySDR::Kwargs> results; @@ -1151,11 +1146,7 @@ "Suggestion: install an ABI compatible version of UHD,\n" "or rebuild SoapySDR UHD support against this ABI version.\n" ) % UHD_VERSION_ABI_STRING % uhd::get_abi_string())); - #ifdef UHD_HAS_MSG_HPP - uhd::msg::register_handler(&SoapyUHDLogger); - #else uhd::log::add_logger("SoapyUHDDevice", &SoapyUHDLogger); - #endif return new SoapyUHDDevice(uhd::usrp::multi_usrp::make(kwargsToDict(args)), args); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/TypeHelpers.hpp new/soapy-uhd-0.4.1git20261004/TypeHelpers.hpp --- old/SoapyUHD/TypeHelpers.hpp 2019-12-14 15:05:27.038913815 +0100 +++ new/soapy-uhd-0.4.1git20261004/TypeHelpers.hpp 2026-10-04 19:53:23.000000000 +0200 @@ -40,11 +40,7 @@ SoapySDR::RangeList out; for (size_t i = 0; i < metaRange.size(); i++) { - #ifdef SOAPY_SDR_API_HAS_RANGE_TYPE_STEP out.push_back(SoapySDR::Range(metaRange[i].start(), metaRange[i].stop(), metaRange[i].step())); - #else - out.push_back(SoapySDR::Range(metaRange[i].start(), metaRange[i].stop())); - #endif } return out; } @@ -54,11 +50,7 @@ uhd::meta_range_t out; for (size_t i = 0; i < ranges.size(); i++) { - #ifdef SOAPY_SDR_API_HAS_RANGE_TYPE_STEP out.push_back(uhd::range_t(ranges[i].minimum(), ranges[i].maximum(), ranges[i].step())); - #else - out.push_back(uhd::range_t(ranges[i].minimum(), ranges[i].maximum())); - #endif } if (out.empty()) out.push_back(uhd::range_t(0.0)); return out; @@ -66,11 +58,7 @@ static inline SoapySDR::Range metaRangeToRange(const uhd::meta_range_t &metaRange) { - #ifdef SOAPY_SDR_API_HAS_RANGE_TYPE_STEP return SoapySDR::Range(metaRange.start(), metaRange.stop(), metaRange.step()); - #else - return SoapySDR::Range(metaRange.start(), metaRange.stop()); - #endif } static inline uhd::meta_range_t numberListToMetaRange(const std::vector<double> &nums) @@ -106,10 +94,8 @@ static inline uhd::meta_range_t rangeToMetaRange(const SoapySDR::Range &range, double step = 0.0) { - //when range step is supported, use it only if initialized to non-zero - #ifdef SOAPY_SDR_API_HAS_RANGE_TYPE_STEP + //use range.step() if initialized to non-zero if (range.step() != 0.0) step = range.step(); - #endif return uhd::meta_range_t(range.minimum(), range.maximum(), step); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/UHDSoapyDevice.cpp new/soapy-uhd-0.4.1git20261004/UHDSoapyDevice.cpp --- old/SoapyUHD/UHDSoapyDevice.cpp 2025-02-15 15:13:25.185218036 +0100 +++ new/soapy-uhd-0.4.1git20261004/UHDSoapyDevice.cpp 2026-10-04 19:53:23.000000000 +0200 @@ -2,11 +2,6 @@ // Copyright (c) 2018 Deepwave Digital, Inc. // SPDX-License-Identifier: GPL-3.0 -#ifdef UHD_HAS_SET_PUBLISHER -#define publish set_publisher -#define subscribe add_desired_subscriber -#endif - /*********************************************************************** * A UHD module that supports Soapy devices within the UHD API. **********************************************************************/ @@ -17,11 +12,7 @@ #include <uhd/version.hpp> #include <uhd/device.hpp> #include <uhd/convert.hpp> -#ifdef UHD_HAS_MSG_HPP -#include <uhd/utils/msg.hpp> -#else #include <uhd/utils/log.hpp> -#endif #include <uhd/types/sensors.hpp> #include <uhd/types/ranges.hpp> #include <uhd/usrp/mboard_eeprom.hpp> @@ -35,6 +26,7 @@ #include <boost/format.hpp> #include <boost/thread/mutex.hpp> #include <boost/bind.hpp> +#include <boost/lexical_cast.hpp> #include <boost/weak_ptr.hpp> #include <boost/algorithm/string.hpp> @@ -111,20 +103,12 @@ uhd::meta_range_t get_bw_range(const int dir, const size_t chan) { - #ifdef SOAPY_SDR_API_HAS_GET_BANDWIDTH_RANGE return rangeListToMetaRange(_device->getBandwidthRange(dir, chan)); - #else - return numberListToMetaRange(_device->listBandwidths(dir, chan)); - #endif } uhd::meta_range_t get_rate_range(const int dir, const size_t chan) { - #ifdef SOAPY_SDR_API_HAS_GET_SAMPLE_RATE_RANGE return rangeListToMetaRange(_device->getSampleRateRange(dir, chan)); - #else - return numberListToMetaRange(_device->listSampleRates(dir, chan)); - #endif } void set_sample_rate(const int dir, const size_t chan, const double rate) @@ -181,13 +165,8 @@ std::map<int, std::map<size_t, double>> _sampleRates; //stash streamers to implement old-style issue stream cmd and async message - #if UHD_VERSION >= 4000000 std::map<size_t, std::weak_ptr<uhd::rx_streamer> > _rx_streamers; std::map<size_t, std::weak_ptr<uhd::tx_streamer> > _tx_streamers; - #else - std::map<size_t, boost::weak_ptr<uhd::rx_streamer> > _rx_streamers; - std::map<size_t, boost::weak_ptr<uhd::tx_streamer> > _tx_streamers; - #endif }; /*********************************************************************** @@ -224,45 +203,45 @@ //the frontend mapping _tree->create<uhd::usrp::subdev_spec_t>(mb_path / "rx_subdev_spec") - .publish(boost::bind(&UHDSoapyDevice::get_frontend_mapping, this, SOAPY_SDR_RX)) - .subscribe(boost::bind(&UHDSoapyDevice::set_frontend_mapping, this, SOAPY_SDR_RX, _1)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_frontend_mapping, this, SOAPY_SDR_RX)) + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_frontend_mapping, this, SOAPY_SDR_RX, _1)); _tree->create<uhd::usrp::subdev_spec_t>(mb_path / "tx_subdev_spec") - .publish(boost::bind(&UHDSoapyDevice::get_frontend_mapping, this, SOAPY_SDR_TX)) - .subscribe(boost::bind(&UHDSoapyDevice::set_frontend_mapping, this, SOAPY_SDR_TX, _1)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_frontend_mapping, this, SOAPY_SDR_TX)) + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_frontend_mapping, this, SOAPY_SDR_TX, _1)); //timed command support _tree->create<uhd::time_spec_t>(mb_path / "time" / "cmd") - .subscribe(boost::bind(&UHDSoapyDevice::set_hardware_time, this, "CMD", _1)); + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_hardware_time, this, "CMD", _1)); _tree->create<double>(mb_path / "tick_rate") - .publish(boost::bind(&SoapySDR::Device::getMasterClockRate, _device)) - .subscribe(boost::bind(&SoapySDR::Device::setMasterClockRate, _device, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getMasterClockRate, _device)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setMasterClockRate, _device, _1)); //hardware time support _tree->create<uhd::time_spec_t>(mb_path / "time" / "now") - .publish(boost::bind(&UHDSoapyDevice::get_hardware_time, this, "")) - .subscribe(boost::bind(&UHDSoapyDevice::set_hardware_time, this, "", _1)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_hardware_time, this, "")) + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_hardware_time, this, "", _1)); _tree->create<uhd::time_spec_t>(mb_path / "time" / "pps") - .publish(boost::bind(&UHDSoapyDevice::get_hardware_time, this, "PPS")) - .subscribe(boost::bind(&UHDSoapyDevice::set_hardware_time, this, "PPS", _1)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_hardware_time, this, "PPS")) + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_hardware_time, this, "PPS", _1)); //clock and time sources _tree->create<std::vector<std::string> >(mb_path / "clock_source"/ "options") - .publish(boost::bind(&SoapySDR::Device::listClockSources, _device)); + .set_publisher(boost::bind(&SoapySDR::Device::listClockSources, _device)); _tree->create<std::string>(mb_path / "clock_source" / "value") - .publish(boost::bind(&SoapySDR::Device::getClockSource, _device)) - .subscribe(boost::bind(&SoapySDR::Device::setClockSource, _device, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getClockSource, _device)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setClockSource, _device, _1)); _tree->create<std::vector<std::string> >(mb_path / "time_source"/ "options") - .publish(boost::bind(&SoapySDR::Device::listTimeSources, _device)); + .set_publisher(boost::bind(&SoapySDR::Device::listTimeSources, _device)); _tree->create<std::string>(mb_path / "time_source" / "value") - .publish(boost::bind(&SoapySDR::Device::getTimeSource, _device)) - .subscribe(boost::bind(&SoapySDR::Device::setTimeSource, _device, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getTimeSource, _device)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setTimeSource, _device, _1)); //mboard sensors _tree->create<int>(mb_path / "sensors"); //ensure this path exists for(const std::string &name : _device->listSensors()) { _tree->create<uhd::sensor_value_t>(mb_path / "sensors" / name) - .publish(boost::bind(&UHDSoapyDevice::get_mboard_sensor, this, name)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_mboard_sensor, this, name)); } //gpio banks @@ -280,8 +259,8 @@ for(const std::string &attr : attrs) { _tree->create<boost::uint32_t>(mb_path / "gpio" / bank / attr) - .subscribe(boost::bind(&UHDSoapyDevice::set_gpio_attr, this, bank, attr, _1)) - .publish(boost::bind(&UHDSoapyDevice::get_gpio_attr, this, bank, attr)); + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_gpio_attr, this, bank, attr, _1)) + .set_publisher(boost::bind(&UHDSoapyDevice::get_gpio_attr, this, bank, attr)); } } @@ -342,10 +321,10 @@ //samp rate _tree->create<uhd::meta_range_t>(dsp_path / "rate" / "range") - .publish(boost::bind(&UHDSoapyDevice::get_rate_range, this, dir, chan)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_rate_range, this, dir, chan)); _tree->create<double>(dsp_path / "rate" / "value") - .publish(boost::bind(&SoapySDR::Device::getSampleRate, _device, dir, chan)) - .subscribe(boost::bind(&UHDSoapyDevice::set_sample_rate, this, dir, chan, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getSampleRate, _device, dir, chan)) + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_sample_rate, this, dir, chan, _1)); //dsp freq (when there is no tunable cordic) if (bbCompName.empty()) @@ -357,17 +336,17 @@ else { _tree->create<double>(dsp_path / "freq" / "value") - .publish(boost::bind(&SoapySDR::Device::getFrequency, _device, dir, chan, bbCompName)) - .subscribe(boost::bind(&UHDSoapyDevice::set_frequency, this, dir, chan, bbCompName, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getFrequency, _device, dir, chan, bbCompName)) + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_frequency, this, dir, chan, bbCompName, _1)); _tree->create<uhd::meta_range_t>(dsp_path / "freq" / "range") - .publish(boost::bind(&UHDSoapyDevice::get_freq_range, this, dir, chan, bbCompName)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_freq_range, this, dir, chan, bbCompName)); } //old style stream cmd if (dir == SOAPY_SDR_RX) { _tree->create<uhd::stream_cmd_t>(dsp_path / "stream_cmd") - .subscribe(boost::bind(&UHDSoapyDevice::old_issue_stream_cmd, this, chan, _1)); + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::old_issue_stream_cmd, this, chan, _1)); } //frontend sensors @@ -376,7 +355,7 @@ { //install the sensor _tree->create<uhd::sensor_value_t>(rf_fe_path / "sensors" / name) - .publish(boost::bind(&UHDSoapyDevice::get_channel_sensor, this, dir, chan, name)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_channel_sensor, this, dir, chan, name)); } //dummy eeprom values @@ -397,71 +376,69 @@ for(const std::string &name : _device->listGains(dir, chan)) { _tree->create<uhd::meta_range_t>(rf_fe_path / "gains" / name / "range") - .publish(boost::bind(&UHDSoapyDevice::get_gain_range, this, dir, chan, name)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_gain_range, this, dir, chan, name)); _tree->create<double>(rf_fe_path / "gains" / name / "value") - .publish(boost::bind(&SoapySDR::Device::getGain, _device, dir, chan, name)) - .subscribe(boost::bind(&SoapySDR::Device::setGain, _device, dir, chan, name, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getGain, _device, dir, chan, name)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setGain, _device, dir, chan, name, _1)); } //agc _tree->create<bool>(rf_fe_path / "gain" / "agc" / "enable") - .publish(boost::bind(&SoapySDR::Device::getGainMode, _device, dir, chan)) - .subscribe(boost::bind(&SoapySDR::Device::setGainMode, _device, dir, chan, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getGainMode, _device, dir, chan)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setGainMode, _device, dir, chan, _1)); //freq _tree->create<double>(rf_fe_path / "freq" / "value") - .publish(boost::bind(&SoapySDR::Device::getFrequency, _device, dir, chan, rfCompName)) - .subscribe(boost::bind(&UHDSoapyDevice::set_frequency, this, dir, chan, rfCompName, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getFrequency, _device, dir, chan, rfCompName)) + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::set_frequency, this, dir, chan, rfCompName, _1)); _tree->create<uhd::meta_range_t>(rf_fe_path / "freq" / "range") - .publish(boost::bind(&UHDSoapyDevice::get_freq_range, this, dir, chan, rfCompName)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_freq_range, this, dir, chan, rfCompName)); _tree->create<bool>(rf_fe_path / "use_lo_offset").set(false); _tree->create<uhd::device_addr_t>(rf_fe_path / "tune_args") - .subscribe(boost::bind(&UHDSoapyDevice::stash_tune_args, this, dir, chan, _1)); + .add_desired_subscriber(boost::bind(&UHDSoapyDevice::stash_tune_args, this, dir, chan, _1)); //ant _tree->create<std::vector<std::string> >(rf_fe_path / "antenna" / "options") - .publish(boost::bind(&SoapySDR::Device::listAntennas, _device, dir, chan)); + .set_publisher(boost::bind(&SoapySDR::Device::listAntennas, _device, dir, chan)); _tree->create<std::string>(rf_fe_path / "antenna" / "value") - .publish(boost::bind(&SoapySDR::Device::getAntenna, _device, dir, chan)) - .subscribe(boost::bind(&SoapySDR::Device::setAntenna, _device, dir, chan, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getAntenna, _device, dir, chan)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setAntenna, _device, dir, chan, _1)); //bw _tree->create<double>(rf_fe_path / "bandwidth" / "value") - .publish(boost::bind(&SoapySDR::Device::getBandwidth, _device, dir, chan)) - .subscribe(boost::bind(&SoapySDR::Device::setBandwidth, _device, dir, chan, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getBandwidth, _device, dir, chan)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setBandwidth, _device, dir, chan, _1)); _tree->create<uhd::meta_range_t>(rf_fe_path / "bandwidth" / "range") - .publish(boost::bind(&UHDSoapyDevice::get_bw_range, this, dir, chan)); + .set_publisher(boost::bind(&UHDSoapyDevice::get_bw_range, this, dir, chan)); //corrections if (_device->hasDCOffsetMode(dir, chan)) { _tree->create<bool>(rf_fe_path / "dc_offset" / "enable") - .publish(boost::bind(&SoapySDR::Device::getDCOffsetMode, _device, dir, chan)) - .subscribe(boost::bind(&SoapySDR::Device::setDCOffsetMode, _device, dir, chan, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getDCOffsetMode, _device, dir, chan)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setDCOffsetMode, _device, dir, chan, _1)); } if (_device->hasDCOffset(dir, chan)) { _tree->create<std::complex<double>>(rf_fe_path / "dc_offset" / "value") - .publish(boost::bind(&SoapySDR::Device::getDCOffset, _device, dir, chan)) - .subscribe(boost::bind(&SoapySDR::Device::setDCOffset, _device, dir, chan, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getDCOffset, _device, dir, chan)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setDCOffset, _device, dir, chan, _1)); } if (_device->hasIQBalance(dir, chan)) { _tree->create<std::complex<double>>(rf_fe_path / "iq_balance" / "value") - .publish(boost::bind(&SoapySDR::Device::getIQBalance, _device, dir, chan)) - .subscribe(boost::bind(&SoapySDR::Device::setIQBalance, _device, dir, chan, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getIQBalance, _device, dir, chan)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setIQBalance, _device, dir, chan, _1)); } - #ifdef SOAPY_SDR_API_HAS_IQ_BALANCE_MODE if (_device->hasIQBalanceMode(dir, chan)) { _tree->create<bool>(rf_fe_path / "iq_balance" / "enable") - .publish(boost::bind(&SoapySDR::Device::getIQBalanceMode, _device, dir, chan)) - .subscribe(boost::bind(&SoapySDR::Device::setIQBalanceMode, _device, dir, chan, _1)); + .set_publisher(boost::bind(&SoapySDR::Device::getIQBalanceMode, _device, dir, chan)) + .add_desired_subscriber(boost::bind(&SoapySDR::Device::setIQBalanceMode, _device, dir, chan, _1)); } - #endif } void UHDSoapyDevice::setupFakeChannelHooks(const int dir, const size_t /*chan*/, const std::string &dirName, const std::string &chName) @@ -568,12 +545,12 @@ _device->closeStream(_stream); } - size_t get_num_channels(void) const + size_t get_num_channels(void) const override { return _nchan; } - size_t get_max_num_samps(void) const + size_t get_max_num_samps(void) const override { return _device->getStreamMTU(_stream); } @@ -584,7 +561,7 @@ uhd::rx_metadata_t &md, const double timeout = 0.1, const bool one_packet = false - ) + ) override { size_t total = 0; md.reset(); @@ -674,7 +651,7 @@ return total; } - void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd) + void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd) override { int flags = 0; if (not stream_cmd.stream_now) flags |= SOAPY_SDR_HAS_TIME; @@ -715,13 +692,19 @@ } #endif + #if UHD_VERSION >= 4110000 + uhd::device_addr_t get_stream_info(const size_t /*chan*/) const override + { + throw uhd::not_implemented_error("get_stream_info is not implemented here!"); + } + #endif + private: SoapySDR::Device *_device; SoapySDR::Stream *_stream; const size_t _nchan; const size_t _elemSize; std::vector<void *> _offsetBuffs; - bool _doErrorOnNextRecv; bool _nextTimeValid; uhd::time_spec_t _nextTime; const double &_sampRate; @@ -758,12 +741,12 @@ _device->closeStream(_stream); } - size_t get_num_channels(void) const + size_t get_num_channels(void) const override { return _nchan; } - size_t get_max_num_samps(void) const + size_t get_max_num_samps(void) const override { return _device->getStreamMTU(_stream); } @@ -773,7 +756,7 @@ size_t nsamps_per_buff, const uhd::tx_metadata_t &md, const double timeout = 0.1 - ) + ) override { //perform activation at the latest/on the first call to send if (not _active) @@ -808,7 +791,7 @@ return total; } - bool recv_async_msg(uhd::async_metadata_t &md, double timeout = 0.1) + bool recv_async_msg(uhd::async_metadata_t &md, double timeout = 0.1) override { size_t chanMask = 0; int flags = 0; @@ -867,6 +850,13 @@ } #endif + #if UHD_VERSION >= 4110000 + uhd::device_addr_t get_stream_info(const size_t /*chan*/) const override + { + throw uhd::not_implemented_error("get_stream_info is not implemented here!"); + } + #endif + private: bool _active; SoapySDR::Device *_device; @@ -899,17 +889,6 @@ #define component "UHDSoapyDevice" switch(logLevel) { - #ifdef UHD_HAS_MSG_HPP - case SOAPY_SDR_FATAL: - case SOAPY_SDR_CRITICAL: - case SOAPY_SDR_ERROR: UHD_MSG(error) << message << std::endl; break; - case SOAPY_SDR_WARNING: UHD_MSG(warning) << message << std::endl; break; - case SOAPY_SDR_NOTICE: - case SOAPY_SDR_INFO: - case SOAPY_SDR_DEBUG: - case SOAPY_SDR_TRACE: UHD_MSG(status) << message << std::endl; break; - case SOAPY_SDR_SSI: UHD_MSG(fastpath) << message << std::flush; break; - #else case SOAPY_SDR_FATAL: case SOAPY_SDR_CRITICAL: UHD_LOG_FATAL(component, message); break; case SOAPY_SDR_ERROR: UHD_LOG_FATAL(component, message); break; @@ -919,7 +898,6 @@ case SOAPY_SDR_DEBUG: case SOAPY_SDR_TRACE: UHD_LOG_TRACE(component, message); break; case SOAPY_SDR_SSI: UHD_LOG_FASTPATH(message); break; - #endif } } @@ -961,9 +939,5 @@ UHD_STATIC_BLOCK(registerUHDSoapyDevice) { - #ifdef UHD_HAS_DEVICE_FILTER uhd::device::register_device(&findUHDSoapyDevice, &makeUHDSoapyDevice, uhd::device::USRP); - #else - uhd::device::register_device(&findUHDSoapyDevice, &makeUHDSoapyDevice); - #endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/tests/CMakeLists.txt new/soapy-uhd-0.4.1git20261004/tests/CMakeLists.txt --- old/SoapyUHD/tests/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/soapy-uhd-0.4.1git20261004/tests/CMakeLists.txt 2026-10-04 19:53:23.000000000 +0200 @@ -0,0 +1,19 @@ +######################################################################## +# Unit tests for TypeHelpers.hpp free functions +######################################################################## +add_executable(test_type_helpers test_type_helpers.cpp) + +target_include_directories(test_type_helpers PRIVATE + ${CMAKE_SOURCE_DIR} + ${SoapySDR_INCLUDE_DIRS} + ${UHD_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} +) + +target_link_libraries(test_type_helpers PRIVATE + ${SoapySDR_LIBRARIES} + ${UHD_LIBRARIES} + ${Boost_LIBRARIES} +) + +add_test(NAME type_helpers COMMAND test_type_helpers) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/SoapyUHD/tests/test_type_helpers.cpp new/soapy-uhd-0.4.1git20261004/tests/test_type_helpers.cpp --- old/SoapyUHD/tests/test_type_helpers.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/soapy-uhd-0.4.1git20261004/tests/test_type_helpers.cpp 2026-10-04 19:53:23.000000000 +0200 @@ -0,0 +1,213 @@ +// Copyright (c) 2026 SoapyUHD contributors +// SPDX-License-Identifier: GPL-3.0 +// +// Unit tests for TypeHelpers.hpp free functions. +// Bare-stdlib harness; no external test framework. + +#include "TypeHelpers.hpp" + +#include <cmath> +#include <iostream> +#include <string> +#include <vector> + +static int g_failures = 0; + +#define CHECK(cond) do { \ + if (!(cond)) { \ + std::cerr << "FAIL: " #cond " at " << __FILE__ << ":" << __LINE__ << "\n"; \ + ++g_failures; \ + } \ +} while (0) + +#define CHECK_NEAR(a, b, eps) do { \ + if (std::fabs((a) - (b)) > (eps)) { \ + std::cerr << "FAIL: |" #a " - " #b "| > " #eps \ + << " (got " << (a) << " vs " << (b) << ")" \ + << " at " << __FILE__ << ":" << __LINE__ << "\n"; \ + ++g_failures; \ + } \ +} while (0) + +static void test_dict_kwargs_round_trip() +{ + SoapySDR::Kwargs kw; + kw["driver"] = "uhd"; + kw["type"] = "b200"; + kw["serial"] = "BADC10E"; + + uhd::device_addr_t addr = kwargsToDict(kw); + CHECK(addr.has_key("driver")); + CHECK(addr.has_key("type")); + CHECK(addr.has_key("serial")); + CHECK(addr["driver"] == "uhd"); + + SoapySDR::Kwargs kw2 = dictToKwargs(addr); + CHECK(kw2.size() == 3); + CHECK(kw2.at("driver") == "uhd"); + CHECK(kw2.at("type") == "b200"); + CHECK(kw2.at("serial") == "BADC10E"); +} + +static void test_dict_kwargs_empty() +{ + SoapySDR::Kwargs kw; + uhd::device_addr_t addr = kwargsToDict(kw); + CHECK(addr.size() == 0); + + SoapySDR::Kwargs kw2 = dictToKwargs(addr); + CHECK(kw2.empty()); +} + +static void test_meta_range_to_range_list_single() +{ + uhd::meta_range_t mr(0.0, 100.0, 1.0); + SoapySDR::RangeList rl = metaRangeToRangeList(mr); + CHECK(rl.size() == 1); + CHECK_NEAR(rl[0].minimum(), 0.0, 1e-9); + CHECK_NEAR(rl[0].maximum(), 100.0, 1e-9); +} + +static void test_meta_range_to_range_list_multi() +{ + uhd::meta_range_t mr; + mr.push_back(uhd::range_t(0.0, 10.0)); + mr.push_back(uhd::range_t(20.0, 30.0)); + SoapySDR::RangeList rl = metaRangeToRangeList(mr); + CHECK(rl.size() == 2); + CHECK_NEAR(rl[0].maximum(), 10.0, 1e-9); + CHECK_NEAR(rl[1].minimum(), 20.0, 1e-9); +} + +static void test_range_list_to_meta_range_round_trip() +{ + SoapySDR::RangeList rl; + rl.push_back(SoapySDR::Range(1.0, 2.0)); + rl.push_back(SoapySDR::Range(5.0, 10.0)); + uhd::meta_range_t mr = rangeListToMetaRange(rl); + CHECK(mr.size() == 2); + CHECK_NEAR(mr[0].start(), 1.0, 1e-9); + CHECK_NEAR(mr[1].stop(), 10.0, 1e-9); +} + +static void test_range_list_to_meta_range_empty_yields_zero() +{ + SoapySDR::RangeList rl; + uhd::meta_range_t mr = rangeListToMetaRange(rl); + CHECK(mr.size() == 1); + CHECK_NEAR(mr[0].start(), 0.0, 1e-9); + CHECK_NEAR(mr[0].stop(), 0.0, 1e-9); +} + +static void test_meta_range_to_range_top_level() +{ + uhd::meta_range_t mr(-50.0, 50.0, 0.5); + SoapySDR::Range r = metaRangeToRange(mr); + CHECK_NEAR(r.minimum(), -50.0, 1e-9); + CHECK_NEAR(r.maximum(), 50.0, 1e-9); +} + +static void test_number_list_to_meta_range_empty_yields_zero() +{ + std::vector<double> v; + uhd::meta_range_t mr = numberListToMetaRange(v); + CHECK(mr.size() == 1); + CHECK_NEAR(mr[0].start(), 0.0, 1e-9); +} + +static void test_meta_range_to_numeric_list_single_returns_bounds() +{ + uhd::meta_range_t mr(10.0, 20.0); + std::vector<double> v = metaRangeToNumericList(mr); + CHECK(v.size() == 2); + CHECK_NEAR(v[0], 10.0, 1e-9); + CHECK_NEAR(v[1], 20.0, 1e-9); +} + +static void test_meta_range_to_numeric_list_multi_returns_starts() +{ + uhd::meta_range_t mr; + mr.push_back(uhd::range_t(1.0)); + mr.push_back(uhd::range_t(2.0)); + mr.push_back(uhd::range_t(3.0)); + std::vector<double> v = metaRangeToNumericList(mr); + CHECK(v.size() == 3); + CHECK_NEAR(v[0], 1.0, 1e-9); + CHECK_NEAR(v[2], 3.0, 1e-9); +} + +static void test_range_to_meta_range_default_step() +{ + SoapySDR::Range r(0.0, 100.0); + uhd::meta_range_t mr = rangeToMetaRange(r); + CHECK_NEAR(mr.start(), 0.0, 1e-9); + CHECK_NEAR(mr.stop(), 100.0, 1e-9); +} + +static void test_sensor_arginfo_round_trip_bool() +{ + uhd::sensor_value_t s("locked", true, "true", "false"); + SoapySDR::ArgInfo ai = sensorToArgInfo(s, "locked"); + CHECK(ai.key == "locked"); + CHECK(ai.type == SoapySDR::ArgInfo::BOOL); + + uhd::sensor_value_t s2 = argInfoToSensor(ai, "true"); + CHECK(s2.to_bool() == true); +} + +static void test_sensor_arginfo_round_trip_int() +{ + uhd::sensor_value_t s("count", 42, "items"); + SoapySDR::ArgInfo ai = sensorToArgInfo(s, "count"); + CHECK(ai.type == SoapySDR::ArgInfo::INT); + + uhd::sensor_value_t s2 = argInfoToSensor(ai, "42"); + CHECK(s2.to_int() == 42); +} + +static void test_sensor_arginfo_round_trip_real() +{ + uhd::sensor_value_t s("temp", 25.5, "C"); + SoapySDR::ArgInfo ai = sensorToArgInfo(s, "temp"); + CHECK(ai.type == SoapySDR::ArgInfo::FLOAT); + + uhd::sensor_value_t s2 = argInfoToSensor(ai, "25.5"); + CHECK_NEAR(s2.to_real(), 25.5, 1e-9); +} + +static void test_sensor_arginfo_round_trip_string() +{ + uhd::sensor_value_t s("status", std::string("active"), ""); + SoapySDR::ArgInfo ai = sensorToArgInfo(s, "status"); + CHECK(ai.type == SoapySDR::ArgInfo::STRING); + + uhd::sensor_value_t s2 = argInfoToSensor(ai, "active"); + CHECK(s2.value == "active"); +} + +int main() +{ + test_dict_kwargs_round_trip(); + test_dict_kwargs_empty(); + test_meta_range_to_range_list_single(); + test_meta_range_to_range_list_multi(); + test_range_list_to_meta_range_round_trip(); + test_range_list_to_meta_range_empty_yields_zero(); + test_meta_range_to_range_top_level(); + test_number_list_to_meta_range_empty_yields_zero(); + test_meta_range_to_numeric_list_single_returns_bounds(); + test_meta_range_to_numeric_list_multi_returns_starts(); + test_range_to_meta_range_default_step(); + test_sensor_arginfo_round_trip_bool(); + test_sensor_arginfo_round_trip_int(); + test_sensor_arginfo_round_trip_real(); + test_sensor_arginfo_round_trip_string(); + + if (g_failures == 0) + { + std::cout << "All tests passed.\n"; + return 0; + } + std::cerr << g_failures << " test(s) FAILED.\n"; + return 1; +}
