Hello community,

here is the log from the commit of package soapy-uhd for openSUSE:Factory 
checked in at 2020-09-27 11:48:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/soapy-uhd (Old)
 and      /work/SRC/openSUSE:Factory/.soapy-uhd.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "soapy-uhd"

Sun Sep 27 11:48:44 2020 rev:7 rq:835803 version:0.4.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/soapy-uhd/soapy-uhd.changes      2019-06-27 
15:26:33.909622790 +0200
+++ /work/SRC/openSUSE:Factory/.soapy-uhd.new.4249/soapy-uhd.changes    
2020-09-27 11:48:45.375977499 +0200
@@ -1,0 +2,16 @@
+Mon Sep 21 08:29:11 UTC 2020 - Martin Hauke <[email protected]>
+
+- Update to version 0.4.1
+  * Fix for UHD_VERSION define and 4.0 release compilation
+- Drop not longer needed patch:
+  * 0001-Fix-for-UHD_VERSION-check-for-4.0.patch (fixed by upstream)
+
+-------------------------------------------------------------------
+Fri Sep 18 07:15:11 UTC 2020 - Martin Hauke <[email protected]>
+
+- Update to version 0.4.0
+  * Support for compilation with UHD 4.0 release
+- Add patch:
+  * 0001-Fix-for-UHD_VERSION-check-for-4.0.patch
+
+-------------------------------------------------------------------

Old:
----
  soapy-uhd-0.3.6.tar.gz

New:
----
  soapy-uhd-0.4.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ soapy-uhd.spec ++++++
--- /var/tmp/diff_new_pack.582YyO/_old  2020-09-27 11:48:47.055979309 +0200
+++ /var/tmp/diff_new_pack.582YyO/_new  2020-09-27 11:48:47.059979313 +0200
@@ -1,8 +1,8 @@
 #
 # spec file for package soapy-uhd
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
-# Copyright (c) 2017, Martin Hauke <[email protected]>
+# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2017-2020, Martin Hauke <[email protected]>
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -13,19 +13,20 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
+
 %define soapy_modver 0.7
 %define soapy_modname soapysdr%{soapy_modver}-module-uhd
 
 Name:           soapy-uhd
-Version:        0.3.6
+Version:        0.4.1
 Release:        0
 Summary:        Soapy SDR plugins for UHD supported SDR devices
-License:        GPL-3.0
+License:        GPL-3.0-only
 Group:          Hardware/Other
-Url:            https://github.com/pothosware/SoapyUHD/wiki
+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
 BuildRequires:  cmake

++++++ soapy-uhd-0.3.6.tar.gz -> soapy-uhd-0.4.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoapyUHD-soapy-uhd-0.3.6/Changelog.txt 
new/SoapyUHD-soapy-uhd-0.4.1/Changelog.txt
--- old/SoapyUHD-soapy-uhd-0.3.6/Changelog.txt  2019-06-22 14:51:56.000000000 
+0200
+++ new/SoapyUHD-soapy-uhd-0.4.1/Changelog.txt  2020-09-21 00:40:10.000000000 
+0200
@@ -1,3 +1,13 @@
+Release 0.4.1 (2020-09-20)
+==========================
+
+- Fix for UHD_VERSION define and 4.0 release compilation
+
+Release 0.4.0 (2020-09-17)
+==========================
+
+- Support for compilation with UHD 4.0 release
+
 Release 0.3.6 (2019-06-22)
 ==========================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoapyUHD-soapy-uhd-0.3.6/SoapyUHDDevice.cpp 
new/SoapyUHD-soapy-uhd-0.4.1/SoapyUHDDevice.cpp
--- old/SoapyUHD-soapy-uhd-0.3.6/SoapyUHDDevice.cpp     2019-06-22 
14:51:56.000000000 +0200
+++ new/SoapyUHD-soapy-uhd-0.4.1/SoapyUHDDevice.cpp     2020-09-21 
00:40:10.000000000 +0200
@@ -1,4 +1,5 @@
 // Copyright (c) 2014-2017 Josh Blum
