<pre style='margin:0'>
Michael Dickens (michaelld) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/f0eb59ba9273132d28973a74125da1b20e83cbaf">https://github.com/macports/macports-ports/commit/f0eb59ba9273132d28973a74125da1b20e83cbaf</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit f0eb59ba9273132d28973a74125da1b20e83cbaf
</span>Author: Davide Gerhard <ra1nb0w@macports.org>
AuthorDate: Tue Mar 17 10:12:59 2020 +0100

<span style='display:block; white-space:pre;color:#404040;'>    gr-osmosdr: support gnuradio 3.8 and create subport for GR 3.7
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    - add IIO devices (like PlutoSDR) support
</span><span style='display:block; white-space:pre;color:#404040;'>    - add AirSpy SPY Server support
</span>---
 science/gr-osmosdr/Portfile                        |  348 ++--
 .../files/add_airspy-spyserver_support.patch       | 1740 ++++++++++++++++++++
 science/gr-osmosdr/files/add_gr-iio_support.patch  |  616 +++++++
 .../patch-fix-include-directories-ordering.diff    |  290 ----
 4 files changed, 2542 insertions(+), 452 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 c261f6346a5..3982f04f869 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;'>@@ -5,165 +5,156 @@ PortGroup           cmake 1.1
</span> PortGroup           active_variants 1.1
 PortGroup           github 1.0
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-compiler.cxx_standard 2011
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> name                gr-osmosdr
 maintainers         {michaelld @michaelld} openmaintainer
