<pre style='margin:0'>
ra1nb0w (ra1nb0w) pushed a commit to branch gnuradio-3.10
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/876029d0e385ef1ac3f4209ffa219517c701e21c">https://github.com/macports/macports-ports/commit/876029d0e385ef1ac3f4209ffa219517c701e21c</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 876029d0e385ef1ac3f4209ffa219517c701e21c
</span>Author: Davide Gerhard <ra1nb0w@macports.org>
AuthorDate: Fri Feb 11 12:33:38 2022 +0100

<span style='display:block; white-space:pre;color:#404040;'>    gr-osmosdr: update commit to a100eb024c
</span>---
 science/gr-osmosdr/Portfile                        |   23 +-
 .../files/add_airspy-spyserver_support.patch       | 1740 --------------------
 science/gr-osmosdr/files/add_gr-iio_support.patch  |  616 -------
 3 files changed, 9 insertions(+), 2370 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/science/gr-osmosdr/Portfile b/science/gr-osmosdr/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index ff2df3b1ae9..a708fb673e3 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/science/gr-osmosdr/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/science/gr-osmosdr/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -17,21 +17,16 @@ long_description    Includes OSMO SDR support GNU Radio source and sink blocks i
</span>     in your applications independent of the underlying radio hardware.
 
 if {${name} eq ${subport}} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    github.setup osmocom gr-osmosdr cffef690f29e0793cd2d6c5d028c0c929115f0ac
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    version      20210117-[string range ${github.version} 0 7]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    checksums    rmd160  d80040fa6a40280dfff5e010d5f9b2575280f5e6 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 sha256  ce916d4fd04af6cde67e137f1ffc4ac69c12284c49f412312ace13622b1a1d07 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 size    252770
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    revision     3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    github.setup osmocom gr-osmosdr a100eb024c0210b95e4738b6efd836d48225bd03
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    version      20210128-[string range ${github.version} 0 7]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    checksums    rmd160  8131a2c7e8f9dbcf0d4faead4652e5cb6614272f \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 sha256  5404e166aee047af6094f3ea1854b7d2691c1485ebb477855001c4fd297820bd \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 size    257829
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    revision     0
</span> 
     conflicts gr37-osmosdr
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # add out-of-tree backend
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    patchfiles-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        add_airspy-spyserver_support.patch \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        add_gr-iio_support.patch
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    github.livecheck.branch gr3.8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    github.livecheck.branch master
</span> }
 
 subport gr37-osmosdr {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -125,11 +120,11 @@ variant fcdproplus description "Install ${name} with support for FunCube Dongle
</span>             port:gr-fcdproplus
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-   configure.args-append -DENABLE_FCDPP=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   configure.args-append -DENABLE_FCD=ON
</span> }
 
 if {![variant_isset fcdproplus]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    configure.args-append -DENABLE_FCDPP=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append -DENABLE_FCD=OFF
</span> }
 
 variant rtlsdr description "Install ${name} with support for rtl-sdr" {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/science/gr-osmosdr/files/add_airspy-spyserver_support.patch b/science/gr-osmosdr/files/add_airspy-spyserver_support.patch
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 8ffa1c2307f..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/science/gr-osmosdr/files/add_airspy-spyserver_support.patch
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,1740 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-From 2008a94fb9cb16f3d58d3ff0545d50527a162268 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-From: Davide Gerhard <rainbow@irh.it>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-Date: Fri, 17 Apr 2020 16:20:46 +0200
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-Subject: [PATCH] add support for AIRSPY SPYServer
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-the work is done by racerxdl
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-see https://github.com/racerxdl/gr-osmosdr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>----
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- grc/gen_osmosdr_blocks.py           |   2 +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/CMakeLists.txt                  |   8 +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/config.h.in                     |   1 +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/device.cc                       |   8 +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/source_impl.cc                  |  18 +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/spyserver/CMakeLists.txt        |  36 ++
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/spyserver/spyserver_protocol.h  | 179 ++++++
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/spyserver/spyserver_source_c.cc | 879 ++++++++++++++++++++++++++++
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/spyserver/spyserver_source_c.h  | 206 +++++++
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/spyserver/tcp_client.cc         | 163 ++++++
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lib/spyserver/tcp_client.h          |  82 +++
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 11 files changed, 1582 insertions(+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- create mode 100644 lib/spyserver/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- create mode 100644 lib/spyserver/spyserver_protocol.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- create mode 100644 lib/spyserver/spyserver_source_c.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- create mode 100644 lib/spyserver/spyserver_source_c.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- create mode 100644 lib/spyserver/tcp_client.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- create mode 100644 lib/spyserver/tcp_client.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git grc/gen_osmosdr_blocks.py grc/gen_osmosdr_blocks.py
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 840320a..13a03fb 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- grc/gen_osmosdr_blocks.py
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ grc/gen_osmosdr_blocks.py
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -165,6 +165,7 @@ documentation: |-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    * gnuradio .cfile input through libgnuradio-blocks
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    * RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    * AirSpy Wideband Receiver through libairspy
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * SpyServer Devices through spyserver
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   % endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   % if sourk == 'sink':
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    * gnuradio .cfile output through libgnuradio-blocks
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -205,6 +206,7 @@ documentation: |-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     cloudiq=127.0.0.1[:50000]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     sdr-iq=/dev/ttyUSB0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     airspy=0[,bias=0|1][,linearity][,sensitivity]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    spyserver=0,ip=192.168.0.10[,port=5555]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   % endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   % if sourk == 'sink':
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     file='/path/to/your file',rate=1e6[,freq=100e6][,append=true][,throttle=true] ...
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/CMakeLists.txt lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index d04cb1d..ec8fe26 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -201,6 +201,14 @@ if(ENABLE_BLADERF)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_subdirectory(bladerf)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- endif(ENABLE_BLADERF)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# Setup SPYSERVER component
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+GR_REGISTER_COMPONENT("AIRSPY SPY Server Receiver" ENABLE_SPYSERVER)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+if(ENABLE_SPYSERVER)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    add_subdirectory(spyserver)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+endif(ENABLE_SPYSERVER)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Setup RFSPACE component
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/config.h.in lib/config.h.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 5303d7d..6ffc8ad 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- lib/config.h.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/config.h.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -15,6 +15,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_HACKRF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_BLADERF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_RFSPACE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#cmakedefine ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_AIRSPY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_AIRSPYHF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_SOAPY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/device.cc lib/device.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 586062f..885d85c 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- lib/device.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/device.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -70,6 +70,10 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <bladerf_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <spyserver_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_RFSPACE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <rfspace_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -186,6 +190,10 @@ devices_t device::find(const device_t &hint)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices( fake ) )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  BOOST_FOREACH( std::string dev, spyserver_source_c::get_devices( fake ) )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_AIRSPY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   BOOST_FOREACH( std::string dev, airspy_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/source_impl.cc lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index f1426e0..6301b74 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -76,6 +76,10 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <rfspace_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <spyserver_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_AIRSPY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <airspy_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -155,6 +159,9 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_BLADERF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dev_types.push_back("bladerf");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dev_types.push_back("spyserver");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_RFSPACE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dev_types.push_back("rfspace");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -232,6 +239,10 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    BOOST_FOREACH( std::string dev, spyserver_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_HACKRF
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     BOOST_FOREACH( std::string dev, hackrf_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -348,6 +359,13 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_AIRSPY
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if ( dict.count("spyserver") ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      spyserver_source_c_sptr src = make_spyserver_source_c( arg );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      block = src; iface = src.get();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_RFSPACE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if ( dict.count("rfspace") ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-          dict.count("sdr-iq") ||
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/spyserver/CMakeLists.txt lib/spyserver/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..09d46a7
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/spyserver/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,36 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# Copyright 2012 Free Software Foundation, Inc.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# This file is part of GNU Radio
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# any later version.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# This file included, use CMake directory variables
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+target_include_directories(gnuradio-osmosdr PRIVATE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${CMAKE_CURRENT_SOURCE_DIR}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+target_link_libraries(gnuradio-osmosdr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${Gnuradio-blocks_LIBRARIES}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+list(APPEND gr_osmosdr_srcs
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${CMAKE_CURRENT_SOURCE_DIR}/tcp_client.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${CMAKE_CURRENT_SOURCE_DIR}/spyserver_source_c.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/spyserver/spyserver_protocol.h lib/spyserver/spyserver_protocol.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..6394535
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/spyserver/spyserver_protocol.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,179 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+SPY Server protocol structures and constants
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+Copyright (C) 2017 Youssef Touil youssef@live.com
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+*/
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#pragma once
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <stdint.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <limits.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SPYSERVER_PROTOCOL_VERSION (((2) << 24) | ((0) << 16) | (1700))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SPYSERVER_MAX_COMMAND_BODY_SIZE (256)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SPYSERVER_MAX_MESSAGE_BODY_SIZE (1 << 20)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SPYSERVER_MAX_DISPLAY_PIXELS (1 << 15)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SPYSERVER_MIN_DISPLAY_PIXELS (100)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SPYSERVER_MAX_FFT_DB_RANGE (150)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SPYSERVER_MIN_FFT_DB_RANGE (10)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define SPYSERVER_MAX_FFT_DB_OFFSET (100)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum DeviceType
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DEVICE_INVALID        = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DEVICE_AIRSPY_ONE     = 1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DEVICE_AIRSPY_HF      = 2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DEVICE_RTLSDR         = 3,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum CommandType
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  CMD_HELLO             = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  CMD_GET_SETTING       = 1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  CMD_SET_SETTING       = 2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  CMD_PING              = 3,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum SettingType
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_STREAMING_MODE        = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_STREAMING_ENABLED     = 1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_GAIN                  = 2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_IQ_FORMAT             = 100,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_IQ_FREQUENCY          = 101,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_IQ_DECIMATION         = 102,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_IQ_DIGITAL_GAIN       = 103,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_FFT_FORMAT            = 200,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_FFT_FREQUENCY         = 201,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_FFT_DECIMATION        = 202,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_FFT_DB_OFFSET         = 203,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_FFT_DB_RANGE          = 204,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  SETTING_FFT_DISPLAY_PIXELS    = 205,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum StreamType
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_TYPE_STATUS    = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_TYPE_IQ        = 1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_TYPE_AF        = 2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_TYPE_FFT       = 4,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum StreamingMode
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_MODE_IQ_ONLY       = STREAM_TYPE_IQ,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_MODE_AF_ONLY       = STREAM_TYPE_AF,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_MODE_FFT_ONLY      = STREAM_TYPE_FFT,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_MODE_FFT_IQ        = STREAM_TYPE_FFT | STREAM_TYPE_IQ,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_MODE_FFT_AF        = STREAM_TYPE_FFT | STREAM_TYPE_AF,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum StreamFormat
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_FORMAT_INVALID     = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_FORMAT_UINT8       = 1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_FORMAT_INT16       = 2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_FORMAT_INT24       = 3,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_FORMAT_FLOAT       = 4,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  STREAM_FORMAT_DINT4       = 5,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum MessageType
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_DEVICE_INFO      = 0,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_CLIENT_SYNC      = 1,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_PONG             = 2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_READ_SETTING     = 3,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_UINT8_IQ         = 100,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_INT16_IQ         = 101,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_INT24_IQ         = 102,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_FLOAT_IQ         = 103,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_UINT8_AF         = 200,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_INT16_AF         = 201,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_INT24_AF         = 202,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_FLOAT_AF         = 203,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_DINT4_FFT        = 300,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MSG_TYPE_UINT8_FFT        = 301,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct ClientHandshake
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t ProtocolVersion;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t ClientNameLength;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct CommandHeader
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t CommandType;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t BodySize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct SettingTarget
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t StreamType;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t SettingType;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct MessageHeader
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t ProtocolID;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MessageType;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t StreamType;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t SequenceNumber;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t BodySize;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct DeviceInfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t DeviceType;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t DeviceSerial;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MaximumSampleRate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MaximumBandwidth;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t DecimationStageCount;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t GainStageCount;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MaximumGainIndex;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MinimumFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MaximumFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t Resolution;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MinimumIQDecimation;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t ForcedIQFormat;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct ClientSync
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t CanControl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t Gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t DeviceCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t IQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t FFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MinimumIQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MaximumIQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MinimumFFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t MaximumFFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct ComplexInt16
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int16_t real;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int16_t imag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+struct ComplexUInt8
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint8_t real;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint8_t imag;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+enum ParserPhase {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  AcquiringHeader,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ReadingData
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/spyserver/spyserver_source_c.cc lib/spyserver/spyserver_source_c.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..df3744f
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/spyserver/spyserver_source_c.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,879 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright 2018 Lucas Teske <lucas@teske.com.br>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *   Based on Youssef Touil (youssef@live.com) C# implementation.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * any later version.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * config.h is generated by configure.  It contains the results
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * of probing for features, options etc.  It should be the first
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * file included in your .cc file.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef HAVE_CONFIG_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "config.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <stdexcept>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <iostream>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <algorithm>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/assign.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/format.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/detail/endian.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/algorithm/string.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/thread/thread.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <gnuradio/io_signature.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "spyserver_source_c.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "spyserver_protocol.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "arg_helpers.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+using namespace boost::assign;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+spyserver_source_c_sptr make_spyserver_source_c (const std::string & args)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gnuradio::get_initial_sptr(new spyserver_source_c (args));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Specify constraints on number of input and output streams.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * This info is used to construct the input and output signatures
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * (2nd & 3rd args to gr::block's constructor).  The input and
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * output signatures are used by the runtime system to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * check that a valid number and type of inputs and outputs
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * are connected to this block.  In this case, we accept
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * only 0 input and 1 output.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static const int MIN_IN = 0;  // mininum number of input streams
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static const int MAX_IN = 0;  // maximum number of input streams
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static const int MIN_OUT = 1; // minimum number of output streams
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+static const int MAX_OUT = 1; // maximum number of output streams
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * The private constructor
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+spyserver_source_c::spyserver_source_c (const std::string &args)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  : gr::sync_block ("spyserver_source_c",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        gr::io_signature::make(MIN_IN, MAX_IN, sizeof (gr_complex)),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof (gr_complex))),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    terminated(false),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    streaming(false),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    got_device_info(false),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    receiver_thread(NULL),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    header_data(new uint8_t[sizeof(MessageHeader)]),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    body_buffer(NULL),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    body_buffer_length(0),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    parser_position(0),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    last_sequence_number(0),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    streaming_mode(STREAM_MODE_IQ_ONLY),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _sample_rate(0),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _center_freq(0),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _gain(0),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _digitalGain(0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dict_t dict = params_to_dict(args);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (dict.count("ip"))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ip = boost::lexical_cast<std::string>( dict["ip"] );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else if (dict.count("host"))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ip = boost::lexical_cast<std::string>( dict["host"] );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    throw std::runtime_error( std::string(__FUNCTION__) + " " +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              "You should defined an IP to connect." );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (dict.count("port"))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    port = boost::lexical_cast<int>( dict["port"] );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    port = 5555;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << "SpyServer(" << ip << ", " << port << ")" << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  client = tcp_client(ip, port);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  connect();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _fifo = new boost::circular_buffer<gr_complex>(5000000);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!_fifo) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    throw std::runtime_error( std::string(__FUNCTION__) + " " +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              "Failed to allocate a sample FIFO!" );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << "SpyServer: Ready" << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+// const std::string &spyserver_source_c::getName() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//   switch (device_info.DeviceType) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//   case DEVICE_INVALID:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//     return spyserver_source_c::NameNoDevice;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//   case DEVICE_AIRSPY_ONE:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//     return spyserver_source_c::NameAirspyOne;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//   case DEVICE_AIRSPY_HF:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//     return spyserver_source_c::NameAirspyHF;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//   case DEVICE_RTLSDR:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//     return spyserver_source_c::NameRTLSDR;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//   default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//     return spyserver_source_c::NameUnknown;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+//   }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+// }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::connect()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool hasError = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (receiver_thread != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << "SpyServer: Trying to connect" << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  client.connect_conn();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  is_connected = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << "SpyServer: Connected" << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  say_hello();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cleanup();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  terminated = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  got_sync_info = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  got_device_info = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::exception error;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  receiver_thread  = new std::thread(&spyserver_source_c::thread_loop, this);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (int i=0; i<1000 && !hasError; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (got_device_info) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (device_info.DeviceType == DEVICE_INVALID) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        error = std::runtime_error( std::string(__FUNCTION__) + " " + "Server is up but no device is available");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        hasError = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (got_sync_info) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        std::cerr << "SpyServer: Got sync Info" << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        on_connect();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::this_thread::sleep_for(std::chrono::milliseconds(1));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  disconnect();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (hasError) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    throw error;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  throw std::runtime_error( std::string(__FUNCTION__) + " " + "Server didn't send the device capability and synchronization info.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::disconnect()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  terminated = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (is_connected) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    client.close_conn();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (receiver_thread != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    receiver_thread->join();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    receiver_thread = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cleanup();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::on_connect()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_setting(SETTING_STREAMING_MODE, { streaming_mode });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_setting(SETTING_IQ_FORMAT, { STREAM_FORMAT_INT16 });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  // set_setting(SETTING_FFT_FORMAT, { STREAM_FORMAT_UINT8 });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  //set_setting(SETTING_FFT_DISPLAY_PIXELS, { displayPixels });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  //set_setting(SETTING_FFT_DB_OFFSET, { fftOffset });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  //set_setting(SETTING_FFT_DB_RANGE, { fftRange });
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  //device_info.MaximumSampleRate
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  //availableSampleRates
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << "SpyServer: Maximum Sample Rate: " << device_info.MaximumSampleRate << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (unsigned int i = device_info.MinimumIQDecimation; i<=device_info.DecimationStageCount; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    uint32_t sr = device_info.MaximumSampleRate / (1 << i);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _sample_rates.push_back( std::pair<double, uint32_t>((double)sr, i ) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::sort(_sample_rates.begin(), _sample_rates.end());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool spyserver_source_c::set_setting(uint32_t settingType, std::vector<uint32_t> params) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector<uint8_t> argBytes;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (params.size() > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    argBytes = std::vector<uint8_t>(sizeof(SettingType) + params.size() * sizeof(uint32_t));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    uint8_t *settingBytes = (uint8_t *) &settingType;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    for (unsigned int i=0; i<sizeof(uint32_t); i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      argBytes[i] = settingBytes[i];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::memcpy(&argBytes[0]+sizeof(uint32_t), &params[0], sizeof(uint32_t) * params.size());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    argBytes = std::vector<uint8_t>();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return send_command(CMD_SET_SETTING, argBytes);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool spyserver_source_c::say_hello() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const uint8_t *protocolVersionBytes = (const uint8_t *) &ProtocolVersion;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const uint8_t *softwareVersionBytes = (const uint8_t *) SoftwareID.c_str();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector<uint8_t> args = std::vector<uint8_t>(sizeof(ProtocolVersion) + SoftwareID.size());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::memcpy(&args[0], protocolVersionBytes, sizeof(ProtocolVersion));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::memcpy(&args[0] + sizeof(ProtocolVersion), softwareVersionBytes, SoftwareID.size());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return send_command(CMD_HELLO, args);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::cleanup() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.DeviceType = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.DeviceSerial = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.DecimationStageCount = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.GainStageCount = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.MaximumSampleRate = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.MaximumBandwidth = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.MaximumGainIndex = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.MinimumFrequency = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    device_info.MaximumFrequency = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _gain = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _digitalGain = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    //displayCenterFrequency = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    //device_center_frequency = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    //displayDecimationStageCount = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    //channel_decimation_stage_count = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    //minimum_tunable_frequency = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    //maximum_tunable_frequency = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    can_control = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    got_device_info = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    got_sync_info = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    last_sequence_number = ((uint32_t)-1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    dropped_buffers = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    down_stream_bytes = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    parser_phase = AcquiringHeader;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    parser_position = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    streaming = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    terminated = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::thread_loop() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  parser_phase = AcquiringHeader;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  parser_position = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  char buffer[BufferSize];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  try {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    while(!terminated) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (terminated) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      uint32_t availableData = client.available_data();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (availableData > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        availableData = availableData > BufferSize ? BufferSize : availableData;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        client.receive_data(buffer, availableData);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        parse_message(buffer, availableData);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } catch (std::exception &e) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::cerr << "SpyServer: Error on ThreadLoop: " << e.what() << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (body_buffer != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    delete[] body_buffer;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    body_buffer = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  cleanup();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::parse_message(char *buffer, uint32_t len) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  down_stream_bytes++;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  while (len > 0 && !terminated) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (parser_phase == AcquiringHeader) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      while (parser_phase == AcquiringHeader && len > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        consumed = parse_header(buffer, len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        buffer += consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        len -= consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (parser_phase == ReadingData) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        uint8_t client_major = (SPYSERVER_PROTOCOL_VERSION >> 24) & 0xFF;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        uint8_t client_minor = (SPYSERVER_PROTOCOL_VERSION >> 16) & 0xFF;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        uint8_t server_major = (header.ProtocolID >> 24) & 0xFF;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        uint8_t server_minor = (header.ProtocolID >> 16) & 0xFF;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        //uint16_t server_build = (header.ProtocolID & 0xFFFF);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (client_major != server_major || client_minor != server_minor) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          throw std::runtime_error( std::string(__FUNCTION__) + " " + "Server is running an unsupported protocol version.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (header.BodySize > SPYSERVER_MAX_MESSAGE_BODY_SIZE) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          throw std::runtime_error( std::string(__FUNCTION__) + " " + "The server is probably buggy.");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (body_buffer == NULL || body_buffer_length < header.BodySize) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (body_buffer != NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            delete[] body_buffer;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          body_buffer = new uint8_t[header.BodySize];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (parser_phase == ReadingData) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      consumed = parse_body(buffer, len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      buffer += consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      len -= consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (parser_phase == AcquiringHeader) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        if (header.MessageType != MSG_TYPE_DEVICE_INFO && header.MessageType != MSG_TYPE_CLIENT_SYNC) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          int32_t gap = header.SequenceNumber - last_sequence_number - 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          last_sequence_number = header.SequenceNumber;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          dropped_buffers += gap;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          if (gap > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            std::cerr << "SpyServer: Lost " << gap << " frames from SpyServer!";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        handle_new_message();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int spyserver_source_c::parse_header(char *buffer, uint32_t length) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  auto consumed = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  while (length > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    int to_write = std::min((uint32_t)(sizeof(MessageHeader) - parser_position), length);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::memcpy(&header + parser_position, buffer, to_write);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    length -= to_write;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    buffer += to_write;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    parser_position += to_write;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    consumed += to_write;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (parser_position == sizeof(MessageHeader)) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      parser_position = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (header.BodySize > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        parser_phase = ReadingData;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      return consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int spyserver_source_c::parse_body(char* buffer, uint32_t length) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  auto consumed = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  while (length > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    int to_write = std::min((int) header.BodySize - parser_position, length);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::memcpy(body_buffer + parser_position, buffer, to_write);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    length -= to_write;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    buffer += to_write;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    parser_position += to_write;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    consumed += to_write;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (parser_position == header.BodySize) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      parser_position = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      parser_phase = AcquiringHeader;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      return consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return consumed;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool spyserver_source_c::send_command(uint32_t cmd, std::vector<uint8_t> args) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!is_connected) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool result;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t headerLen = sizeof(CommandHeader);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint16_t argLen = args.size();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint8_t *buffer = new uint8_t[headerLen + argLen];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  CommandHeader header;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  header.CommandType = cmd;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  header.BodySize = argLen;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (uint32_t i=0; i<sizeof(CommandHeader); i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    buffer[i] = ((uint8_t *)(&header))[i];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (argLen > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    for (uint16_t i=0; i<argLen; i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      buffer[i+headerLen] = args[i];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  try {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    client.send_data((char *)buffer, headerLen+argLen);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    result = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } catch (std::exception &e) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    result = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  delete[] buffer;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return result;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::handle_new_message() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (terminated) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  switch (header.MessageType) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    case MSG_TYPE_DEVICE_INFO:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      process_device_info();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    case MSG_TYPE_CLIENT_SYNC:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      process_client_sync();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    case MSG_TYPE_UINT8_IQ:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      process_uint8_samples();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    case MSG_TYPE_INT16_IQ:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      process_int16_samples();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    case MSG_TYPE_FLOAT_IQ:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      process_float_samples();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    case MSG_TYPE_UINT8_FFT:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      process_uint8_fft();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    default:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::process_device_info() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::memcpy(&device_info, body_buffer, sizeof(DeviceInfo));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  minimum_tunable_frequency = device_info.MinimumFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  maximum_tunable_frequency = device_info.MaximumFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  got_device_info = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::process_client_sync() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ClientSync sync;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::memcpy(&sync, body_buffer, sizeof(ClientSync));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  can_control = sync.CanControl != 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _gain = (double) sync.Gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  device_center_frequency = sync.DeviceCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  channel_center_frequency = sync.IQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _center_freq = (double) sync.IQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  switch (streaming_mode) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case STREAM_MODE_FFT_ONLY:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case STREAM_MODE_FFT_IQ:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    minimum_tunable_frequency = sync.MinimumFFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    maximum_tunable_frequency = sync.MaximumFFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  case STREAM_MODE_IQ_ONLY:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    minimum_tunable_frequency = sync.MinimumIQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    maximum_tunable_frequency = sync.MaximumIQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  got_sync_info = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::process_uint8_samples() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t n_avail, to_copy, num_samples = (header.BodySize) / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _fifo_lock.lock();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint8_t *sample = (uint8_t *)body_buffer;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  n_avail = _fifo->capacity() - _fifo->size();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  to_copy = (n_avail < num_samples ? n_avail : num_samples / 2);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (size_t i=0; i < to_copy; i++)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _fifo->push_back(gr_complex(*sample - 128.f / 128.f, *(sample+1) - 128.f / 128.f));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    sample += 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _fifo_lock.unlock();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (to_copy) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _samp_avail.notify_one();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (to_copy < num_samples)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::cerr << "O" << std::flush;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::process_int16_samples() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t n_avail, to_copy, num_samples = (header.BodySize / 2) / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _fifo_lock.lock();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int16_t *sample = (int16_t *)body_buffer;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  n_avail = _fifo->capacity() - _fifo->size();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  to_copy = (n_avail < num_samples ? n_avail : num_samples);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (size_t i=0; i < to_copy; i++)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _fifo->push_back(gr_complex(*sample / 32768.f, *(sample+1) / 32768.f));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    sample += 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _fifo_lock.unlock();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (to_copy) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _samp_avail.notify_one();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (to_copy < num_samples)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::cerr << "O" << std::flush;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::process_float_samples() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t n_avail, to_copy, num_samples = (header.BodySize / 4) / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _fifo_lock.lock();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  float *sample = (float *)body_buffer;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  n_avail = _fifo->capacity() - _fifo->size();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  to_copy = (n_avail < num_samples ? n_avail : num_samples);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (size_t i=0; i < to_copy; i++)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _fifo->push_back(gr_complex(*sample, *(sample+1)));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    sample += 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _fifo_lock.unlock();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (to_copy) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _samp_avail.notify_one();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::set_stream_state() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_setting(SETTING_STREAMING_ENABLED, {(unsigned int)(streaming ? 1 : 0)});
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_sample_rate(double sampleRate) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (sampleRate <= 0xFFFFFFFF) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::cerr << "SpyServer: Setting sample rate to " << sampleRate << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    for (unsigned int i=0; i<_sample_rates.size(); i++) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (_sample_rates[i].first == sampleRate) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              channel_decimation_stage_count = _sample_rates[i].second;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              set_setting(SETTING_IQ_DECIMATION, {channel_decimation_stage_count});
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              _sample_rate = sampleRate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+              return get_sample_rate();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << "SpyServer: Sample rate not supported: " << sampleRate << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << "SpyServer: Supported Sample Rates: " << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (std::pair<double, uint32_t> sr: _sample_rates) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::cerr << "SpyServer:   " << sr.first << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  throw std::runtime_error(boost::str( boost::format("Unsupported samplerate: %gM") % (sampleRate/1e6) ) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_center_freq(double centerFrequency, size_t chan) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (centerFrequency <= 0xFFFFFFFF) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    channel_center_frequency = (uint32_t) centerFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    set_setting(SETTING_IQ_FREQUENCY, {channel_center_frequency});
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return centerFrequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << boost::format("Unsupported center frequency: %gM") % (centerFrequency/1e6) << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return this->get_center_freq(chan);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::process_uint8_fft() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  // TODO
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  // // std::cerr << "UInt8 FFT Samples processing not implemented!!!" << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Our virtual destructor.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+spyserver_source_c::~spyserver_source_c ()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  disconnect();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (_fifo)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    delete _fifo;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _fifo = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  delete[] header_data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  header_data = NULL;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool spyserver_source_c::start()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (!streaming) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::cerr << "SpyServer: Starting Streaming" << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    streaming = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    down_stream_bytes = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    set_stream_state();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool spyserver_source_c::stop()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (streaming) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::cerr << "SpyServer: Stopping Streaming" << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    streaming = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    down_stream_bytes = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    set_stream_state();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+int spyserver_source_c::work( int noutput_items,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                        gr_vector_const_void_star &input_items,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                        gr_vector_void_star &output_items )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gr_complex *out = (gr_complex *)output_items[0];
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ( ! streaming )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return WORK_DONE;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  boost::unique_lock<boost::mutex> lock(_fifo_lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /* Wait until we have the requested number of samples */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int n_samples_avail = _fifo->size();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  while (n_samples_avail < noutput_items) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _samp_avail.wait(lock);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    n_samples_avail = _fifo->size();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for(int i = 0; i < noutput_items; ++i) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    out[i] = _fifo->at(0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _fifo->pop_front();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  //std::cerr << "-" << std::flush;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return noutput_items;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::vector<std::string> spyserver_source_c::get_devices(bool fake)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector<std::string> devices;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string label;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if ( fake )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::string args = "spyserver=0,host=localhost,port=5555";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    args += ",label='Spyserver Client'";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    devices.push_back( args );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return devices;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+size_t spyserver_source_c::get_num_channels()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::meta_range_t spyserver_source_c::get_sample_rates()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::meta_range_t range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (size_t i = 0; i < _sample_rates.size(); i++)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    range += osmosdr::range_t( _sample_rates[i].first );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::get_sample_rate()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return _sample_rate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::freq_range_t spyserver_source_c::get_freq_range( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::freq_range_t range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  range += osmosdr::range_t( minimum_tunable_frequency, maximum_tunable_frequency );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::get_center_freq( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return _center_freq;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_freq_corr( double ppm, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return get_freq_corr( chan );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::get_freq_corr( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::vector<std::string> spyserver_source_c::get_gain_names( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector< std::string > names;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (can_control) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    names += "LNA";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  names += "Digital";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return names;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::gain_range_t spyserver_source_c::get_gain_range( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return osmosdr::gain_range_t( 0, 16, 1 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::gain_range_t spyserver_source_c::get_gain_range( const std::string & name, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (name == "Digital") {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return osmosdr::gain_range_t( 0, 1, 1 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return get_gain_range(chan);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool spyserver_source_c::set_gain_mode( bool automatic, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return get_gain_mode(chan);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool spyserver_source_c::get_gain_mode( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_gain( double gain, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (can_control) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _gain = gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    set_setting(SETTING_GAIN, {(uint32_t)gain});
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    std::cerr << "Spyserver: The server does not allow you to change the gains." << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return _gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_lna_gain( double gain, size_t chan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return set_gain(gain, chan);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_gain( double gain, const std::string & name, size_t chan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (name == "Digital") {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    _digitalGain = gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    set_setting(SETTING_IQ_DIGITAL_GAIN, {((uint32_t)gain) * 0xFFFFFFFF});
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return _gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return set_gain(gain, chan);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::get_gain( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return chan == 0 ? _gain : _digitalGain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return _gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::get_gain( const std::string & name, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (name == "Digital") {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return _digitalGain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return get_gain(chan);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_mix_gain(double gain, size_t chan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return _gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_if_gain(double gain, size_t chan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return _gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::vector< std::string > spyserver_source_c::get_antennas( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector< std::string > antennas;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  antennas += get_antenna( chan );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return antennas;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::string spyserver_source_c::set_antenna( const std::string & antenna, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return get_antenna( chan );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::string spyserver_source_c::get_antenna( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return "RX";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::set_bandwidth( double bandwidth, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return get_bandwidth( chan );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double spyserver_source_c::get_bandwidth( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return _sample_rate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::freq_range_t spyserver_source_c::get_bandwidth_range( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::freq_range_t bandwidths;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bandwidths += osmosdr::range_t( get_bandwidth( chan ) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return bandwidths;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void spyserver_source_c::set_biast( bool enabled ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool spyserver_source_c::get_biast() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-\ No newline at end of file
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/spyserver/spyserver_source_c.h lib/spyserver/spyserver_source_c.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..d72c562
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/spyserver/spyserver_source_c.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,206 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * This file is part of GNU Radio
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * any later version.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifndef INCLUDED_SPYSERVER_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define INCLUDED_SPYSERVER_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <thread>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <atomic>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/circular_buffer.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/thread/mutex.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/thread/condition_variable.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <gnuradio/sync_block.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "source_iface.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "spyserver_protocol.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "tcp_client.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+class spyserver_source_c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * We use boost::shared_ptr's instead of raw pointers for all access
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * to gr::blocks (and many other data structures).  The shared_ptr gets
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * us transparent reference counting, which greatly simplifies storage
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * management issues.  This is especially helpful in our hybrid
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * C++ / Python system.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * As a convention, the _sptr suffix indicates a boost::shared_ptr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+typedef boost::shared_ptr<spyserver_source_c> spyserver_source_c_sptr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*!
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * \brief Return a shared_ptr to a new instance of spyserver_source_c.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * To avoid accidental use of raw pointers, spyserver_source_c's
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * constructor is private.  make_spyserver_source_c is the public
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * interface for creating new instances.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+spyserver_source_c_sptr make_spyserver_source_c (const std::string & args = "");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*!
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * \brief Provides a stream of complex samples.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * \ingroup block
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+class spyserver_source_c :
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    public gr::sync_block,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    public source_iface
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+private:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  // The friend declaration allows make_spyserver_source_c to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  // access the private constructor.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  friend spyserver_source_c_sptr make_spyserver_source_c (const std::string & args);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  /*!
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   * \brief Provides a stream of complex samples.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+   */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  spyserver_source_c (const std::string & args);   // private constructor
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+public:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ~spyserver_source_c ();  // public destructor
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool start();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool stop();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int work( int noutput_items,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            gr_vector_const_void_star &input_items,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            gr_vector_void_star &output_items );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static std::vector< std::string > get_devices(bool fake = false);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t get_num_channels( void );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::meta_range_t get_sample_rates( void );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_sample_rate( double rate );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_sample_rate( void );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_center_freq( double freq, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_center_freq( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_freq_corr( double ppm, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_freq_corr( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector<std::string> get_gain_names( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool set_gain_mode( bool automatic, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool get_gain_mode( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_gain( double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_gain( double gain, const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_gain( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_gain( const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_lna_gain( double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_mix_gain(double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_if_gain( double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_bb_gain( double gain, size_t chan = 0 ) { return set_mix_gain(gain, chan); };
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector< std::string > get_antennas( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string set_antenna( const std::string & antenna, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string get_antenna( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_bandwidth( double bandwidth, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_bandwidth( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void set_biast( bool enabled );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool get_biast();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+private:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static constexpr unsigned int BufferSize = 64 * 1024;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const uint32_t ProtocolVersion = SPYSERVER_PROTOCOL_VERSION;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const std::string SoftwareID = std::string("gr-osmosdr");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const std::string NameNoDevice = std::string("SpyServer - No Device");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const std::string NameAirspyOne = std::string("SpyServer - Airspy One");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const std::string NameAirspyHF = std::string("SpyServer - Airspy HF+");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const std::string NameRTLSDR = std::string("SpyServer - RTLSDR");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  const std::string NameUnknown = std::string("SpyServer - Unknown Device");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t minimum_tunable_frequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t maximum_tunable_frequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t device_center_frequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t channel_center_frequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t channel_decimation_stage_count;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  tcp_client client;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void connect();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void disconnect();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void thread_loop();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool say_hello();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void cleanup();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void on_connect();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool set_setting(uint32_t settingType, std::vector<uint32_t> params);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool send_command(uint32_t cmd, std::vector<uint8_t> args);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void parse_message(char *buffer, uint32_t len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int parse_header(char *buffer, uint32_t len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int parse_body(char *buffer, uint32_t len);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void process_device_info();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void process_client_sync();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void process_uint8_samples();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void process_int16_samples();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void process_float_samples();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void process_uint8_fft();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void handle_new_message();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void set_stream_state();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::atomic_bool terminated;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::atomic_bool streaming;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::atomic_bool got_device_info;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::atomic_bool got_sync_info;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::atomic_bool can_control;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::atomic_bool is_connected;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::thread *receiver_thread;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t dropped_buffers;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::atomic<int64_t> down_stream_bytes;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint8_t *header_data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint8_t *body_buffer;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint64_t body_buffer_length;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t parser_position;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t last_sequence_number;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string ip;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int port;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  DeviceInfo device_info;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  MessageHeader header;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t streaming_mode;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uint32_t parser_phase;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  boost::circular_buffer<gr_complex> *_fifo;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  boost::mutex _fifo_lock;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  boost::condition_variable _samp_avail;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector< std::pair<double, uint32_t> > _sample_rates;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double _sample_rate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double _center_freq;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double _gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double _digitalGain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* INCLUDED_SPYSERVER_SOURCE_C_H */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/spyserver/tcp_client.cc lib/spyserver/tcp_client.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..78bb54b
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/spyserver/tcp_client.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,163 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright 2018 Lucas Teske <lucas@teske.com.br>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * any later version.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "tcp_client.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <cstdio>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sstream>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <iostream>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <winsock2.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <Ws2tcpip.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <atomic>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   ifdef _MSC_VER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   pragma comment(lib, "ws2_32.lib")
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# ifndef MSG_WAITALL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   define MSG_WAITALL (1 << 3)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <sys/socket.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <arpa/inet.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <sys/resource.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <sys/select.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <sys/ioctl.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <netdb.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# include <unistd.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# define ioctlsocket ioctl
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(_WIN32) || defined(__APPLE__)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    #ifndef MSG_NOSIGNAL
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        #define MSG_NOSIGNAL 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::atomic_bool tcp_client::initialized(false);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::atomic_uint tcp_client::sockCount(0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void tcp_client::socket_initialize() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (!initialized) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        initialized = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        sockCount = 1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        WSADATA wsa_data;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        WSAStartup(MAKEWORD(1, 1), &wsa_data);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        sockCount++;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+tcp_client::tcp_client(std::string addr, int port)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    this->port = port;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    #ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    socket_initialize();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    hostent * record = gethostbyname(addr.c_str());
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (record == NULL) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      throw std::runtime_error( std::string(__FUNCTION__) + " " +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                              "Cannot resolve: " + addr );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    in_addr * address = (in_addr *)record->h_addr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    memset(&socketAddr, 0x00, sizeof(sockaddr_in));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    socketAddr.sin_addr = *address;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void tcp_client::connect_conn() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  s = socket(AF_INET, SOCK_STREAM, 0);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (s < 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    throw std::runtime_error("Socket Error Code " + std::to_string(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  socketAddr.sin_family = AF_INET;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  socketAddr.sin_port = htons(port);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  int x = connect(s, (struct sockaddr *) &socketAddr, sizeof(socketAddr));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (x < 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    throw std::runtime_error("Socket Error Code " + std::to_string(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void tcp_client::close_conn() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (s > 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      int status = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      status = shutdown(s, SD_BOTH);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (status == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          status = closesocket(s);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      status = shutdown(s, 2);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      if (status == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          status = close(s);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+tcp_client::~tcp_client() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    #ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    sockCount--;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (!sockCount) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        WSACleanup();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void tcp_client::receive_data(char *data, int length) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    long n = recv(s, data, length, MSG_WAITALL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (n == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        throw std::runtime_error("Client Disconnected");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    } else if (n != length) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        throw std::runtime_error("Socket Error Code " + std::to_string(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void tcp_client::send_data(char * data, int length) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    int n = send(s, data, length, MSG_NOSIGNAL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (n == 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        throw std::runtime_error("Client Disconnected");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    } else if (n != length) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        throw std::runtime_error("Socket Error Code " + std::to_string(errno));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+uint64_t tcp_client::available_data() {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if (s < 0) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        return 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    unsigned long bytesAvailable = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    int ret = ioctlsocket(s, FIONREAD, &bytesAvailable);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    switch (ret) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        case EINVAL:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        case EFAULT:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        case ENOTTY:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        throw std::runtime_error("Socket Error Code " + std::to_string(ret));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        case EBADF:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        throw std::runtime_error("Client Disconnected");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    return bytesAvailable;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-\ No newline at end of file
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/spyserver/tcp_client.h lib/spyserver/tcp_client.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..249a718
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/spyserver/tcp_client.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,82 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright 2018 Lucas Teske <lucas@teske.com.br>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * any later version.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifndef TCPCLIENT_H_
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define TCPCLIENT_H_
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <atomic>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <chrono>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <thread>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <cstdint>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <stdint.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <memory.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <sstream>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <iostream>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   include <winsock2.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   include <Ws2tcpip.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#else
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   include <sys/socket.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#   include <netinet/in.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#if defined(__GNUC__) || defined(__MINGW32__)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+class tcp_client {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+private:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    int port;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    #ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    static std::atomic_bool initialized;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    static std::atomic_uint sockCount;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    void socket_initialize();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+protected:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    struct sockaddr_in socketAddr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    int s;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+public:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    tcp_client() {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    tcp_client(std::string addr, int port);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ~tcp_client();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    void connect_conn();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    void close_conn();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    void receive_data(char *data, int length);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    void send_data(char *data, int length);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    uint64_t available_data();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    inline void wait_for_data(uint64_t bytes, uint32_t timeout) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        uint32_t checkTime = (int) time(NULL);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        while (available_data() < bytes) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            if (((int) time(NULL)) - checkTime > timeout) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                return;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+            std::this_thread::sleep_for(std::chrono::microseconds(10));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif /* TCPCLIENT_H_ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-2.26.1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/science/gr-osmosdr/files/add_gr-iio_support.patch b/science/gr-osmosdr/files/add_gr-iio_support.patch
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 3a2df9c11e5..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/science/gr-osmosdr/files/add_gr-iio_support.patch
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,616 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git CMakeLists.txt CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 74c54f5..1f3678e 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -183,6 +183,7 @@ find_package(SoapySDR NO_MODULE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- find_package(LibFreeSRP)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- find_package(LibXTRX)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- find_package(Doxygen)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+find_package(GNURadioIIO)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     # Python
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ##########
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git cmake/Modules/FindGNURadioIIO.cmake cmake/Modules/FindGNURadioIIO.cmake
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..f26da38
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ cmake/Modules/FindGNURadioIIO.cmake
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,34 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+INCLUDE(FindPkgConfig)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+PKG_CHECK_MODULES(PC_GNURADIO_IIO gnuradio-iio)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+FIND_PATH(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    GNURADIO_IIO_INCLUDE_DIRS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NAMES iio/api.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    HINTS $ENV{GNURADIO_IIO_DIR}/include
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ${PC_GNURADIO_IIO_INCLUDEDIR}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    PATHS /usr/local/include
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /usr/include
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+FIND_LIBRARY(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     GNURADIO_IIO_LIBRARIES
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     NAMES gnuradio-iio
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     HINTS $ENV{GNURADIO_IIO_DIR}/lib
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+         ${PC_GNURADIO_IIO_LIBDIR}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+     PATHS /usr/local/lib
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /usr/local/lib64
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /usr/lib
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /usr/lib64
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+if(GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set(GNURADIO_IIO_FOUND TRUE CACHE INTERNAL "gnuradio-iio found")
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  message(STATUS "Found gnuradio-iio: ${GNURADIO_IIO_INCLUDE_DIRS}, ${GNURADIO_IIO_LIBRARIES}")
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+else(GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set(GNURADIO_IIO_FOUND FALSE CACHE INTERNAL "gnuradio-iio found")
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  message(STATUS "gnuradio-iio not found.")
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+endif(GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+INCLUDE(FindPackageHandleStandardArgs)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_IIO DEFAULT_MSG GNURADIO_IIO_LIBRARIES GNURADIO_IIO_INCLUDE_DIRS)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+MARK_AS_ADVANCED(GNURADIO_IIO_LIBRARIES GNURADIO_IIO_INCLUDE_DIRS)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git cmake/Modules/FindIIO.cmake cmake/Modules/FindIIO.cmake
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..bb87a4b
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ cmake/Modules/FindIIO.cmake
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,28 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# Find the IIO userspace library
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+INCLUDE(FindPkgConfig)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+PKG_CHECK_MODULES(PC_IIO iio)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+FIND_PATH(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    IIO_INCLUDE_DIRS
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NAMES iio.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    HINTS $ENV{IIO_DIR}/include
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ${PC_IIO_INCLUDEDIR}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    PATHS /usr/local/include
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /usr/include
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+FIND_LIBRARY(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    IIO_LIBRARIES
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    NAMES iio
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    HINTS $ENV{IIO_DIR}/lib
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+        ${PC_IIO_LIBDIR}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    PATHS /usr/local/lib
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+          /usr/lib
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+INCLUDE(FindPackageHandleStandardArgs)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+FIND_PACKAGE_HANDLE_STANDARD_ARGS(IIO DEFAULT_MSG IIO_LIBRARIES IIO_INCLUDE_DIRS)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+MARK_AS_ADVANCED(IIO_LIBRARIES IIO_INCLUDE_DIRS)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/CMakeLists.txt lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 1bb8655..8612409 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -167,6 +167,14 @@ if(ENABLE_RTL_TCP)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     add_subdirectory(rtl_tcp)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- endif(ENABLE_RTL_TCP)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# Setup IIO component
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+GR_REGISTER_COMPONENT("IIO Devices (like PlutoSDR)" ENABLE_IIO GNURADIO_IIO_FOUND)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+if(ENABLE_IIO)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    add_subdirectory(plutosdr)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+endif(ENABLE_IIO)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Setup UHD component
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/config.h.in lib/config.h.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index d96cd80..8c8bf49 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- lib/config.h.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/config.h.in
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -19,6 +19,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_REDPITAYA
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_FREESRP
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #cmakedefine ENABLE_XTRX
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#cmakedefine ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- //provide NAN define for MSVC older than VC12
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #if defined(_MSC_VER) && (_MSC_VER < 1800)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/device.cc lib/device.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index d072e27..fb5aaa1 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- lib/device.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/device.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -85,6 +85,10 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <freesrp_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <plutosdr_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "arg_helpers.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- using namespace osmosdr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -185,6 +189,10 @@ devices_t device::find(const device_t &hint)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   for (std::string dev : soapy_source_c::get_devices())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  for (std::string dev : plutosdr_source_c::get_devices())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   /* software-only sources should be appended at the very end,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    * hopefully resulting in hardware sources to be shown first
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/plutosdr/CMakeLists.txt lib/plutosdr/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..835f4f2
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/plutosdr/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,38 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# Copyright 2012 Free Software Foundation, Inc.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# This file is part of GNU Radio
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# any later version.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+# This file included, use CMake directory variables
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+target_include_directories(gnuradio-osmosdr PRIVATE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${CMAKE_CURRENT_SOURCE_DIR}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${GNURADIO_IIO_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${IIO_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+target_link_libraries(gnuradio-osmosdr
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${GNURADIO_IIO_LIBRARIES}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${IIO_LIBRARIES}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+list(APPEND gr_osmosdr_srcs
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    ${CMAKE_CURRENT_SOURCE_DIR}/plutosdr_source_c.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/plutosdr/plutosdr_source_c.cc lib/plutosdr/plutosdr_source_c.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..009d4b2
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/plutosdr/plutosdr_source_c.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,262 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright 2017 Dimitri Stolnikov <horiz0n@gmx.net>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * any later version.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <boost/assign.hpp>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <iostream>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "arg_helpers.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "osmosdr/source.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "plutosdr_source_c.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+using namespace boost::assign;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+plutosdr_source_c_sptr make_plutosdr_source_c(const std::string &args)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gnuradio::get_initial_sptr(new plutosdr_source_c(args));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+plutosdr_source_c::plutosdr_source_c(const std::string &args) :
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    gr::hier_block2("plutosdr_source_c",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                   gr::io_signature::make(0, 0, 0),
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                   gr::io_signature::make(1, 1, sizeof(gr_complex)))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  uri = "ip:pluto.local";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  frequency = 434000000;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  samplerate = 2500000;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  decimation = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bandwidth = 2000000;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  buffer_size = 0x4000;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  quadrature = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  rfdc = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bbdc = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gain_auto = false;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gain_value = 50;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  filter = "";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  filter_auto = true;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _freq_corr = 0.0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dict_t dict = params_to_dict(args);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (dict.count("uri"))
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    uri = boost::lexical_cast< std::string >( dict["uri"] );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::cerr << "Using PlutoSDR URI = " << uri << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _src = gr::iio::pluto_source::make(uri, frequency, samplerate,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                     bandwidth, buffer_size,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                     quadrature, rfdc, bbdc,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                     "manual", gain_value,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                     filter.c_str(), filter_auto);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  connect( _src, 0, self(), 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+plutosdr_source_c::~plutosdr_source_c()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::vector< std::string > plutosdr_source_c::get_devices()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector< std::string > devices;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string args = "plutosdr,label='PlutoSDR'";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  devices.push_back( args );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return devices;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::string plutosdr_source_c::name()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return "PlutoSDR";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+size_t plutosdr_source_c::get_num_channels()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return output_signature()->max_streams();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::meta_range_t plutosdr_source_c::get_sample_rates( void )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::meta_range_t rates;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  rates += osmosdr::range_t( 2500000 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  rates += osmosdr::range_t( 5000000 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  rates += osmosdr::range_t( 10000000 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  rates += osmosdr::range_t( 20000000 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return rates;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::set_sample_rate( double rate )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  samplerate = (unsigned long) rate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_params();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return samplerate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::get_sample_rate( void )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return samplerate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::freq_range_t plutosdr_source_c::get_freq_range( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::freq_range_t range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  range += osmosdr::range_t( 70.0e6, 6000.0e6, 1.0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::set_center_freq( double freq, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  frequency = (unsigned long long) freq;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_params();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return freq;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::get_center_freq( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return frequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::set_freq_corr( double ppm, size_t chan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _freq_corr = ppm;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_params();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return ppm;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::get_freq_corr( size_t chan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return _freq_corr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::vector<std::string> plutosdr_source_c::get_gain_names( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector< std::string > gains;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gains.push_back( "RF" );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gains;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::gain_range_t plutosdr_source_c::get_gain_range( size_t chan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::gain_range_t range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  range += osmosdr::range_t( -10, 77, 1 );   // https://wiki.analog.com/resources/tools-software/linux-drivers/iio-transceiver/ad9361#rx_gain_control
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+osmosdr::gain_range_t plutosdr_source_c::get_gain_range( const std::string & name,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                                                         size_t chan)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::gain_range_t range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  range += osmosdr::range_t( -10, 77, 1 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return range;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool plutosdr_source_c::set_gain_mode( bool automatic, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gain_auto = automatic;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_params();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return automatic;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+bool plutosdr_source_c::get_gain_mode( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gain_auto;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::set_gain( double gain, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gain_value = gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_params();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::set_gain( double gain, const std::string & name, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gain_value = gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_params();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gain;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::get_gain( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gain_value;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::get_gain( const std::string & name, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return gain_value;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::vector< std::string > plutosdr_source_c::get_antennas( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector< std::string > antennas;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  antennas += get_antenna( chan );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return antennas;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::string plutosdr_source_c::set_antenna( const std::string & antenna, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return get_antenna( chan );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+std::string plutosdr_source_c::get_antenna( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return "A_BALANCED";
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::set_bandwidth( double bw, size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  if (bw == 0.0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    bw = 0.8 * samplerate;  // auto bandwidth
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bandwidth = (unsigned long)bw;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  set_params();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return bandwidth;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+double plutosdr_source_c::get_bandwidth( size_t chan )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  return bandwidth;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+void plutosdr_source_c::set_params( void )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  unsigned long long freq = ((double)frequency * (1.0 + _freq_corr * 0.000001));
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  // FIXME: gain_mode string can be manual / slow_attack / fast_attack / hybrid
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  _src->set_params( freq, samplerate, bandwidth, quadrature, rfdc, bbdc,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                    gain_auto ? "fast_attack" : "manual", gain_value,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+                    filter.c_str(), filter_auto );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/plutosdr/plutosdr_source_c.h lib/plutosdr/plutosdr_source_c.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-new file mode 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 0000000..c515ec9
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- /dev/null
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/plutosdr/plutosdr_source_c.h
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -0,0 +1,105 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+/*
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Copyright 2017 Dimitri Stolnikov <horiz0n@gmx.net>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * any later version.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ *
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifndef PLUTOSDR_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#define PLUTOSDR_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <gnuradio/blocks/float_to_complex.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <gnuradio/blocks/short_to_float.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <gnuradio/hier_block2.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <iio/pluto_source.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include "source_iface.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+class plutosdr_source_c;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+typedef boost::shared_ptr< plutosdr_source_c > plutosdr_source_c_sptr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+plutosdr_source_c_sptr make_plutosdr_source_c(const std::string &args = "");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+class plutosdr_source_c :
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    public gr::hier_block2,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    public source_iface
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+{
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+private:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  friend plutosdr_source_c_sptr make_plutosdr_source_c(const std::string &args);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  plutosdr_source_c(const std::string &args);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+public:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  ~plutosdr_source_c();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  static std::vector< std::string > get_devices();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string name();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  size_t get_num_channels( void );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::meta_range_t get_sample_rates( void );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_sample_rate( double rate );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_sample_rate( void );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_center_freq( double freq, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_center_freq( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_freq_corr( double ppm, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_freq_corr( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector<std::string> get_gain_names( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool set_gain_mode( bool automatic, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool get_gain_mode( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_gain( double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_gain( double gain, const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_gain( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_gain( const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::vector< std::string > get_antennas( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string set_antenna( const std::string & antenna, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string get_antenna( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double set_bandwidth( double bw, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double get_bandwidth( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+private:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  void set_params(void);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  gr::iio::pluto_source::sptr       _src;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string   uri;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  unsigned long long frequency;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  unsigned long samplerate;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  unsigned long decimation;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  unsigned long bandwidth;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  unsigned long buffer_size;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool quadrature;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool rfdc;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool bbdc;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool          gain_auto;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double        gain_value;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  std::string   filter;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  bool          filter_auto;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  double _freq_corr;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+};
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif // PLUTOSDR_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git lib/source_impl.cc lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 8f2028b..89899e7 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -92,6 +92,10 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include <xtrx_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#include <plutosdr_source_c.h>
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "arg_helpers.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #include "source_impl.h"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -165,6 +169,9 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #ifdef ENABLE_XTRX
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   dev_types.push_back("xtrx");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+  dev_types.push_back("plutosdr");
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-   std::cerr << "gr-osmosdr "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             << GR_OSMOSDR_VERSION << " (" << GR_OSMOSDR_LIBVER << ") "
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -245,6 +252,10 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     for (std::string dev : xtrx_source_c::get_devices())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    for (std::string dev : plutosdr_source_c::get_devices())
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- //    std::cerr << std::endl;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- //    for (std::string dev : dev_list)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -376,6 +387,13 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- #endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    if ( dict.count("plutosdr") ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      plutosdr_source_c_sptr src = make_plutosdr_source_c( arg );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+      block = src; iface = src.get();
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+#endif
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     if ( iface != NULL && long(block.get()) != 0 ) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-       _devs.push_back( iface );
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span></pre><pre style='margin:0'>

</pre>