+//                    2019 Nicholas Corgan
 // SPDX-License-Identifier: GPL-3.0
 
 /***********************************************************************
@@ -64,7 +65,7 @@
         for (size_t i = 0; i < this->getNumChannels(SOAPY_SDR_TX); i++)
         {
             const uhd::dict<std::string, std::string> info = 
_dev->get_usrp_tx_info(i);
-            BOOST_FOREACH (const std::string &key, info.keys())
+            for (const std::string &key : info.keys())
             {
                 if (key.size() > 3 and key.substr(0, 3) == "tx_")
                     out[str(boost::format("tx%d_%s") % i % key.substr(3))] = 
info[key];
@@ -74,7 +75,7 @@
         for (size_t i = 0; i < this->getNumChannels(SOAPY_SDR_RX); i++)
         {
             const uhd::dict<std::string, std::string> info = 
_dev->get_usrp_rx_info(i);
-            BOOST_FOREACH (const std::string &key, info.keys())
+            for (const std::string &key : info.keys())
             {
                 if (key.size() > 3 and key.substr(0, 3) == "rx_")
                     out[str(boost::format("rx%d_%s") % i % key.substr(3))] = 
info[key];
@@ -201,7 +202,7 @@
     SoapySDR::Stream *setupStream(const int dir, const std::string &format, 
const std::vector<size_t> &channels, const SoapySDR::Kwargs &args)
     {
         std::string hostFormat;
-        BOOST_FOREACH(const char ch, format)
+        for(const char ch : format)
         {
             if (ch == 'C') hostFormat += "c";
             else if (ch == 'F') hostFormat = "f" + hostFormat;
@@ -375,11 +376,19 @@
     /*******************************************************************
      * Frontend corrections support
      ******************************************************************/
-    bool hasDCOffsetMode(const int dir, const size_t) const
+
+    bool hasDCOffsetMode(const int dir, const size_t channel) const
     {
-        //since we don't have a way to really query this,
-        //assume that DC offset removal is always supported on RX
-        return (dir == SOAPY_SDR_RX);
+        if (dir == SOAPY_SDR_TX) return false;
+        if (dir == SOAPY_SDR_RX)
+        {
+            // This is usually on the motherboard's layer, but for some devices
+            // (ex. the B2XX), it is done on the RF frontend.
+            return __doesMBoardFEPropTreeEntryExist(dir, channel, 
"dc_offset/enable") ||
+                   __doesDBoardFEPropTreeEntryExist(dir, channel, 
"dc_offset/enable");
+        }
+
+        return SoapySDR::Device::hasDCOffsetMode(dir, channel);
     }
 
     void setDCOffsetMode(const int dir, const size_t channel, const bool 
automatic)
@@ -387,11 +396,35 @@
         if (dir == SOAPY_SDR_RX) _dev->set_rx_dc_offset(automatic, channel);
     }
 
-    bool hasDCOffset(const int, const size_t) const
+    bool getDCOffsetMode(const int dir, const size_t channel) const
     {
-        //since we don't have a way to really query this,
-        //assume that DC offset is always supported
-        return true;
+        // multi_usrp has no getter for this, so we need to query the
+        // property tree itself.
+        if (dir == SOAPY_SDR_TX) return false;
+        if((dir == SOAPY_SDR_RX) && this->hasDCOffsetMode(dir, channel))
+        {
+            auto tree = _dev->get_device()->get_tree();
+            const std::string subpath = "/dc_offset/enable";
+
+            auto mboardPath = __getMBoardFEPropTreePath(dir, channel) + 
subpath;
+            if(tree->exists(mboardPath))
+            {
+                return tree->access<bool>(mboardPath).get();
+            }
+
+            auto dboardPath = __getDBoardFEPropTreePath(dir, channel) + 
subpath;
+            if(tree->exists(dboardPath))
+            {
+                return tree->access<bool>(dboardPath).get();
+            }
+        }
+
+        return SoapySDR::Device::getDCOffsetMode(dir, channel);
+    }
+
+    bool hasDCOffset(const int dir, const size_t channel) const
+    {
+        return __doesMBoardFEPropTreeEntryExist(dir, channel, 
"dc_offset/value");
     }
 
     void setDCOffset(const int dir, const size_t channel, const 
std::complex<double> &offset)
@@ -400,11 +433,25 @@
         if (dir == SOAPY_SDR_RX) _dev->set_rx_dc_offset(offset, channel);
     }
 