<span style='display:block; white-space:pre;background:#e0ffe0;'>+categories          science comms
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+homepage            http://sdr.osmocom.org/trac/wiki/GrOsmoSDR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+license             GPL-3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+platforms           darwin macosx
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+description         gr-osmosdr provides support for OsmoSDR hardware within GNU Radio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+long_description    Includes OSMO SDR support GNU Radio source and sink blocks in C++, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    Python, and GNU Radio Companion (grc).  This port also offers a wrapper functionality \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    for the FunCube Dongle, FunCube Dongle Pro+, HackRF, RFSpace, Ettus UHD, and rtl-sdr radios \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    and software.  By using gr-osmosdr source you can take advantage of a common software API \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    in your applications independent of the underlying radio hardware.
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-subport gr-osmosdr-38 {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# use C++11
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compiler.cxx_standard 2011
</span> 
 if {${name} eq ${subport}} {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    github.setup osmocom gr-osmosdr af2fda22b3b3745520ef38e9aaa757484871ee0c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    version      20200214-[string range ${github.version} 0 7]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    checksums    rmd160  36df660e45eba9a33e3e0af8554b89bd2e3e3741 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 sha256  4010a5fa7000b7d4382b87840f5399ba235fac34c5f19fb6ddac21093be5b49b \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 size    251199
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    revision     0
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    github.setup osmocom gr-osmosdr 4d83c6067f059b0c5015c3f59f8117bbd361e877
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    version      20170704
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    revision     11
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    checksums    rmd160 7be1f9f0663066ffdb04f7f3378aef007b6c00d9 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 sha256 77eb39c4f19f27fac9e3029a01030b9a64168e15adcda7ad3ad9a7b0ecbfdd00 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 size   278330
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    depends_lib-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        path:lib/libgnuradio-runtime.dylib:gnuradio
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # allow gr-osmosdr to work with gnuradio, gnuradio-devel, or gnuradio-next
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    conflicts gr37-osmosdr
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    depends_lib-append  path:lib/libgnuradio-runtime.dylib:gnuradio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set python_versions { 3.6 3.7 3.8 }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set default_python_variant +python37
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-} else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+subport gr37-osmosdr {
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    # just GR 3.8 version
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    github.setup osmocom gr-osmosdr 4d83c6067f059b0c5015c3f59f8117bbd361e877
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    version      20170704
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    revision     11
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    checksums    rmd160 7be1f9f0663066ffdb04f7f3378aef007b6c00d9 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 sha256 77eb39c4f19f27fac9e3029a01030b9a64168e15adcda7ad3ad9a7b0ecbfdd00 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                 size   278330
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # allow gr-osmosdr to work with gnuradio, gnuradio-devel, or gnuradio-next
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    name         gr37-osmosdr
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    depends_lib-append  path:lib/libgnuradio-runtime.dylib:gnuradio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    github.setup osmocom gr-osmosdr a95bbd74181de7df55cb14d728ee313314f6c092
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    github.livecheck.branch gr3.7
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    version      20191201-[string range ${github.version} 0 7]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    checksums    rmd160  1d4c0d1738a2c975caab615e89900d6ec958817b \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 sha256  baf4ce1cc0531c25e33c6b8b3c5eed12d2af1903c3c9a6c364a9b8360199fd48 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 size    278344
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    revision     0
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    conflicts gr-osmosdr
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-description         gr-osmosdr provides support for OsmoSDR hardware within GNU Radio
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-long_description    Includes OSMO SDR support GNU Radio source and sink blocks in C++, Python, and GNU Radio Companion (grc).  This port also offers a wrapper functionality for the FunCube Dongle, FunCube Dongle Pro+, HackRF, RFSpace, Ettus UHD, and rtl-sdr radios and software.  By using gr-osmosdr source you can take advantage of a common software API in your applications independent of the underlying radio hardware. This port is kept up with the gr-osmosdr GIT 'master' branch, which is [...]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set python_versions { 2.7 }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set default_python_variant +python27
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-categories          science comms
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-homepage            http://sdr.osmocom.org/trac/wiki/GrOsmoSDR
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-license             GPL-3
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-platforms           darwin macosx
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    depends_lib-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        port:gnuradio37
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# is gnuradio-next not installed?
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-set not_gr_next [catch {set installed [lindex [registry_active gnuradio-next] 0]}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Define the available variants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach py_ver ${python_versions} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set py_ver_no_dot [join [split ${py_ver} "."] ""]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set variant_line {variant python${py_ver_no_dot} description "Build with python ${py_ver} support"}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach py_over ${python_versions} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { ${py_ver} == ${py_over} } { continue }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set py_over_no_dot [join [split ${py_over} "."] ""]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        append variant_line " conflicts python${py_over_no_dot}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    append variant_line { { } }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    eval $variant_line
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[variant_isset python${py_ver_no_dot}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {${default_python_variant} != "+python${py_ver_no_dot}"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set default_python_variant ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# set the correct build type; not the default of 'MacPorts'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# set default python variant if not selected
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${default_python_variant} != ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    default_variants-append "${default_python_variant}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-if {[variant_isset debug]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    cmake.build_type Debug
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-} else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    cmake.build_type Release
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# If a python variant is enabled, activate it
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set active_python_version ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set active_python_version_no_dot ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach py_ver ${python_versions} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set py_ver_no_dot [join [split ${py_ver} "."] ""]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[variant_isset python${py_ver_no_dot}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set active_python_version        ${py_ver}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set active_python_version_no_dot ${py_ver_no_dot}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# add out-of-tree backend
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patchfiles-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    add_airspy-spyserver_support.patch \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    add_gr-iio_support.patch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> depends_build-append \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    port:pkgconfig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    port:pkgconfig \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    port:cppunit
</span> 
 depends_lib-append \
     port:boost \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    path:lib/libvolk.dylib:volk
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# patch to fix include_directories ordering to that internal-to-build
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# ones come before external-to-build ones
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-patchfiles-append patch-fix-include-directories-ordering.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-patch.pre_args -p1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# remove top-level library path, such that internal libraries are used
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# instead of any already-installed ones.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-configure.ldflags-delete -L${prefix}/lib
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# per user concensus: enable all variants except +debug and +universal
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-default_variants +docs +uhd +swig +hackrf +rtlsdr +bladeRF +airspy
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# can't use fcdproplus with gnuradio-next yet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    path:lib/libvolk.dylib:volk \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    port:python${active_python_version_no_dot}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-if {${not_gr_next}} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    default_variants +fcdproplus
</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;'>-# SoapySDR and SDRPlay work on 10.9 and newer only until fixed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-platform darwin {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {${os.major} > 12} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        default_variants +soapysdr +sdrplay
</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:#e0ffe0;'>+# specify the Python version to use
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set python_framework_dir ${frameworks_dir}/Python.framework/Versions/${active_python_version}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.args-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    -DPYTHON_EXECUTABLE=${python_framework_dir}/bin/python${active_python_version} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    -DPYTHON_INCLUDE_DIR=${python_framework_dir}/Headers \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    -DPYTHON_LIBRARY=${python_framework_dir}/Python \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    -DGR_PYTHON_DIR=${python_framework_dir}/lib/python${active_python_version}/site-packages
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# common configure flags
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+configure.args-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    -DDOXYGEN_DOT_EXECUTABLE= \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    -DDOXYGEN_EXECUTABLE= \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    -DCMAKE_MODULES_DIR=share/cmake
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# default
</span> configure.args-append \
     -DENABLE_IQBALANCE=OFF \
     -DENABLE_OSMOSDR=OFF \
     -DENABLE_FILE=ON \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    -DENABLE_MIRI=OFF \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    -DENABLE_RFSPACE=ON \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    -DENABLE_REDPITAYA=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    -DENABLE_MIRI=OFF
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# gr-fcd is not available on next
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-if {${not_gr_next}} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    configure.args-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        -DENABLE_FCD=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {[variant_isset debug]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cmake.build_type Debug
</span> } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    configure.args-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        -DENABLE_FCD=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cmake.build_type Release
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# one of the c++ codes uses struct assignment settings that require
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# C++11 or newer.  don't patch; just require C++11 instead.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-configure.args-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    -DCMAKE_CXX_STANDARD=11
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# specify the Python dependencies
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-depends_lib-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    port:python27
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# specify the Python version to use
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-configure.args-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    -DPYTHON_EXECUTABLE=${frameworks_dir}/Python.framework/Versions/2.7/bin/python2.7 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    -DPYTHON_INCLUDE_DIR=${frameworks_dir}/Python.framework/Versions/2.7/Headers \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    -DPYTHON_LIBRARY=${frameworks_dir}/Python.framework/Versions/2.7/Python \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    -DGR_PYTHON_DIR=${frameworks_dir}/Python.framework/Versions/2.7/lib/python2.7/site-packages
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> variant docs description "Install ${name} documentation" {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     depends_build-append \
         port:doxygen \
         path:bin/dot:graphviz
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-delete \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DDOXYGEN_DOT_EXECUTABLE= \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DDOXYGEN_EXECUTABLE=
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>     configure.args-append \
         -DDOXYGEN_DOT_EXECUTABLE=${prefix}/bin/dot \
         -DDOXYGEN_EXECUTABLE=${prefix}/bin/doxygen
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-if {![variant_isset docs]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    configure.args-append \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        -DDOXYGEN_DOT_EXECUTABLE= \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        -DDOXYGEN_EXECUTABLE=
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span> 
 variant uhd description "Install ${name} with support for UHD" {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     # allow uhd or uhd-devel
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     depends_lib-append \
         path:lib/libuhd.dylib:uhd
 
     # require gnuradio to also have this variant
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     require_active_variants \
         path:lib/libgnuradio-runtime.dylib:gnuradio uhd
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -173,149 +164,156 @@ variant uhd description "Install ${name} with support for UHD" {
</span>         -DGNURADIO_UHD_LIBRARIES=${prefix}/lib/libgnuradio-uhd.dylib \
         -DUHD_INCLUDE_DIRS=${prefix}/include/uhd \
         -DUHD_LIBRARIES=${prefix}/lib/libuhd.dylib
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 if {![variant_isset uhd]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     configure.args-append \
         -DENABLE_UHD=OFF \
         -DGNURADIO_UHD_INCLUDE_DIRS= \
         -DGNURADIO_UHD_LIBRARIES= \
         -DUHD_INCLUDE_DIRS= \
         -DUHD_LIBRARIES=
<span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+variant iio description "Install ${name} with support for IIO devices like PlutoSDR" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    depends_lib-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        path:lib/libiio.dylib:libiio \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        port:gr-iio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DENABLE_IIO=ON \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DGNURADIO_IIO_INCLUDE_DIRS=${prefix}/include \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DGNURADIO_IIO_LIBRARIES=${prefix}/lib/libgnuradio-iio.dylib \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DIIO_INCLUDE_DIRS=${prefix}/include \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DIIO_LIBRARIES=${prefix}/lib/libiio.dylib
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-variant swig description "Install ${name} with support for SWIG-base Python bindings" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {![variant_isset iio]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DENABLE_IIO=OFF \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DGNURADIO_IIO_INCLUDE_DIRS= \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DGNURADIO_IIO_LIBRARIES= \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DIIO_INCLUDE_DIRS= \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        -DIIO_LIBRARIES=
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+variant swig description "Install ${name} with support for SWIG-base Python bindings" {
</span>     depends_build-append \
         port:swig-python
 
     # require gnuradio to also have this variant
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     require_active_variants \
         path:lib/libgnuradio-runtime.dylib:gnuradio swig
 
     configure.args-append \
         -DSWIG_EXECUTABLE=${prefix}/bin/swig
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 if {![variant_isset swig]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     configure.args-append \
         -DSWIG_EXECUTABLE=
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 variant hackrf description "Install ${name} with support for hackrf" {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     # allow for release or devel
     depends_lib-append path:lib/libhackrf.dylib:hackrf
     configure.args-append -DENABLE_HACKRF=ON
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 if {![variant_isset hackrf]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     configure.args-append -DENABLE_HACKRF=OFF
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-variant fcdproplus description "Install ${name} with support for FunCube Dongle Pro+ (fcdproplus) \[NOTE not compatible with gnuradio-next\]" {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {${not_gr_next}} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        depends_lib-append port:gr-fcdproplus
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        configure.args-append -DENABLE_FCDPP=ON
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+variant fcdproplus description "Install ${name} with support for FunCube Dongle Pro+ (fcdproplus)" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${subport} eq "gr37-osmosdr"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        depends_lib-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            port:gr37-fcdproplus
</span>     } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_error "$subport variant +fcdproplus is not viable because port:gr-fcdproplus cannot use port:gnuradio-next."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        error "unsupported variant"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        depends_lib-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            port:gr-fcdproplus
</span>     }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   configure.args-append -DENABLE_FCDPP=ON
</span> }
 
 if {![variant_isset fcdproplus]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     configure.args-append -DENABLE_FCDPP=OFF
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 variant rtlsdr description "Install ${name} with support for rtl-sdr" {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     depends_lib-append port:rtl-sdr
     configure.args-append -DENABLE_RTL=ON -DENABLE_RTL_TCP=ON
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 if {![variant_isset rtlsdr]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     configure.args-append -DENABLE_RTL=OFF -DENABLE_RTL_TCP=OFF
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 variant bladeRF description "Install ${name} with support for bladeRF" {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     depends_lib-append port:bladeRF
     configure.args-append -DENABLE_BLADERF=ON
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 if {![variant_isset bladeRF]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     configure.args-append -DENABLE_BLADERF=OFF
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 variant airspy description "Install ${name} with support for airspy" {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     depends_lib-append port:airspy
     configure.args-append -DENABLE_AIRSPY=ON
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
 if {![variant_isset airspy]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     configure.args-append -DENABLE_AIRSPY=OFF
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-# SoapySDR and SDRPlay work on 10.9 and newer only until fixed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-platform darwin {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {${os.major} > 12} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-variant soapysdr description "Install ${name} with support for SoapySDR" {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    depends_lib-append port:SoapySDR
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    configure.args-append -DENABLE_SOAPY=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+variant spyserver description "Install ${name} with support for airspy spyserver" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append -DENABLE_SPYSERVER=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+if {![variant_isset spyserver]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append -DENABLE_SPYSERVER=OFF
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-if {![variant_isset soapysdr]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+variant redpitaya description "Install ${name} with support for Red Pitaya" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append -DENABLE_REDPITAYA=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    configure.args-append -DENABLE_SOAPY=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {![variant_isset redpitaya]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append -DENABLE_REDPITAYA=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+variant rfspace description "Install ${name} with support for RFSpace" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append -DENABLE_RFSPACE=ON
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-variant sdrplay description "Install ${name} with support for SDRplay" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {![variant_isset rfspace]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-append -DENABLE_RFSPACE=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    depends_lib-append port:SDRplay
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    configure.args-append -DENABLE_NONFREE=ON -DENABLE_SDRPLAY=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# SoapySDR and SDRPlay work on 10.9 and newer only until fixed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+platform darwin {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${os.major} > 12} {
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        variant soapysdr description "Install ${name} with support for SoapySDR" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            depends_lib-append port:SoapySDR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            configure.args-append -DENABLE_SOAPY=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-if {![variant_isset sdrplay]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {![variant_isset soapysdr]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            configure.args-append -DENABLE_SOAPY=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    configure.args-append -DENABLE_NONFREE=OFF -DENABLE_SDRPLAY=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        variant sdrplay description "Install ${name} with support for SDRplay" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            depends_lib-append port:SDRplay
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            configure.args-append -DENABLE_NONFREE=ON -DENABLE_SDRPLAY=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {![variant_isset sdrplay]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            configure.args-append -DENABLE_NONFREE=OFF -DENABLE_SDRPLAY=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span> 
     } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>         # for any Mac OS X <= 10.8 (major <= 12), explicitly disable
         # SOAPYSDR and SDRPLAY. Just in case they might be installed
         # somehow, we don't want to link with those installs.
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -323,6 +321,32 @@ if {![variant_isset sdrplay]} {
</span>             -DENABLE_SOAPY=OFF \
             -DENABLE_NONFREE=OFF \
             -DENABLE_SDRPLAY=OFF
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# available only on >GR3.7 versions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${subport} eq "gr-osmosdr"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    variant airspyhf description "Install ${name} with support for airspyhf" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        depends_lib-append port:airspyhf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        configure.args-append -DENABLE_AIRSPYHF=ON
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {![variant_isset airspyhf]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        configure.args-append -DENABLE_AIRSPYHF=OFF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# per user concensus: enable all variants except +debug and +universal
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default_variants +docs +uhd +swig +hackrf +rtlsdr +bladeRF +airspy +redpitaya +rfspace +fcdproplus +spyserver
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# SoapySDR and SDRPlay work on 10.9 and newer only until fixed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+platform darwin {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${os.major} > 12} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        default_variants +soapysdr +sdrplay
</span>     }
 }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# available only on >GR3.7 versions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${subport} eq "gr-osmosdr"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    default_variants +airspyhf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><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>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..8ffa1c2307f
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/science/gr-osmosdr/files/add_airspy-spyserver_support.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,1740 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From 2008a94fb9cb16f3d58d3ff0545d50527a162268 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Davide Gerhard <rainbow@irh.it>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Fri, 17 Apr 2020 16:20:46 +0200
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] add support for AIRSPY SPYServer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+the work is done by racerxdl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+see https://github.com/racerxdl/gr-osmosdr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ grc/gen_osmosdr_blocks.py           |   2 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/CMakeLists.txt                  |   8 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/config.h.in                     |   1 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/device.cc                       |   8 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/source_impl.cc                  |  18 +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/spyserver/CMakeLists.txt        |  36 ++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/spyserver/spyserver_protocol.h  | 179 ++++++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/spyserver/spyserver_source_c.cc | 879 ++++++++++++++++++++++++++++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/spyserver/spyserver_source_c.h  | 206 +++++++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/spyserver/tcp_client.cc         | 163 ++++++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lib/spyserver/tcp_client.h          |  82 +++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 11 files changed, 1582 insertions(+)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ create mode 100644 lib/spyserver/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ create mode 100644 lib/spyserver/spyserver_protocol.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ create mode 100644 lib/spyserver/spyserver_source_c.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ create mode 100644 lib/spyserver/spyserver_source_c.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ create mode 100644 lib/spyserver/tcp_client.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ create mode 100644 lib/spyserver/tcp_client.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git grc/gen_osmosdr_blocks.py grc/gen_osmosdr_blocks.py
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 840320a..13a03fb 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- grc/gen_osmosdr_blocks.py
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ grc/gen_osmosdr_blocks.py
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -165,6 +165,7 @@ documentation: |-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * gnuradio .cfile input through libgnuradio-blocks
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * AirSpy Wideband Receiver through libairspy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   * SpyServer Devices through spyserver
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   % endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   % if sourk == 'sink':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * gnuradio .cfile output through libgnuradio-blocks
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -205,6 +206,7 @@ documentation: |-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     cloudiq=127.0.0.1[:50000]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     sdr-iq=/dev/ttyUSB0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     airspy=0[,bias=0|1][,linearity][,sensitivity]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    spyserver=0,ip=192.168.0.10[,port=5555]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   % endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   % if sourk == 'sink':
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     file='/path/to/your file',rate=1e6[,freq=100e6][,append=true][,throttle=true] ...
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/CMakeLists.txt lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index d04cb1d..ec8fe26 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -201,6 +201,14 @@ if(ENABLE_BLADERF)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     add_subdirectory(bladerf)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ endif(ENABLE_BLADERF)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Setup SPYSERVER component
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++GR_REGISTER_COMPONENT("AIRSPY SPY Server Receiver" ENABLE_SPYSERVER)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++if(ENABLE_SPYSERVER)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    add_subdirectory(spyserver)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++endif(ENABLE_SPYSERVER)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Setup RFSPACE component
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/config.h.in lib/config.h.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 5303d7d..6ffc8ad 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- lib/config.h.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/config.h.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -15,6 +15,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_HACKRF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_BLADERF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_RFSPACE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#cmakedefine ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_AIRSPY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_AIRSPYHF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_SOAPY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/device.cc lib/device.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 586062f..885d85c 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- lib/device.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/device.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -70,6 +70,10 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <bladerf_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <spyserver_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_RFSPACE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <rfspace_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -186,6 +190,10 @@ devices_t device::find(const device_t &hint)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices( fake ) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  BOOST_FOREACH( std::string dev, spyserver_source_c::get_devices( fake ) )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_AIRSPY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   BOOST_FOREACH( std::string dev, airspy_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/source_impl.cc lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f1426e0..6301b74 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -76,6 +76,10 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <rfspace_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <spyserver_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_AIRSPY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <airspy_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -155,6 +159,9 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_BLADERF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   dev_types.push_back("bladerf");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  dev_types.push_back("spyserver");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_RFSPACE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   dev_types.push_back("rfspace");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -232,6 +239,10 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_SPYSERVER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    BOOST_FOREACH( std::string dev, spyserver_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_HACKRF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     BOOST_FOREACH( std::string dev, hackrf_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -348,6 +359,13 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_AIRSPY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ( dict.count("spyserver") ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      spyserver_source_c_sptr src = make_spyserver_source_c( arg );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      block = src; iface = src.get();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_RFSPACE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if ( dict.count("rfspace") ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          dict.count("sdr-iq") ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/spyserver/CMakeLists.txt lib/spyserver/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..09d46a7
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/spyserver/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,36 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Copyright 2012 Free Software Foundation, Inc.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# This file is part of GNU Radio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# This file included, use CMake directory variables
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++target_include_directories(gnuradio-osmosdr PRIVATE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${CMAKE_CURRENT_SOURCE_DIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++target_link_libraries(gnuradio-osmosdr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${Gnuradio-blocks_LIBRARIES}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++list(APPEND gr_osmosdr_srcs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${CMAKE_CURRENT_SOURCE_DIR}/tcp_client.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${CMAKE_CURRENT_SOURCE_DIR}/spyserver_source_c.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/spyserver/spyserver_protocol.h lib/spyserver/spyserver_protocol.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..6394535
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/spyserver/spyserver_protocol.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,179 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++SPY Server protocol structures and constants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++Copyright (C) 2017 Youssef Touil youssef@live.com
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++*/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#pragma once
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <stdint.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <limits.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SPYSERVER_PROTOCOL_VERSION (((2) << 24) | ((0) << 16) | (1700))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SPYSERVER_MAX_COMMAND_BODY_SIZE (256)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SPYSERVER_MAX_MESSAGE_BODY_SIZE (1 << 20)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SPYSERVER_MAX_DISPLAY_PIXELS (1 << 15)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SPYSERVER_MIN_DISPLAY_PIXELS (100)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SPYSERVER_MAX_FFT_DB_RANGE (150)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SPYSERVER_MIN_FFT_DB_RANGE (10)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define SPYSERVER_MAX_FFT_DB_OFFSET (100)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enum DeviceType
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  DEVICE_INVALID        = 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  DEVICE_AIRSPY_ONE     = 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  DEVICE_AIRSPY_HF      = 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  DEVICE_RTLSDR         = 3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enum CommandType
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CMD_HELLO             = 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CMD_GET_SETTING       = 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CMD_SET_SETTING       = 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CMD_PING              = 3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enum SettingType
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_STREAMING_MODE        = 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_STREAMING_ENABLED     = 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_GAIN                  = 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_IQ_FORMAT             = 100,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_IQ_FREQUENCY          = 101,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_IQ_DECIMATION         = 102,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_IQ_DIGITAL_GAIN       = 103,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_FFT_FORMAT            = 200,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_FFT_FREQUENCY         = 201,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_FFT_DECIMATION        = 202,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_FFT_DB_OFFSET         = 203,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_FFT_DB_RANGE          = 204,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  SETTING_FFT_DISPLAY_PIXELS    = 205,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enum StreamType
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_TYPE_STATUS    = 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_TYPE_IQ        = 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_TYPE_AF        = 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_TYPE_FFT       = 4,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enum StreamingMode
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_MODE_IQ_ONLY       = STREAM_TYPE_IQ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_MODE_AF_ONLY       = STREAM_TYPE_AF,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_MODE_FFT_ONLY      = STREAM_TYPE_FFT,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_MODE_FFT_IQ        = STREAM_TYPE_FFT | STREAM_TYPE_IQ,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_MODE_FFT_AF        = STREAM_TYPE_FFT | STREAM_TYPE_AF,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enum StreamFormat
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_FORMAT_INVALID     = 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_FORMAT_UINT8       = 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_FORMAT_INT16       = 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_FORMAT_INT24       = 3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_FORMAT_FLOAT       = 4,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  STREAM_FORMAT_DINT4       = 5,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enum MessageType
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_DEVICE_INFO      = 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_CLIENT_SYNC      = 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_PONG             = 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_READ_SETTING     = 3,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_UINT8_IQ         = 100,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_INT16_IQ         = 101,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_INT24_IQ         = 102,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_FLOAT_IQ         = 103,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_UINT8_AF         = 200,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_INT16_AF         = 201,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_INT24_AF         = 202,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_FLOAT_AF         = 203,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_DINT4_FFT        = 300,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MSG_TYPE_UINT8_FFT        = 301,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct ClientHandshake
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t ProtocolVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t ClientNameLength;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct CommandHeader
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t CommandType;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t BodySize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct SettingTarget
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t StreamType;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t SettingType;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct MessageHeader
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t ProtocolID;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MessageType;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t StreamType;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t SequenceNumber;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t BodySize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct DeviceInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t DeviceType;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t DeviceSerial;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MaximumSampleRate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MaximumBandwidth;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t DecimationStageCount;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t GainStageCount;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MaximumGainIndex;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MinimumFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MaximumFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t Resolution;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MinimumIQDecimation;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t ForcedIQFormat;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct ClientSync
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t CanControl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t Gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t DeviceCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t IQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t FFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MinimumIQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MaximumIQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MinimumFFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t MaximumFFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct ComplexInt16
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int16_t real;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int16_t imag;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct ComplexUInt8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint8_t real;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint8_t imag;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++enum ParserPhase {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  AcquiringHeader,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ReadingData
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/spyserver/spyserver_source_c.cc lib/spyserver/spyserver_source_c.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..df3744f
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/spyserver/spyserver_source_c.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,879 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2018 Lucas Teske <lucas@teske.com.br>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *   Based on Youssef Touil (youssef@live.com) C# implementation.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * config.h is generated by configure.  It contains the results
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * of probing for features, options etc.  It should be the first
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * file included in your .cc file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef HAVE_CONFIG_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "config.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <stdexcept>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <iostream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <algorithm>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/assign.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/format.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/detail/endian.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/algorithm/string.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/thread/thread.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/io_signature.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "spyserver_source_c.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "spyserver_protocol.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "arg_helpers.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++using namespace boost::assign;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++spyserver_source_c_sptr make_spyserver_source_c (const std::string & args)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return gnuradio::get_initial_sptr(new spyserver_source_c (args));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Specify constraints on number of input and output streams.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * This info is used to construct the input and output signatures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * (2nd & 3rd args to gr::block's constructor).  The input and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * output signatures are used by the runtime system to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * check that a valid number and type of inputs and outputs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * are connected to this block.  In this case, we accept
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * only 0 input and 1 output.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static const int MIN_IN = 0;  // mininum number of input streams
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static const int MAX_IN = 0;  // maximum number of input streams
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static const int MIN_OUT = 1; // minimum number of output streams
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static const int MAX_OUT = 1; // maximum number of output streams
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * The private constructor
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++spyserver_source_c::spyserver_source_c (const std::string &args)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  : gr::sync_block ("spyserver_source_c",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        gr::io_signature::make(MIN_IN, MAX_IN, sizeof (gr_complex)),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof (gr_complex))),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    terminated(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    streaming(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    got_device_info(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    receiver_thread(NULL),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    header_data(new uint8_t[sizeof(MessageHeader)]),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    body_buffer(NULL),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    body_buffer_length(0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    parser_position(0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    last_sequence_number(0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    streaming_mode(STREAM_MODE_IQ_ONLY),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _sample_rate(0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _center_freq(0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _gain(0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _digitalGain(0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  dict_t dict = params_to_dict(args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (dict.count("ip"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ip = boost::lexical_cast<std::string>( dict["ip"] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  else if (dict.count("host"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ip = boost::lexical_cast<std::string>( dict["host"] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    throw std::runtime_error( std::string(__FUNCTION__) + " " +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                              "You should defined an IP to connect." );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (dict.count("port"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    port = boost::lexical_cast<int>( dict["port"] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    port = 5555;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << "SpyServer(" << ip << ", " << port << ")" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  client = tcp_client(ip, port);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  connect();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _fifo = new boost::circular_buffer<gr_complex>(5000000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (!_fifo) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    throw std::runtime_error( std::string(__FUNCTION__) + " " +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                              "Failed to allocate a sample FIFO!" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << "SpyServer: Ready" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// const std::string &spyserver_source_c::getName() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//   switch (device_info.DeviceType) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//   case DEVICE_INVALID:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//     return spyserver_source_c::NameNoDevice;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//   case DEVICE_AIRSPY_ONE:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//     return spyserver_source_c::NameAirspyOne;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//   case DEVICE_AIRSPY_HF:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//     return spyserver_source_c::NameAirspyHF;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//   case DEVICE_RTLSDR:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//     return spyserver_source_c::NameRTLSDR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//   default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//     return spyserver_source_c::NameUnknown;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::connect()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool hasError = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (receiver_thread != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << "SpyServer: Trying to connect" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  client.connect_conn();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  is_connected = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << "SpyServer: Connected" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  say_hello();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  cleanup();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  terminated = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  got_sync_info = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  got_device_info = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::exception error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  receiver_thread  = new std::thread(&spyserver_source_c::thread_loop, this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (int i=0; i<1000 && !hasError; i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (got_device_info) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (device_info.DeviceType == DEVICE_INVALID) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        error = std::runtime_error( std::string(__FUNCTION__) + " " + "Server is up but no device is available");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        hasError = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (got_sync_info) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        std::cerr << "SpyServer: Got sync Info" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        on_connect();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::this_thread::sleep_for(std::chrono::milliseconds(1));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  disconnect();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (hasError) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    throw error;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  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:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::disconnect()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  terminated = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (is_connected) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    client.close_conn();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (receiver_thread != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    receiver_thread->join();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    receiver_thread = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  cleanup();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::on_connect()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_setting(SETTING_STREAMING_MODE, { streaming_mode });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_setting(SETTING_IQ_FORMAT, { STREAM_FORMAT_INT16 });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // set_setting(SETTING_FFT_FORMAT, { STREAM_FORMAT_UINT8 });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  //set_setting(SETTING_FFT_DISPLAY_PIXELS, { displayPixels });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  //set_setting(SETTING_FFT_DB_OFFSET, { fftOffset });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  //set_setting(SETTING_FFT_DB_RANGE, { fftRange });
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  //device_info.MaximumSampleRate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  //availableSampleRates
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << "SpyServer: Maximum Sample Rate: " << device_info.MaximumSampleRate << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (unsigned int i = device_info.MinimumIQDecimation; i<=device_info.DecimationStageCount; i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    uint32_t sr = device_info.MaximumSampleRate / (1 << i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _sample_rates.push_back( std::pair<double, uint32_t>((double)sr, i ) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::sort(_sample_rates.begin(), _sample_rates.end());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool spyserver_source_c::set_setting(uint32_t settingType, std::vector<uint32_t> params) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<uint8_t> argBytes;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (params.size() > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    argBytes = std::vector<uint8_t>(sizeof(SettingType) + params.size() * sizeof(uint32_t));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    uint8_t *settingBytes = (uint8_t *) &settingType;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    for (unsigned int i=0; i<sizeof(uint32_t); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      argBytes[i] = settingBytes[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::memcpy(&argBytes[0]+sizeof(uint32_t), &params[0], sizeof(uint32_t) * params.size());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    argBytes = std::vector<uint8_t>();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return send_command(CMD_SET_SETTING, argBytes);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool spyserver_source_c::say_hello() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const uint8_t *protocolVersionBytes = (const uint8_t *) &ProtocolVersion;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const uint8_t *softwareVersionBytes = (const uint8_t *) SoftwareID.c_str();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<uint8_t> args = std::vector<uint8_t>(sizeof(ProtocolVersion) + SoftwareID.size());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::memcpy(&args[0], protocolVersionBytes, sizeof(ProtocolVersion));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::memcpy(&args[0] + sizeof(ProtocolVersion), softwareVersionBytes, SoftwareID.size());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return send_command(CMD_HELLO, args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::cleanup() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.DeviceType = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.DeviceSerial = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.DecimationStageCount = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.GainStageCount = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.MaximumSampleRate = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.MaximumBandwidth = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.MaximumGainIndex = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.MinimumFrequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    device_info.MaximumFrequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _gain = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _digitalGain = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    //displayCenterFrequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    //device_center_frequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    //displayDecimationStageCount = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    //channel_decimation_stage_count = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    //minimum_tunable_frequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    //maximum_tunable_frequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    can_control = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    got_device_info = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    got_sync_info = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    last_sequence_number = ((uint32_t)-1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    dropped_buffers = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    down_stream_bytes = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    parser_phase = AcquiringHeader;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    parser_position = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    streaming = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    terminated = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::thread_loop() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  parser_phase = AcquiringHeader;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  parser_position = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  char buffer[BufferSize];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  try {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    while(!terminated) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (terminated) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      uint32_t availableData = client.available_data();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (availableData > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        availableData = availableData > BufferSize ? BufferSize : availableData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        client.receive_data(buffer, availableData);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        parse_message(buffer, availableData);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } catch (std::exception &e) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::cerr << "SpyServer: Error on ThreadLoop: " << e.what() << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (body_buffer != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    delete[] body_buffer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    body_buffer = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  cleanup();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::parse_message(char *buffer, uint32_t len) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  down_stream_bytes++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  while (len > 0 && !terminated) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (parser_phase == AcquiringHeader) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      while (parser_phase == AcquiringHeader && len > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        consumed = parse_header(buffer, len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        buffer += consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        len -= consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (parser_phase == ReadingData) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        uint8_t client_major = (SPYSERVER_PROTOCOL_VERSION >> 24) & 0xFF;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        uint8_t client_minor = (SPYSERVER_PROTOCOL_VERSION >> 16) & 0xFF;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        uint8_t server_major = (header.ProtocolID >> 24) & 0xFF;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        uint8_t server_minor = (header.ProtocolID >> 16) & 0xFF;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        //uint16_t server_build = (header.ProtocolID & 0xFFFF);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (client_major != server_major || client_minor != server_minor) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          throw std::runtime_error( std::string(__FUNCTION__) + " " + "Server is running an unsupported protocol version.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (header.BodySize > SPYSERVER_MAX_MESSAGE_BODY_SIZE) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          throw std::runtime_error( std::string(__FUNCTION__) + " " + "The server is probably buggy.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (body_buffer == NULL || body_buffer_length < header.BodySize) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (body_buffer != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            delete[] body_buffer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          body_buffer = new uint8_t[header.BodySize];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (parser_phase == ReadingData) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      consumed = parse_body(buffer, len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      buffer += consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      len -= consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (parser_phase == AcquiringHeader) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        if (header.MessageType != MSG_TYPE_DEVICE_INFO && header.MessageType != MSG_TYPE_CLIENT_SYNC) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          int32_t gap = header.SequenceNumber - last_sequence_number - 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          last_sequence_number = header.SequenceNumber;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          dropped_buffers += gap;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          if (gap > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            std::cerr << "SpyServer: Lost " << gap << " frames from SpyServer!";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        handle_new_message();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int spyserver_source_c::parse_header(char *buffer, uint32_t length) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  auto consumed = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  while (length > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int to_write = std::min((uint32_t)(sizeof(MessageHeader) - parser_position), length);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::memcpy(&header + parser_position, buffer, to_write);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    length -= to_write;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    buffer += to_write;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    parser_position += to_write;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    consumed += to_write;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (parser_position == sizeof(MessageHeader)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      parser_position = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (header.BodySize > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        parser_phase = ReadingData;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      return consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int spyserver_source_c::parse_body(char* buffer, uint32_t length) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  auto consumed = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  while (length > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int to_write = std::min((int) header.BodySize - parser_position, length);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::memcpy(body_buffer + parser_position, buffer, to_write);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    length -= to_write;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    buffer += to_write;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    parser_position += to_write;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    consumed += to_write;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (parser_position == header.BodySize) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      parser_position = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      parser_phase = AcquiringHeader;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      return consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return consumed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool spyserver_source_c::send_command(uint32_t cmd, std::vector<uint8_t> args) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (!is_connected) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t headerLen = sizeof(CommandHeader);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint16_t argLen = args.size();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint8_t *buffer = new uint8_t[headerLen + argLen];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  CommandHeader header;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  header.CommandType = cmd;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  header.BodySize = argLen;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (uint32_t i=0; i<sizeof(CommandHeader); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    buffer[i] = ((uint8_t *)(&header))[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (argLen > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    for (uint16_t i=0; i<argLen; i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      buffer[i+headerLen] = args[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  try {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    client.send_data((char *)buffer, headerLen+argLen);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    result = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } catch (std::exception &e) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    result = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  delete[] buffer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::handle_new_message() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (terminated) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  switch (header.MessageType) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case MSG_TYPE_DEVICE_INFO:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      process_device_info();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case MSG_TYPE_CLIENT_SYNC:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      process_client_sync();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case MSG_TYPE_UINT8_IQ:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      process_uint8_samples();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case MSG_TYPE_INT16_IQ:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      process_int16_samples();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case MSG_TYPE_FLOAT_IQ:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      process_float_samples();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    case MSG_TYPE_UINT8_FFT:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      process_uint8_fft();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::process_device_info() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::memcpy(&device_info, body_buffer, sizeof(DeviceInfo));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  minimum_tunable_frequency = device_info.MinimumFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  maximum_tunable_frequency = device_info.MaximumFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  got_device_info = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::process_client_sync() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ClientSync sync;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::memcpy(&sync, body_buffer, sizeof(ClientSync));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  can_control = sync.CanControl != 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _gain = (double) sync.Gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  device_center_frequency = sync.DeviceCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  channel_center_frequency = sync.IQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _center_freq = (double) sync.IQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  switch (streaming_mode) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  case STREAM_MODE_FFT_ONLY:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  case STREAM_MODE_FFT_IQ:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    minimum_tunable_frequency = sync.MinimumFFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    maximum_tunable_frequency = sync.MaximumFFTCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  case STREAM_MODE_IQ_ONLY:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    minimum_tunable_frequency = sync.MinimumIQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    maximum_tunable_frequency = sync.MaximumIQCenterFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  got_sync_info = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::process_uint8_samples() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  size_t n_avail, to_copy, num_samples = (header.BodySize) / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _fifo_lock.lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint8_t *sample = (uint8_t *)body_buffer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  n_avail = _fifo->capacity() - _fifo->size();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  to_copy = (n_avail < num_samples ? n_avail : num_samples / 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (size_t i=0; i < to_copy; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _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:#e0ffe0;'>++    sample += 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _fifo_lock.unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (to_copy) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _samp_avail.notify_one();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (to_copy < num_samples)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::cerr << "O" << std::flush;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::process_int16_samples() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  size_t n_avail, to_copy, num_samples = (header.BodySize / 2) / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _fifo_lock.lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int16_t *sample = (int16_t *)body_buffer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  n_avail = _fifo->capacity() - _fifo->size();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  to_copy = (n_avail < num_samples ? n_avail : num_samples);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (size_t i=0; i < to_copy; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _fifo->push_back(gr_complex(*sample / 32768.f, *(sample+1) / 32768.f));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    sample += 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _fifo_lock.unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (to_copy) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _samp_avail.notify_one();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (to_copy < num_samples)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::cerr << "O" << std::flush;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::process_float_samples() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  size_t n_avail, to_copy, num_samples = (header.BodySize / 4) / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _fifo_lock.lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  float *sample = (float *)body_buffer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  n_avail = _fifo->capacity() - _fifo->size();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  to_copy = (n_avail < num_samples ? n_avail : num_samples);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (size_t i=0; i < to_copy; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _fifo->push_back(gr_complex(*sample, *(sample+1)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    sample += 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _fifo_lock.unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (to_copy) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _samp_avail.notify_one();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::set_stream_state() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_setting(SETTING_STREAMING_ENABLED, {(unsigned int)(streaming ? 1 : 0)});
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_sample_rate(double sampleRate) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (sampleRate <= 0xFFFFFFFF) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::cerr << "SpyServer: Setting sample rate to " << sampleRate << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    for (unsigned int i=0; i<_sample_rates.size(); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (_sample_rates[i].first == sampleRate) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              channel_decimation_stage_count = _sample_rates[i].second;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              set_setting(SETTING_IQ_DECIMATION, {channel_decimation_stage_count});
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              _sample_rate = sampleRate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++              return get_sample_rate();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << "SpyServer: Sample rate not supported: " << sampleRate << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << "SpyServer: Supported Sample Rates: " << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (std::pair<double, uint32_t> sr: _sample_rates) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::cerr << "SpyServer:   " << sr.first << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  throw std::runtime_error(boost::str( boost::format("Unsupported samplerate: %gM") % (sampleRate/1e6) ) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_center_freq(double centerFrequency, size_t chan) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (centerFrequency <= 0xFFFFFFFF) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    channel_center_frequency = (uint32_t) centerFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    set_setting(SETTING_IQ_FREQUENCY, {channel_center_frequency});
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return centerFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << boost::format("Unsupported center frequency: %gM") % (centerFrequency/1e6) << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return this->get_center_freq(chan);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::process_uint8_fft() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // TODO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // // std::cerr << "UInt8 FFT Samples processing not implemented!!!" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Our virtual destructor.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++spyserver_source_c::~spyserver_source_c ()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  disconnect();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (_fifo)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    delete _fifo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _fifo = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  delete[] header_data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  header_data = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool spyserver_source_c::start()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (!streaming) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::cerr << "SpyServer: Starting Streaming" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    streaming = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    down_stream_bytes = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    set_stream_state();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool spyserver_source_c::stop()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (streaming) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::cerr << "SpyServer: Stopping Streaming" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    streaming = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    down_stream_bytes = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    set_stream_state();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++int spyserver_source_c::work( int noutput_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                        gr_vector_const_void_star &input_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                        gr_vector_void_star &output_items )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gr_complex *out = (gr_complex *)output_items[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( ! streaming )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return WORK_DONE;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  boost::unique_lock<boost::mutex> lock(_fifo_lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  /* Wait until we have the requested number of samples */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int n_samples_avail = _fifo->size();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  while (n_samples_avail < noutput_items) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _samp_avail.wait(lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    n_samples_avail = _fifo->size();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for(int i = 0; i < noutput_items; ++i) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    out[i] = _fifo->at(0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _fifo->pop_front();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  //std::cerr << "-" << std::flush;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return noutput_items;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::vector<std::string> spyserver_source_c::get_devices(bool fake)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<std::string> devices;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string label;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if ( fake )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::string args = "spyserver=0,host=localhost,port=5555";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    args += ",label='Spyserver Client'";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    devices.push_back( args );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return devices;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++size_t spyserver_source_c::get_num_channels()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++osmosdr::meta_range_t spyserver_source_c::get_sample_rates()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::meta_range_t range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  for (size_t i = 0; i < _sample_rates.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    range += osmosdr::range_t( _sample_rates[i].first );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::get_sample_rate()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return _sample_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++osmosdr::freq_range_t spyserver_source_c::get_freq_range( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::freq_range_t range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  range += osmosdr::range_t( minimum_tunable_frequency, maximum_tunable_frequency );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::get_center_freq( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return _center_freq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_freq_corr( double ppm, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return get_freq_corr( chan );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::get_freq_corr( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::vector<std::string> spyserver_source_c::get_gain_names( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector< std::string > names;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (can_control) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    names += "LNA";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  names += "Digital";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return names;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++osmosdr::gain_range_t spyserver_source_c::get_gain_range( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return osmosdr::gain_range_t( 0, 16, 1 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++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:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (name == "Digital") {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return osmosdr::gain_range_t( 0, 1, 1 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return get_gain_range(chan);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool spyserver_source_c::set_gain_mode( bool automatic, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return get_gain_mode(chan);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool spyserver_source_c::get_gain_mode( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_gain( double gain, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (can_control) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _gain = gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    set_setting(SETTING_GAIN, {(uint32_t)gain});
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    std::cerr << "Spyserver: The server does not allow you to change the gains." << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return _gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_lna_gain( double gain, size_t chan)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return set_gain(gain, chan);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_gain( double gain, const std::string & name, size_t chan)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (name == "Digital") {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    _digitalGain = gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    set_setting(SETTING_IQ_DIGITAL_GAIN, {((uint32_t)gain) * 0xFFFFFFFF});
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return _gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return set_gain(gain, chan);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::get_gain( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return chan == 0 ? _gain : _digitalGain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return _gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::get_gain( const std::string & name, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (name == "Digital") {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return _digitalGain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return get_gain(chan);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_mix_gain(double gain, size_t chan)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return _gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_if_gain(double gain, size_t chan)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return _gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::vector< std::string > spyserver_source_c::get_antennas( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector< std::string > antennas;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  antennas += get_antenna( chan );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return antennas;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::string spyserver_source_c::set_antenna( const std::string & antenna, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return get_antenna( chan );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::string spyserver_source_c::get_antenna( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return "RX";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::set_bandwidth( double bandwidth, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return get_bandwidth( chan );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double spyserver_source_c::get_bandwidth( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return _sample_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++osmosdr::freq_range_t spyserver_source_c::get_bandwidth_range( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::freq_range_t bandwidths;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bandwidths += osmosdr::range_t( get_bandwidth( chan ) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return bandwidths;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void spyserver_source_c::set_biast( bool enabled ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool spyserver_source_c::get_biast() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+\ No newline at end of file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/spyserver/spyserver_source_c.h lib/spyserver/spyserver_source_c.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..d72c562
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/spyserver/spyserver_source_c.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,206 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * This file is part of GNU Radio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef INCLUDED_SPYSERVER_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define INCLUDED_SPYSERVER_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <thread>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <atomic>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/circular_buffer.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/thread/mutex.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/thread/condition_variable.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/sync_block.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "source_iface.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "spyserver_protocol.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "tcp_client.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class spyserver_source_c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * We use boost::shared_ptr's instead of raw pointers for all access
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * to gr::blocks (and many other data structures).  The shared_ptr gets
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * us transparent reference counting, which greatly simplifies storage
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * management issues.  This is especially helpful in our hybrid
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * C++ / Python system.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * As a convention, the _sptr suffix indicates a boost::shared_ptr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef boost::shared_ptr<spyserver_source_c> spyserver_source_c_sptr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * \brief Return a shared_ptr to a new instance of spyserver_source_c.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * To avoid accidental use of raw pointers, spyserver_source_c's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * constructor is private.  make_spyserver_source_c is the public
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * interface for creating new instances.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++spyserver_source_c_sptr make_spyserver_source_c (const std::string & args = "");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * \brief Provides a stream of complex samples.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * \ingroup block
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class spyserver_source_c :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    public gr::sync_block,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    public source_iface
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // The friend declaration allows make_spyserver_source_c to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // access the private constructor.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  friend spyserver_source_c_sptr make_spyserver_source_c (const std::string & args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  /*!
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   * \brief Provides a stream of complex samples.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++   */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  spyserver_source_c (const std::string & args);   // private constructor
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ~spyserver_source_c ();  // public destructor
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int work( int noutput_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            gr_vector_const_void_star &input_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            gr_vector_void_star &output_items );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  static std::vector< std::string > get_devices(bool fake = false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  size_t get_num_channels( void );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::meta_range_t get_sample_rates( void );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_sample_rate( double rate );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_sample_rate( void );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_center_freq( double freq, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_center_freq( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_freq_corr( double ppm, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_freq_corr( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<std::string> get_gain_names( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool set_gain_mode( bool automatic, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool get_gain_mode( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_gain( double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_gain( double gain, const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_gain( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_gain( const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_lna_gain( double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_mix_gain(double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_if_gain( double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  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:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector< std::string > get_antennas( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string set_antenna( const std::string & antenna, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string get_antenna( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_bandwidth( double bandwidth, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_bandwidth( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void set_biast( bool enabled );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool get_biast();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  static constexpr unsigned int BufferSize = 64 * 1024;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const uint32_t ProtocolVersion = SPYSERVER_PROTOCOL_VERSION;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const std::string SoftwareID = std::string("gr-osmosdr");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const std::string NameNoDevice = std::string("SpyServer - No Device");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const std::string NameAirspyOne = std::string("SpyServer - Airspy One");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const std::string NameAirspyHF = std::string("SpyServer - Airspy HF+");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const std::string NameRTLSDR = std::string("SpyServer - RTLSDR");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  const std::string NameUnknown = std::string("SpyServer - Unknown Device");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t minimum_tunable_frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t maximum_tunable_frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t device_center_frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t channel_center_frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t channel_decimation_stage_count;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  tcp_client client;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void connect();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void disconnect();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void thread_loop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool say_hello();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void cleanup();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void on_connect();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool set_setting(uint32_t settingType, std::vector<uint32_t> params);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool send_command(uint32_t cmd, std::vector<uint8_t> args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void parse_message(char *buffer, uint32_t len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int parse_header(char *buffer, uint32_t len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int parse_body(char *buffer, uint32_t len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void process_device_info();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void process_client_sync();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void process_uint8_samples();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void process_int16_samples();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void process_float_samples();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void process_uint8_fft();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void handle_new_message();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void set_stream_state();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::atomic_bool terminated;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::atomic_bool streaming;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::atomic_bool got_device_info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::atomic_bool got_sync_info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::atomic_bool can_control;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::atomic_bool is_connected;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::thread *receiver_thread;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t dropped_buffers;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::atomic<int64_t> down_stream_bytes;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint8_t *header_data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint8_t *body_buffer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint64_t body_buffer_length;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t parser_position;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t last_sequence_number;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string ip;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int port;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  DeviceInfo device_info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  MessageHeader header;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t streaming_mode;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uint32_t parser_phase;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  boost::circular_buffer<gr_complex> *_fifo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  boost::mutex _fifo_lock;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  boost::condition_variable _samp_avail;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector< std::pair<double, uint32_t> > _sample_rates;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double _sample_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double _center_freq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double _gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double _digitalGain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif /* INCLUDED_SPYSERVER_SOURCE_C_H */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/spyserver/tcp_client.cc lib/spyserver/tcp_client.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..78bb54b
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/spyserver/tcp_client.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,163 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2018 Lucas Teske <lucas@teske.com.br>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "tcp_client.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <cstdio>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <sstream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <iostream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <winsock2.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <Ws2tcpip.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <atomic>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#   ifdef _MSC_VER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#   pragma comment(lib, "ws2_32.lib")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#   endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# ifndef MSG_WAITALL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#   define MSG_WAITALL (1 << 3)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <sys/socket.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <arpa/inet.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <sys/resource.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <sys/select.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <sys/ioctl.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <netdb.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# define ioctlsocket ioctl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(_WIN32) || defined(__APPLE__)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    #ifndef MSG_NOSIGNAL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        #define MSG_NOSIGNAL 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::atomic_bool tcp_client::initialized(false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::atomic_uint tcp_client::sockCount(0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void tcp_client::socket_initialize() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (!initialized) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        initialized = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        sockCount = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        WSADATA wsa_data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        WSAStartup(MAKEWORD(1, 1), &wsa_data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        sockCount++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++tcp_client::tcp_client(std::string addr, int port)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    this->port = port;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    #ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    socket_initialize();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    hostent * record = gethostbyname(addr.c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (record == NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      throw std::runtime_error( std::string(__FUNCTION__) + " " +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                              "Cannot resolve: " + addr );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    in_addr * address = (in_addr *)record->h_addr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    memset(&socketAddr, 0x00, sizeof(sockaddr_in));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    socketAddr.sin_addr = *address;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void tcp_client::connect_conn() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  s = socket(AF_INET, SOCK_STREAM, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (s < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    throw std::runtime_error("Socket Error Code " + std::to_string(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  socketAddr.sin_family = AF_INET;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  socketAddr.sin_port = htons(port);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int x = connect(s, (struct sockaddr *) &socketAddr, sizeof(socketAddr));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (x < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    throw std::runtime_error("Socket Error Code " + std::to_string(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void tcp_client::close_conn() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (s > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      int status = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      status = shutdown(s, SD_BOTH);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (status == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          status = closesocket(s);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      status = shutdown(s, 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      if (status == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          status = close(s);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++tcp_client::~tcp_client() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    #ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    sockCount--;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (!sockCount) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        WSACleanup();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void tcp_client::receive_data(char *data, int length) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    long n = recv(s, data, length, MSG_WAITALL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (n == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        throw std::runtime_error("Client Disconnected");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } else if (n != length) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        throw std::runtime_error("Socket Error Code " + std::to_string(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void tcp_client::send_data(char * data, int length) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int n = send(s, data, length, MSG_NOSIGNAL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (n == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        throw std::runtime_error("Client Disconnected");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    } else if (n != length) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        throw std::runtime_error("Socket Error Code " + std::to_string(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++uint64_t tcp_client::available_data() {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if (s < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    unsigned long bytesAvailable = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int ret = ioctlsocket(s, FIONREAD, &bytesAvailable);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    switch (ret) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        case EINVAL:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        case EFAULT:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        case ENOTTY:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        throw std::runtime_error("Socket Error Code " + std::to_string(ret));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        case EBADF:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        throw std::runtime_error("Client Disconnected");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    return bytesAvailable;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+\ No newline at end of file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/spyserver/tcp_client.h lib/spyserver/tcp_client.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..249a718
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/spyserver/tcp_client.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,82 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2018 Lucas Teske <lucas@teske.com.br>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef TCPCLIENT_H_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define TCPCLIENT_H_
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <atomic>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <chrono>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <thread>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <cstdint>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <stdint.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <memory.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <sstream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <iostream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#   include <winsock2.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#   include <Ws2tcpip.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#   include <sys/socket.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#   include <netinet/in.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(__GNUC__) || defined(__MINGW32__)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class tcp_client {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int port;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    #ifdef _WIN32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    static std::atomic_bool initialized;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    static std::atomic_uint sockCount;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    void socket_initialize();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++protected:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    struct sockaddr_in socketAddr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    int s;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    tcp_client() {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    tcp_client(std::string addr, int port);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ~tcp_client();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    void connect_conn();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    void close_conn();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    void receive_data(char *data, int length);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    void send_data(char *data, int length);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    uint64_t available_data();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    inline void wait_for_data(uint64_t bytes, uint32_t timeout) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        uint32_t checkTime = (int) time(NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        while (available_data() < bytes) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            if (((int) time(NULL)) - checkTime > timeout) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            std::this_thread::sleep_for(std::chrono::microseconds(10));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif /* TCPCLIENT_H_ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-- 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+2.26.1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</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>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..add5a452e58
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/science/gr-osmosdr/files/add_gr-iio_support.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,616 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git CMakeLists.txt CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 7a2cf9d..dab2089 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -176,6 +176,7 @@ find_package(LibHackRF)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ find_package(LibAIRSPY)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ find_package(LibAIRSPYHF)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ find_package(LibbladeRF)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++find_package(GNURadioIIO)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ find_package(SoapySDR NO_MODULE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ find_package(LibFreeSRP)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ find_package(Doxygen)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git cmake/Modules/FindGnuradioIIO.cmake cmake/Modules/FindGnuradioIIO.cmake
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..d2e8326
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ cmake/Modules/FindGNURadioIIO.cmake
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,34 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++INCLUDE(FindPkgConfig)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++PKG_CHECK_MODULES(PC_GNURADIO_IIO gnuradio-iio)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FIND_PATH(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    GNURADIO_IIO_INCLUDE_DIRS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    NAMES iio/api.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    HINTS $ENV{GNURADIO_IIO_DIR}/include
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        ${PC_GNURADIO_IIO_INCLUDEDIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    PATHS /usr/local/include
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          /usr/include
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FIND_LIBRARY(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++     GNURADIO_IIO_LIBRARIES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++     NAMES gnuradio-iio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++     HINTS $ENV{GNURADIO_IIO_DIR}/lib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++         ${PC_GNURADIO_IIO_LIBDIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++     PATHS /usr/local/lib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          /usr/local/lib64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          /usr/lib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          /usr/lib64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++if(GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set(GNURADIO_IIO_FOUND TRUE CACHE INTERNAL "gnuradio-iio found")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  message(STATUS "Found gnuradio-iio: ${GNURADIO_IIO_INCLUDE_DIRS}, ${GNURADIO_IIO_LIBRARIES}")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++else(GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set(GNURADIO_IIO_FOUND FALSE CACHE INTERNAL "gnuradio-iio found")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  message(STATUS "gnuradio-iio not found.")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++endif(GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++INCLUDE(FindPackageHandleStandardArgs)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++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:#e0ffe0;'>++MARK_AS_ADVANCED(GNURADIO_IIO_LIBRARIES GNURADIO_IIO_INCLUDE_DIRS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git cmake/Modules/FindIIO.cmake cmake/Modules/FindIIO.cmake
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..bb87a4b
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ cmake/Modules/FindIIO.cmake
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,28 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Find the IIO userspace library
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++INCLUDE(FindPkgConfig)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++PKG_CHECK_MODULES(PC_IIO iio)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FIND_PATH(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    IIO_INCLUDE_DIRS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    NAMES iio.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    HINTS $ENV{IIO_DIR}/include
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        ${PC_IIO_INCLUDEDIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    PATHS /usr/local/include
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          /usr/include
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FIND_LIBRARY(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    IIO_LIBRARIES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    NAMES iio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    HINTS $ENV{IIO_DIR}/lib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        ${PC_IIO_LIBDIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    PATHS /usr/local/lib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          /usr/lib
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++INCLUDE(FindPackageHandleStandardArgs)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++FIND_PACKAGE_HANDLE_STANDARD_ARGS(IIO DEFAULT_MSG IIO_LIBRARIES IIO_INCLUDE_DIRS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++MARK_AS_ADVANCED(IIO_LIBRARIES IIO_INCLUDE_DIRS)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/CMakeLists.txt lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index d04cb1d..865b58a 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -167,6 +167,14 @@ if(ENABLE_UHD)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     add_subdirectory(uhd)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ endif(ENABLE_UHD)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Setup IIO component
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++GR_REGISTER_COMPONENT("IIO Devices (like PlutoSDR)" ENABLE_IIO GNURADIO_IIO_FOUND)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++if(ENABLE_IIO)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    add_subdirectory(plutosdr)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++endif(ENABLE_IIO)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Setup MiriSDR component
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/config.h.in lib/config.h.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 5303d7d..d33203a 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- lib/config.h.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/config.h.in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -10,6 +10,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_RTL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_RTL_TCP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_UHD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#cmakedefine ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_MIRI
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_SDRPLAY
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #cmakedefine ENABLE_HACKRF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/device.cc lib/device.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 586062f..b0e8a77 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- lib/device.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/device.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -54,6 +54,10 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <uhd_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <plutosdr_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_MIRI
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <miri_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -166,6 +170,10 @@ devices_t device::find(const device_t &hint)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  BOOST_FOREACH( std::string dev, plutosdr_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_MIRI
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     devices.push_back( device_t(dev) );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/plutosdr/CMakeLists.txt lib/plutosdr/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..835f4f2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/plutosdr/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,38 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Copyright 2012 Free Software Foundation, Inc.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# This file is part of GNU Radio
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++# This file included, use CMake directory variables
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++########################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++target_include_directories(gnuradio-osmosdr PRIVATE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${CMAKE_CURRENT_SOURCE_DIR}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${GNURADIO_IIO_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${IIO_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++target_link_libraries(gnuradio-osmosdr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${GNURADIO_IIO_LIBRARIES}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${IIO_LIBRARIES}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++list(APPEND gr_osmosdr_srcs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    ${CMAKE_CURRENT_SOURCE_DIR}/plutosdr_source_c.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/plutosdr/plutosdr_source_c.cc lib/plutosdr/plutosdr_source_c.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..009d4b2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/plutosdr/plutosdr_source_c.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,262 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2017 Dimitri Stolnikov <horiz0n@gmx.net>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <boost/assign.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <iostream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "arg_helpers.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "osmosdr/source.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "plutosdr_source_c.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++using namespace boost::assign;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++plutosdr_source_c_sptr make_plutosdr_source_c(const std::string &args)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return gnuradio::get_initial_sptr(new plutosdr_source_c(args));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++plutosdr_source_c::plutosdr_source_c(const std::string &args) :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    gr::hier_block2("plutosdr_source_c",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                   gr::io_signature::make(0, 0, 0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                   gr::io_signature::make(1, 1, sizeof(gr_complex)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  uri = "ip:pluto.local";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  frequency = 434000000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  samplerate = 2500000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  decimation = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bandwidth = 2000000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  buffer_size = 0x4000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  quadrature = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  rfdc = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bbdc = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gain_auto = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gain_value = 50;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  filter = "";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  filter_auto = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _freq_corr = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  dict_t dict = params_to_dict(args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (dict.count("uri"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    uri = boost::lexical_cast< std::string >( dict["uri"] );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::cerr << "Using PlutoSDR URI = " << uri << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _src = gr::iio::pluto_source::make(uri, frequency, samplerate,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                     bandwidth, buffer_size,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                     quadrature, rfdc, bbdc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                     "manual", gain_value,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                     filter.c_str(), filter_auto);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  connect( _src, 0, self(), 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++plutosdr_source_c::~plutosdr_source_c()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::vector< std::string > plutosdr_source_c::get_devices()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector< std::string > devices;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string args = "plutosdr,label='PlutoSDR'";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  devices.push_back( args );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return devices;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::string plutosdr_source_c::name()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return "PlutoSDR";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++size_t plutosdr_source_c::get_num_channels()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return output_signature()->max_streams();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++osmosdr::meta_range_t plutosdr_source_c::get_sample_rates( void )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::meta_range_t rates;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  rates += osmosdr::range_t( 2500000 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  rates += osmosdr::range_t( 5000000 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  rates += osmosdr::range_t( 10000000 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  rates += osmosdr::range_t( 20000000 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return rates;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::set_sample_rate( double rate )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  samplerate = (unsigned long) rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_params();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return samplerate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::get_sample_rate( void )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return samplerate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++osmosdr::freq_range_t plutosdr_source_c::get_freq_range( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::freq_range_t range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  range += osmosdr::range_t( 70.0e6, 6000.0e6, 1.0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::set_center_freq( double freq, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  frequency = (unsigned long long) freq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_params();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return freq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::get_center_freq( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::set_freq_corr( double ppm, size_t chan)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _freq_corr = ppm;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_params();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return ppm;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::get_freq_corr( size_t chan)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return _freq_corr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::vector<std::string> plutosdr_source_c::get_gain_names( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector< std::string > gains;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gains.push_back( "RF" );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return gains;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++osmosdr::gain_range_t plutosdr_source_c::get_gain_range( size_t chan)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::gain_range_t range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  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:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++osmosdr::gain_range_t plutosdr_source_c::get_gain_range( const std::string & name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                                                         size_t chan)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::gain_range_t range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  range += osmosdr::range_t( -10, 77, 1 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool plutosdr_source_c::set_gain_mode( bool automatic, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gain_auto = automatic;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_params();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return automatic;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool plutosdr_source_c::get_gain_mode( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return gain_auto;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::set_gain( double gain, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gain_value = gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_params();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::set_gain( double gain, const std::string & name, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gain_value = gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_params();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::get_gain( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return gain_value;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::get_gain( const std::string & name, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return gain_value;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::vector< std::string > plutosdr_source_c::get_antennas( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector< std::string > antennas;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  antennas += get_antenna( chan );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return antennas;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::string plutosdr_source_c::set_antenna( const std::string & antenna, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return get_antenna( chan );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::string plutosdr_source_c::get_antenna( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return "A_BALANCED";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::set_bandwidth( double bw, size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  if (bw == 0.0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    bw = 0.8 * samplerate;  // auto bandwidth
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bandwidth = (unsigned long)bw;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  set_params();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return bandwidth;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double plutosdr_source_c::get_bandwidth( size_t chan )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  return bandwidth;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void plutosdr_source_c::set_params( void )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  unsigned long long freq = ((double)frequency * (1.0 + _freq_corr * 0.000001));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // FIXME: gain_mode string can be manual / slow_attack / fast_attack / hybrid
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  _src->set_params( freq, samplerate, bandwidth, quadrature, rfdc, bbdc,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                    gain_auto ? "fast_attack" : "manual", gain_value,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                    filter.c_str(), filter_auto );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/plutosdr/plutosdr_source_c.h lib/plutosdr/plutosdr_source_c.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..c515ec9
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/plutosdr/plutosdr_source_c.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,105 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2017 Dimitri Stolnikov <horiz0n@gmx.net>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU Radio is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with GNU Radio; see the file COPYING.  If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef PLUTOSDR_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define PLUTOSDR_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/blocks/float_to_complex.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/blocks/short_to_float.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/hier_block2.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <iio/pluto_source.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "source_iface.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class plutosdr_source_c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef boost::shared_ptr< plutosdr_source_c > plutosdr_source_c_sptr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++plutosdr_source_c_sptr make_plutosdr_source_c(const std::string &args = "");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class plutosdr_source_c :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    public gr::hier_block2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    public source_iface
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  friend plutosdr_source_c_sptr make_plutosdr_source_c(const std::string &args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  plutosdr_source_c(const std::string &args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  ~plutosdr_source_c();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  static std::vector< std::string > get_devices();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string name();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  size_t get_num_channels( void );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::meta_range_t get_sample_rates( void );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_sample_rate( double rate );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_sample_rate( void );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_center_freq( double freq, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_center_freq( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_freq_corr( double ppm, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_freq_corr( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector<std::string> get_gain_names( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool set_gain_mode( bool automatic, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool get_gain_mode( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_gain( double gain, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_gain( double gain, const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_gain( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_gain( const std::string & name, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::vector< std::string > get_antennas( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string set_antenna( const std::string & antenna, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string get_antenna( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double set_bandwidth( double bw, size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double get_bandwidth( size_t chan = 0 );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  void set_params(void);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  gr::iio::pluto_source::sptr       _src;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string   uri;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  unsigned long long frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  unsigned long samplerate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  unsigned long decimation;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  unsigned long bandwidth;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  unsigned long buffer_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool quadrature;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool rfdc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool bbdc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool          gain_auto;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double        gain_value;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  std::string   filter;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  bool          filter_auto;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  double _freq_corr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif // PLUTOSDR_SOURCE_C_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git lib/source_impl.cc lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f1426e0..15042f3 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ lib/source_impl.cc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -56,6 +56,10 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <uhd_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <plutosdr_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_MIRI
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <miri_source_c.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -143,6 +147,9 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_UHD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   dev_types.push_back("uhd");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  dev_types.push_back("plutosdr");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_MIRI
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   dev_types.push_back("miri");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -216,6 +223,10 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    BOOST_FOREACH( std::string dev, plutosdr_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_MIRI
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       dev_list.push_back( dev );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -320,6 +331,13 @@ source_impl::source_impl( const std::string &args )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef ENABLE_IIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    if ( dict.count("plutosdr") ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      plutosdr_source_c_sptr src = make_plutosdr_source_c( arg );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      block = src; iface = src.get();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef ENABLE_MIRI
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if ( dict.count("miri") ) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       miri_source_c_sptr src = make_miri_source_c( arg );
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/science/gr-osmosdr/files/patch-fix-include-directories-ordering.diff b/science/gr-osmosdr/files/patch-fix-include-directories-ordering.diff
</span>deleted file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 78f70e240d6..00000000000
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/science/gr-osmosdr/files/patch-fix-include-directories-ordering.diff
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,290 +0,0 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/CMakeLists.txt b/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 296456d..5754726 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -58,9 +58,11 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    message(FATAL_ERROR "Option ${USE_SIMD} not supported, valid entries are ${USE_SIMD_VALUES}")
</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(CMAKE_CXX_COMPILER MATCHES ".*clang")
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+ SET(CMAKE_COMPILER_IS_CLANGXX 0)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+IF(CMAKE_CXX_COMPILER MATCHES "Clang")
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     SET(CMAKE_COMPILER_IS_CLANGXX 1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ENDIF()
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+MESSAGE(STATUS "CMAKE_COMPILER_IS_CLANGXX is '${CMAKE_COMPILER_IS_CLANGXX}'")
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ADD_DEFINITIONS(-Wall)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -182,9 +184,11 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Setup the include and linker paths
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ########################################################################
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${CMAKE_SOURCE_DIR}/include
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${CMAKE_SOURCE_DIR}/lib
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${Boost_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${GNURADIO_ALL_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/cmake/Modules/GrSwig.cmake b/cmake/Modules/GrSwig.cmake
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index f907a51..a219352 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/cmake/Modules/GrSwig.cmake
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/cmake/Modules/GrSwig.cmake
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -156,7 +156,7 @@
</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;'>-     #append the specified include directories
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--    include_directories(${GR_SWIG_INCLUDE_DIRS})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+    include_directories(AFTER ${GR_SWIG_INCLUDE_DIRS})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     #setup the swig flags with flags and include directories
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 4f83f72..65932ab 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -121,7 +121,7 @@
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- GR_REGISTER_COMPONENT("Osmocom IQ Imbalance Correction" ENABLE_IQBALANCE GNURADIO_IQBALANCE_FOUND)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if(ENABLE_IQBALANCE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- add_definitions(-DHAVE_IQBALANCE=1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--include_directories(${GNURADIO_IQBALANCE_INCLUDE_DIRS})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(AFTER ${GNURADIO_IQBALANCE_INCLUDE_DIRS})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- GR_OSMOSDR_APPEND_LIBS(${GNURADIO_IQBALANCE_LIBRARIES})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- endif(ENABLE_IQBALANCE)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/lib/airspy/CMakeLists.txt b/lib/airspy/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 3e34aa6..52b0c31 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/airspy/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/airspy/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${LIBAIRSPY_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;'>-diff --git a/lib/bladerf/CMakeLists.txt b/lib/bladerf/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index c253a22..026c57f 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/bladerf/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/bladerf/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${LIBBLADERF_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${VOLK_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- )
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/lib/fcd/CMakeLists.txt b/lib/fcd/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index e71b153..3c2bfa6 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/fcd/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/fcd/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,14 +21,14 @@
</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;'>--include_directories(${CMAKE_CURRENT_SOURCE_DIR})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if(ENABLE_FCD)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--include_directories(${GNURADIO_FCD_INCLUDE_DIRS})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(AFTER ${GNURADIO_FCD_INCLUDE_DIRS})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- endif(ENABLE_FCD)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if(ENABLE_FCDPP)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--include_directories(${GNURADIO_FCDPP_INCLUDE_DIRS})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(AFTER ${GNURADIO_FCDPP_INCLUDE_DIRS})
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- endif(ENABLE_FCDPP)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- 
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- set(fcd_srcs
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-diff --git a/lib/file/CMakeLists.txt b/lib/file/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 6c55e85..0bae0b4 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/file/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/file/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,7 +21,7 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-diff --git a/lib/freesrp/CMakeLists.txt b/lib/freesrp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 46df7e4..5cedc4d 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/freesrp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/freesrp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${LIBFREESRP_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;'>-diff --git a/lib/hackrf/CMakeLists.txt b/lib/hackrf/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index c7af0c9..397186a 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/hackrf/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/hackrf/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${LIBHACKRF_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;'>-diff --git a/lib/miri/CMakeLists.txt b/lib/miri/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index ddaeb0a..8d41565 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/miri/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/miri/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${LIBMIRISDR_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;'>-diff --git a/lib/osmosdr/CMakeLists.txt b/lib/osmosdr/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index b0872f8..73714ed 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/osmosdr/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/osmosdr/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${LIBOSMOSDR_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;'>-diff --git a/lib/redpitaya/CMakeLists.txt b/lib/redpitaya/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index a14dc9e..64ffc35 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/redpitaya/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/redpitaya/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,7 +21,7 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-diff --git a/lib/rfspace/CMakeLists.txt b/lib/rfspace/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index eebc15d..f5b9ebe 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/rfspace/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/rfspace/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,7 +21,7 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-diff --git a/lib/rtl/CMakeLists.txt b/lib/rtl/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index f438df5..053b0da 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/rtl/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/rtl/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${LIBRTLSDR_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;'>-diff --git a/lib/rtl_tcp/CMakeLists.txt b/lib/rtl_tcp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 9f7c201..1010304 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/rtl_tcp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/rtl_tcp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,7 +21,7 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-diff --git a/lib/sdrplay/CMakeLists.txt b/lib/sdrplay/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 382ab33..2a468b6 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/sdrplay/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/sdrplay/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${LIBSDRPLAY_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;'>-diff --git a/lib/soapy/CMakeLists.txt b/lib/soapy/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index 338bcaf..c639d2e 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/soapy/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/soapy/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${SoapySDR_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;'>-diff --git a/lib/uhd/CMakeLists.txt b/lib/uhd/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-index aba5c77..c2539ca 100644
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>---- a/lib/uhd/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+++ b/lib/uhd/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-@@ -21,8 +21,10 @@
</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;'>--include_directories(
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-+include_directories(BEFORE
</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;'>-+include_directories(AFTER
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${GNURADIO_UHD_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     ${UHD_INCLUDE_DIRS}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- )
</span></pre><pre style='margin:0'>

</pre>