-    bool hasIQBalance(const int, const size_t) const
+    std::complex<double> getDCOffset(const int dir, const size_t channel) const
     {
-        //since we don't have a way to really query this,
-        //assume that IQ balance is always supported
-        return true;
+        // multi_usrp has no getter for this, so we need to query the
+        // property tree itself.
+        if(this->hasDCOffset(dir, channel))
+        {
+            auto tree = _dev->get_device()->get_tree();
+            const std::string subpath = "/dc_offset/value";
+
+            auto path = __getMBoardFEPropTreePath(dir, channel) + subpath;
+            return tree->access<std::complex<double>>(path).get();
+        }
+
+        return SoapySDR::Device::getDCOffset(dir, channel);
+    }
+
+    bool hasIQBalance(const int dir, const size_t channel) const
+    {
+        return __doesMBoardFEPropTreeEntryExist(dir, channel, 
"iq_balance/value");
     }
 
     void setIQBalance(const int dir, const size_t channel, const 
std::complex<double> &balance)
@@ -413,6 +460,55 @@
         if (dir == SOAPY_SDR_RX) _dev->set_rx_iq_balance(balance, channel);
     }
 
+    std::complex<double> getIQBalance(const int dir, const size_t channel) 
const
+    {
+        // multi_usrp has no getter for this, so we need to query the
+        // property tree itself.
+        if(this->hasIQBalance(dir, channel))
+        {
+            auto tree = _dev->get_device()->get_tree();
+            const std::string subpath = "/iq_balance/value";
+
+            auto path = __getMBoardFEPropTreePath(dir, channel) + subpath;
+            return tree->access<std::complex<double>>(path).get();
+        }
+
+        return SoapySDR::Device::getIQBalance(dir, channel);
+    }
+
+    bool hasIQBalanceMode(const int dir, const size_t channel) const
+    {
+        if (dir == SOAPY_SDR_TX) return false;
+        if (dir == SOAPY_SDR_RX)
+        {
+            return __doesMBoardFEPropTreeEntryExist(dir, channel, 
"iq_balance/enable");
+        }
+
+        return SoapySDR::Device::hasDCOffsetMode(dir, channel);
+    }
+
+    void setIQBalanceMode(const int dir, const size_t channel, const bool 
automatic)
+    {
+        if (dir == SOAPY_SDR_RX) _dev->set_rx_iq_balance(automatic, channel);
+    }
+
+    bool getIQBalanceMode(const int dir, const size_t channel) const
+    {
+        // multi_usrp has no getter for this, so we need to query the
+        // property tree itself.
+        if (dir == SOAPY_SDR_TX) return false;
+        if((dir == SOAPY_SDR_RX) && this->hasIQBalanceMode(dir, channel))
+        {
+            auto tree = _dev->get_device()->get_tree();
+            const std::string subpath = "/iq_balance/enable";
+
+            auto path = __getMBoardFEPropTreePath(dir, channel) + subpath;
+            return tree->access<bool>(path).get();
+        }
+
+        return false;
+    }
+
     /*******************************************************************
      * Gain support
      ******************************************************************/
@@ -424,6 +520,18 @@
         return SoapySDR::Device::listGains(dir, channel);
     }
 
+    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
@@ -825,6 +933,55 @@
         return _dev->get_gpio_attr(bank, "DDR");
     }
 
+    /*******************************************************************
+     * Helpers for searching property tree
+     ******************************************************************/
+
+    std::string __getMBoardFEPropTreePath(const int dir, const size_t channel) 
const
+    {
+        auto tree = _dev->get_device()->get_tree();
+        const std::string directionName = (dir == SOAPY_SDR_TX) ? "tx" : "rx";
+        auto subdevSpec = (dir == SOAPY_SDR_TX) ? 
_dev->get_tx_subdev_spec(0).at(channel)
+                                                : 
_dev->get_rx_subdev_spec(0).at(channel);
+
+        const std::string path =
+            str(boost::format("/mboards/0/%s_frontends/%s")
+                % directionName
+                % subdevSpec.db_name);
+
+        return path;
+    }
+
+    std::string __getDBoardFEPropTreePath(const int dir, const size_t channel) 
const
+    {
+        auto tree = _dev->get_device()->get_tree();
+        const std::string directionName = (dir == SOAPY_SDR_TX) ? "tx" : "rx";
+        auto subdevSpec = (dir == SOAPY_SDR_TX) ? 
_dev->get_tx_subdev_spec(0).at(channel)
+                                                : 
_dev->get_rx_subdev_spec(0).at(channel);
+
+        const std::string path =
+            str(boost::format("/mboards/0/dboards/%s/%s_frontends/%s")
+                % subdevSpec.db_name
+                % directionName
+                % subdevSpec.sd_name);
+
+        return path;
+    }
+
+    bool __doesMBoardFEPropTreeEntryExist(const int dir, const size_t channel, 
const std::string &subpath) const
+    {
+        auto path = __getMBoardFEPropTreePath(dir, channel) + "/" + subpath;
+
+        return _dev->get_device()->get_tree()->exists(path);
+    }
+
+    bool __doesDBoardFEPropTreeEntryExist(const int dir, const size_t channel, 
const std::string &subpath) const
+    {
+        auto path = __getDBoardFEPropTreePath(dir, channel) + "/" + subpath;
+
+        return _dev->get_device()->get_tree()->exists(path);
+    }
+
 private:
     uhd::usrp::multi_usrp::sptr _dev;
     const std::string _type;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoapyUHD-soapy-uhd-0.3.6/UHDSoapyDevice.cpp 
new/SoapyUHD-soapy-uhd-0.4.1/UHDSoapyDevice.cpp
--- old/SoapyUHD-soapy-uhd-0.3.6/UHDSoapyDevice.cpp     2019-06-22 
14:51:56.000000000 +0200
+++ new/SoapyUHD-soapy-uhd-0.4.1/UHDSoapyDevice.cpp     2020-09-21 
00:40:10.000000000 +0200
@@ -1,4 +1,4 @@
-// Copyright (c) 2015-2017 Josh Blum
+// Copyright (c) 2015-2020 Josh Blum
 // Copyright (c) 2018 Deepwave Digital, Inc.
 // SPDX-License-Identifier: GPL-3.0
 
@@ -14,6 +14,7 @@
 #include "TypeHelpers.hpp"
 #include <uhd/utils/static.hpp>
 #include <uhd/property_tree.hpp>
+#include <uhd/version.hpp>
 #include <uhd/device.hpp>
 #include <uhd/convert.hpp>
 #ifdef UHD_HAS_MSG_HPP
@@ -150,7 +151,7 @@
 
     void old_issue_stream_cmd(const size_t chan, const uhd::stream_cmd_t &cmd)
     {
-        uhd::rx_streamer::sptr stream = _rx_streamers[chan].lock();
+        auto stream = _rx_streamers[chan].lock();
         if (stream) stream->issue_stream_cmd(cmd);
     }
 
@@ -179,8 +180,13 @@
     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
 };
 
 /***********************************************************************
@@ -212,7 +218,7 @@
     //mb eeprom filled with hardware info
     uhd::usrp::mboard_eeprom_t mb_eeprom;
     const uhd::device_addr_t 
hardware_info(kwargsToDict(_device->getHardwareInfo()));
-    BOOST_FOREACH(const std::string &key, hardware_info.keys()) mb_eeprom[key] 
= hardware_info[key];
+    for(const std::string &key : hardware_info.keys()) mb_eeprom[key] = 
hardware_info[key];
     _tree->create<uhd::usrp::mboard_eeprom_t>(mb_path / 
"eeprom").set(mb_eeprom);
 
     //the frontend mapping
@@ -252,14 +258,14 @@
 
     //mboard sensors
     _tree->create<int>(mb_path / "sensors"); //ensure this path exists
-    BOOST_FOREACH(const std::string &name, _device->listSensors())
+    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));
     }
 
     //gpio banks
-    BOOST_FOREACH(const std::string &bank, _device->listGPIOBanks())
+    for(const std::string &bank : _device->listGPIOBanks())
     {
         std::vector<std::string> attrs;
         attrs.push_back("CTRL");
@@ -270,7 +276,7 @@
         attrs.push_back("ATR_TX");
         attrs.push_back("ATR_XX");
         attrs.push_back("READBACK");
-        BOOST_FOREACH(const std::string &attr, attrs)
+        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))
@@ -365,7 +371,7 @@
 
     //frontend sensors
     _tree->create<int>(rf_fe_path / "sensors"); //ensure this path exists
-    BOOST_FOREACH(const std::string &name, _device->listSensors(dir, chan))
+    for(const std::string &name : _device->listSensors(dir, chan))
     {
         //install the sensor
         _tree->create<uhd::sensor_value_t>(rf_fe_path / "sensors" / name)
@@ -387,7 +393,7 @@
     }
 
     //gains
-    BOOST_FOREACH(const std::string &name, _device->listGains(dir, chan))
+    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));
@@ -446,6 +452,15 @@
             .publish(boost::bind(&SoapySDR::Device::getIQBalance, _device, 
dir, chan))
             .subscribe(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));
+    }
+    #endif
 }
 
 void UHDSoapyDevice::setupFakeChannelHooks(const int dir, const size_t 
/*chan*/, const std::string &dirName, const std::string &chName)
@@ -520,7 +535,7 @@
 
     //the format string
     std::string hostFormat;
-    BOOST_FOREACH(const char ch, args.cpu_format)
+    for(const char ch : args.cpu_format)
     {
         if (ch == 'c') hostFormat = "C" + hostFormat;
         else if (ch == 'f') hostFormat += "F";
@@ -707,7 +722,7 @@
 {
     size_t ch = 0; if (not args.channels.empty()) ch = args.channels.front();
     uhd::rx_streamer::sptr stream(new UHDSoapyRxStream(_device, args, 
_sampleRates[SOAPY_SDR_RX][ch]));
-    BOOST_FOREACH(const size_t ch, args.channels) _rx_streamers[ch] = stream;
+    for(const size_t ch : args.channels) _rx_streamers[ch] = stream;
     if (args.channels.empty()) _rx_streamers[0] = stream;
     return stream;
 }
@@ -847,14 +862,14 @@
 uhd::tx_streamer::sptr UHDSoapyDevice::get_tx_stream(const uhd::stream_args_t 
&args)
 {
     uhd::tx_streamer::sptr stream(new UHDSoapyTxStream(_device, args));
-    BOOST_FOREACH(const size_t ch, args.channels) _tx_streamers[ch] = stream;
+    for(const size_t ch : args.channels) _tx_streamers[ch] = stream;
     if (args.channels.empty()) _tx_streamers[0] = stream;
     return stream;
 }
 
 bool UHDSoapyDevice::recv_async_msg(uhd::async_metadata_t &md, double timeout)
 {
-    uhd::tx_streamer::sptr stream = _tx_streamers[0].lock();
+    auto stream = _tx_streamers[0].lock();
     if (not stream) return false;
     return stream->recv_async_msg(md, timeout);
 }
@@ -913,11 +928,16 @@
     if (args.count("type") != 0 and args.at("type") != "soapy") return 
uhd::device_addrs_t();
 
     uhd::device_addrs_t result;
-    BOOST_FOREACH(SoapySDR::Kwargs found, SoapySDR::Device::enumerate(args))
+    for(SoapySDR::Kwargs found : SoapySDR::Device::enumerate(args))
     {
         found.erase(SOAPY_UHD_NO_DEEPER);
         result.push_back(kwargsToDict(found));
         result.back()["type"] = "soapy";
+        if (found.count("serial") == 0)
+        {
+            auto serial = 
std::hash<std::string>()(SoapySDR::KwargsToString(found));
+            result.back()["serial"] = std::to_string(serial);
+        }
     }
     return result;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoapyUHD-soapy-uhd-0.3.6/debian/changelog 
new/SoapyUHD-soapy-uhd-0.4.1/debian/changelog
--- old/SoapyUHD-soapy-uhd-0.3.6/debian/changelog       2019-06-22 
14:51:56.000000000 +0200
+++ new/SoapyUHD-soapy-uhd-0.4.1/debian/changelog       2020-09-21 
00:40:10.000000000 +0200
@@ -1,3 +1,15 @@
+soapyuhd (0.4.1-1) unstable; urgency=low
+
+  * Release 0.4.1 (2020-09-20)
+
+ -- Josh Blum <[email protected]>  Sun, 20 Sep 2020 17:40:02 -0000
+
+soapyuhd (0.4.0-1) unstable; urgency=low
+
+  * Release 0.4.0 (2020-09-17)
+
+ -- Josh Blum <[email protected]>  Thu, 17 Sep 2020 10:06:00 -0000
+
 soapyuhd (0.3.6-1) unstable; urgency=low
 
   * Release 0.3.6 (2019-06-22)


Reply via email to