aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CMakeLists.txt193
-rw-r--r--lib/airspy/CMakeLists.txt25
-rw-r--r--lib/airspy/airspy_source_c.cc3
-rw-r--r--lib/airspy/airspy_source_c.h9
-rw-r--r--lib/airspyhf/airspyhf_source_c.cc437
-rw-r--r--lib/arg_helpers.h15
-rw-r--r--lib/bladerf/CMakeLists.txt26
-rw-r--r--lib/bladerf/bladerf_common.cc24
-rw-r--r--lib/bladerf/bladerf_common.h11
-rw-r--r--lib/bladerf/bladerf_compat.h2
-rw-r--r--lib/bladerf/bladerf_sink_c.cc25
-rw-r--r--lib/bladerf/bladerf_source_c.cc14
-rw-r--r--lib/config.h.in4
-rw-r--r--lib/device.cc63
-rw-r--r--lib/fcd/CMakeLists.txt39
-rw-r--r--lib/fcd/fcd_source_c.cc21
-rw-r--r--lib/fcd/fcd_source_c.h13
-rw-r--r--lib/file/CMakeLists.txt25
-rw-r--r--lib/freesrp/CMakeLists.txt23
-rw-r--r--lib/freesrp/freesrp_common.cc3
-rw-r--r--lib/freesrp/freesrp_common.h3
-rw-r--r--lib/gnuradio-osmosdr.rc.in55
-rw-r--r--lib/hackrf/CMakeLists.txt33
-rw-r--r--lib/hackrf/hackrf_common.cc427
-rw-r--r--lib/hackrf/hackrf_common.h113
-rw-r--r--lib/hackrf/hackrf_sink_c.cc425
-rw-r--r--lib/hackrf/hackrf_sink_c.h37
-rw-r--r--lib/hackrf/hackrf_source_c.cc453
-rw-r--r--lib/hackrf/hackrf_source_c.h40
-rw-r--r--lib/miri/CMakeLists.txt (renamed from lib/xtrx/CMakeLists.txt)16
-rw-r--r--lib/miri/miri_source_c.cc451
-rw-r--r--lib/miri/miri_source_c.h (renamed from lib/airspyhf/airspyhf_source_c.h)98
-rw-r--r--lib/osmosdr/CMakeLists.txt (renamed from lib/airspyhf/CMakeLists.txt)28
-rw-r--r--lib/osmosdr/osmosdr_src_c.cc533
-rw-r--r--lib/osmosdr/osmosdr_src_c.h139
-rw-r--r--lib/ranges.cc13
-rw-r--r--lib/redpitaya/CMakeLists.txt23
-rw-r--r--lib/rfspace/CMakeLists.txt20
-rw-r--r--lib/rfspace/rfspace_source_c.cc156
-rw-r--r--lib/rfspace/rfspace_source_c.h31
-rw-r--r--lib/rtl/CMakeLists.txt24
-rw-r--r--lib/rtl/rtl_source_c.cc7
-rw-r--r--lib/rtl/rtl_source_c.h9
-rw-r--r--lib/rtl_tcp/CMakeLists.txt24
-rw-r--r--lib/rtl_tcp/rtl_tcp_source_c.cc10
-rw-r--r--lib/sdrplay/CMakeLists.txt23
-rw-r--r--lib/sdrplay/sdrplay_source_c.h7
-rw-r--r--lib/sink_impl.cc107
-rw-r--r--lib/soapy/CMakeLists.txt23
-rw-r--r--lib/soapy/soapy_common.cc4
-rw-r--r--lib/soapy/soapy_common.h5
-rw-r--r--lib/soapy/soapy_sink_c.cc16
-rw-r--r--lib/soapy/soapy_source_c.cc27
-rw-r--r--lib/source_impl.cc199
-rw-r--r--lib/uhd/CMakeLists.txt26
-rw-r--r--lib/uhd/uhd_sink_c.cc15
-rw-r--r--lib/uhd/uhd_source_c.cc15
-rw-r--r--lib/xtrx/xtrx_obj.cc138
-rw-r--r--lib/xtrx/xtrx_obj.h68
-rw-r--r--lib/xtrx/xtrx_sink_c.cc505
-rw-r--r--lib/xtrx/xtrx_sink_c.h129
-rw-r--r--lib/xtrx/xtrx_source_c.cc583
-rw-r--r--lib/xtrx/xtrx_source_c.h127
63 files changed, 2841 insertions, 3319 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 1bb8655..d95109b 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,32 +1,41 @@
# Copyright 2011 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
########################################################################
# Setup library
########################################################################
-include(GrPlatform) #define LIB_SUFFIX
+INCLUDE(GrPlatform) #define LIB_SUFFIX
+INCLUDE(GrMiscUtils)
+INCLUDE(GrComponent)
########################################################################
-# Setup target
+# Helpful Macros
########################################################################
+MACRO(GR_OSMOSDR_APPEND_SRCS)
+ LIST(APPEND gr_osmosdr_srcs ${ARGV})
+ENDMACRO(GR_OSMOSDR_APPEND_SRCS)
-list(APPEND gr_osmosdr_srcs
+MACRO(GR_OSMOSDR_APPEND_LIBS)
+ LIST(APPEND gr_osmosdr_libs ${ARGV})
+ENDMACRO(GR_OSMOSDR_APPEND_LIBS)
+
+GR_OSMOSDR_APPEND_SRCS(
source_impl.cc
sink_impl.cc
ranges.cc
@@ -34,44 +43,28 @@ list(APPEND gr_osmosdr_srcs
time_spec.cc
)
+set(CMAKE_CXX_STANDARD 11)
+
#-pthread Adds support for multithreading with the pthreads library.
#This option sets flags for both the preprocessor and linker. (man gcc)
if(CMAKE_COMPILER_IS_GNUCXX)
list(APPEND Boost_LIBRARIES -pthread)
endif()
-#dirty macro to allow appending from subdirs
-#this appends all unnamed implicit macro args!
-MACRO (APPEND_LIB_LIST)
- SET (gr_osmosdr_libs "${gr_osmosdr_libs};${ARGN}" CACHE INTERNAL "lib list")
-ENDMACRO (APPEND_INTERNAL_LIST)
-
-set(gr_osmosdr_libs "" CACHE INTERNAL "lib that accumulates link targets")
-
-add_library(gnuradio-osmosdr SHARED)
-APPEND_LIB_LIST(${Boost_LIBRARIES} gnuradio::gnuradio-runtime)
-target_include_directories(gnuradio-osmosdr
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PUBLIC ${Boost_INCLUDE_DIRS}
- PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
- PUBLIC $<INSTALL_INTERFACE:include>
- )
-set_target_properties(gnuradio-osmosdr PROPERTIES DEFINE_SYMBOL "gnuradio_osmosdr_EXPORTS")
-
-if(APPLE)
- set_target_properties(gnuradio-osmosdr PROPERTIES
- INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
- )
-endif(APPLE)
+GR_OSMOSDR_APPEND_LIBS(
+ ${Boost_LIBRARIES}
+ gnuradio::gnuradio-blocks
+ ${GNURADIO_ALL_LIBRARIES}
+)
########################################################################
# Setup defines for high resolution timing
########################################################################
-message(STATUS "")
-message(STATUS "Configuring high resolution timing...")
-include(CheckCXXSourceCompiles)
+MESSAGE(STATUS "")
+MESSAGE(STATUS "Configuring high resolution timing...")
+INCLUDE(CheckCXXSourceCompiles)
-set(CMAKE_REQUIRED_LIBRARIES -lrt)
+SET(CMAKE_REQUIRED_LIBRARIES -lrt)
CHECK_CXX_SOURCE_COMPILES("
#include <ctime>
int main(){
@@ -80,9 +73,9 @@ CHECK_CXX_SOURCE_COMPILES("
}
" HAVE_CLOCK_GETTIME
)
-unset(CMAKE_REQUIRED_LIBRARIES)
+UNSET(CMAKE_REQUIRED_LIBRARIES)
-include(CheckCXXSourceCompiles)
+INCLUDE(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("
#include <mach/mach_time.h>
int main(){
@@ -105,22 +98,22 @@ CHECK_CXX_SOURCE_COMPILES("
" HAVE_QUERY_PERFORMANCE_COUNTER
)
-if(HAVE_CLOCK_GETTIME)
- message(STATUS " High resolution timing supported through clock_gettime.")
- set(TIME_SPEC_DEFS HAVE_CLOCK_GETTIME)
- APPEND_LIB_LIST( "-lrt")
-elseif(HAVE_MACH_ABSOLUTE_TIME)
- message(STATUS " High resolution timing supported through mach_absolute_time.")
- set(TIME_SPEC_DEFS HAVE_MACH_ABSOLUTE_TIME)
-elseif(HAVE_QUERY_PERFORMANCE_COUNTER)
- message(STATUS " High resolution timing supported through QueryPerformanceCounter.")
- set(TIME_SPEC_DEFS HAVE_QUERY_PERFORMANCE_COUNTER)
-else()
- message(STATUS " High resolution timing supported through microsec_clock.")
- set(TIME_SPEC_DEFS HAVE_MICROSEC_CLOCK)
-endif()
-
-set_source_files_properties(
+IF(HAVE_CLOCK_GETTIME)
+ MESSAGE(STATUS " High resolution timing supported through clock_gettime.")
+ SET(TIME_SPEC_DEFS HAVE_CLOCK_GETTIME)
+ GR_OSMOSDR_APPEND_LIBS("-lrt")
+ELSEIF(HAVE_MACH_ABSOLUTE_TIME)
+ MESSAGE(STATUS " High resolution timing supported through mach_absolute_time.")
+ SET(TIME_SPEC_DEFS HAVE_MACH_ABSOLUTE_TIME)
+ELSEIF(HAVE_QUERY_PERFORMANCE_COUNTER)
+ MESSAGE(STATUS " High resolution timing supported through QueryPerformanceCounter.")
+ SET(TIME_SPEC_DEFS HAVE_QUERY_PERFORMANCE_COUNTER)
+ELSE()
+ MESSAGE(STATUS " High resolution timing supported through microsec_clock.")
+ SET(TIME_SPEC_DEFS HAVE_MICROSEC_CLOCK)
+ENDIF()
+
+SET_SOURCE_FILES_PROPERTIES(
time_spec.cc
PROPERTIES COMPILE_DEFINITIONS "${TIME_SPEC_DEFS}"
)
@@ -128,27 +121,27 @@ set_source_files_properties(
########################################################################
# Setup IQBalance component
########################################################################
-GR_REGISTER_COMPONENT("Osmocom IQ Imbalance Correction" ENABLE_IQBALANCE gnuradio-iqbalance_FOUND)
+GR_REGISTER_COMPONENT("Osmocom IQ Imbalance Correction" ENABLE_IQBALANCE GNURADIO_IQBALANCE_FOUND)
if(ENABLE_IQBALANCE)
- add_definitions(-DHAVE_IQBALANCE=1)
- target_include_directories(gnuradio-osmosdr PRIVATE ${gnuradio-iqbalance_INCLUDE_DIRS})
- APPEND_LIB_LIST( gnuradio::gnuradio-iqbalance)
+add_definitions(-DHAVE_IQBALANCE=1)
+include_directories(${GNURADIO_IQBALANCE_INCLUDE_DIRS})
+GR_OSMOSDR_APPEND_LIBS(${GNURADIO_IQBALANCE_LIBRARIES})
endif(ENABLE_IQBALANCE)
########################################################################
-# Setup FCD component
+# Setup OsmoSDR component
########################################################################
-GR_REGISTER_COMPONENT("FUNcube Dongle" ENABLE_FCD GNURADIO_FCDPP_FOUND)
-if(ENABLE_FCD)
- add_subdirectory(fcd)
-endif(ENABLE_FCD)
+GR_REGISTER_COMPONENT("sysmocom OsmoSDR" ENABLE_OSMOSDR LIBOSMOSDR_FOUND)
+if(ENABLE_OSMOSDR)
+GR_INCLUDE_SUBDIRECTORY(osmosdr)
+endif(ENABLE_OSMOSDR)
########################################################################
# Setup File component
########################################################################
-GR_REGISTER_COMPONENT("IQ File Source & Sink" ENABLE_FILE gnuradio-blocks_FOUND)
+GR_REGISTER_COMPONENT("IQ File Source & Sink" ENABLE_FILE GNURADIO_BLOCKS_FOUND)
if(ENABLE_FILE)
- add_subdirectory(file)
+GR_INCLUDE_SUBDIRECTORY(file)
endif(ENABLE_FILE)
########################################################################
@@ -156,32 +149,40 @@ endif(ENABLE_FILE)
########################################################################
GR_REGISTER_COMPONENT("Osmocom RTLSDR" ENABLE_RTL LIBRTLSDR_FOUND)
if(ENABLE_RTL)
- add_subdirectory(rtl)
+GR_INCLUDE_SUBDIRECTORY(rtl)
endif(ENABLE_RTL)
########################################################################
# Setup RTL_TCP component
########################################################################
-GR_REGISTER_COMPONENT("RTLSDR TCP Client" ENABLE_RTL_TCP gnuradio-blocks_FOUND)
+GR_REGISTER_COMPONENT("RTLSDR TCP Client" ENABLE_RTL_TCP GNURADIO_BLOCKS_FOUND)
if(ENABLE_RTL_TCP)
- add_subdirectory(rtl_tcp)
+GR_INCLUDE_SUBDIRECTORY(rtl_tcp)
endif(ENABLE_RTL_TCP)
########################################################################
# Setup UHD component
########################################################################
-GR_REGISTER_COMPONENT("Ettus USRP Devices" ENABLE_UHD UHD_FOUND gnuradio-uhd_FOUND)
+GR_REGISTER_COMPONENT("Ettus USRP Devices" ENABLE_UHD UHD_FOUND GNURADIO_UHD_FOUND)
if(ENABLE_UHD)
- add_subdirectory(uhd)
+GR_INCLUDE_SUBDIRECTORY(uhd)
endif(ENABLE_UHD)
########################################################################
+# Setup MiriSDR component
+########################################################################
+GR_REGISTER_COMPONENT("Osmocom MiriSDR" ENABLE_MIRI LIBMIRISDR_FOUND)
+if(ENABLE_MIRI)
+GR_INCLUDE_SUBDIRECTORY(miri)
+endif(ENABLE_MIRI)
+
+########################################################################
# Setup SDRplay component
########################################################################
if(ENABLE_NONFREE)
GR_REGISTER_COMPONENT("SDRplay RSP (NONFREE)" ENABLE_SDRPLAY LIBSDRPLAY_FOUND)
if(ENABLE_SDRPLAY)
- add_subdirectory(sdrplay)
+GR_INCLUDE_SUBDIRECTORY(sdrplay)
endif(ENABLE_SDRPLAY)
endif(ENABLE_NONFREE)
@@ -190,7 +191,7 @@ endif(ENABLE_NONFREE)
########################################################################
GR_REGISTER_COMPONENT("HackRF & rad1o Badge" ENABLE_HACKRF LIBHACKRF_FOUND)
if(ENABLE_HACKRF)
- add_subdirectory(hackrf)
+GR_INCLUDE_SUBDIRECTORY(hackrf)
endif(ENABLE_HACKRF)
########################################################################
@@ -198,7 +199,7 @@ endif(ENABLE_HACKRF)
########################################################################
GR_REGISTER_COMPONENT("nuand bladeRF" ENABLE_BLADERF LIBBLADERF_FOUND)
if(ENABLE_BLADERF)
- add_subdirectory(bladerf)
+GR_INCLUDE_SUBDIRECTORY(bladerf)
endif(ENABLE_BLADERF)
########################################################################
@@ -206,7 +207,7 @@ endif(ENABLE_BLADERF)
########################################################################
GR_REGISTER_COMPONENT("RFSPACE Receivers" ENABLE_RFSPACE)
if(ENABLE_RFSPACE)
- add_subdirectory(rfspace)
+GR_INCLUDE_SUBDIRECTORY(rfspace)
endif(ENABLE_RFSPACE)
########################################################################
@@ -214,23 +215,15 @@ endif(ENABLE_RFSPACE)
########################################################################
GR_REGISTER_COMPONENT("AIRSPY Receiver" ENABLE_AIRSPY LIBAIRSPY_FOUND)
if(ENABLE_AIRSPY)
- add_subdirectory(airspy)
+GR_INCLUDE_SUBDIRECTORY(airspy)
endif(ENABLE_AIRSPY)
########################################################################
-# Setup AIRSPYHF component
-########################################################################
-GR_REGISTER_COMPONENT("AIRSPY HF+ Receiver" ENABLE_AIRSPYHF LIBAIRSPYHF_FOUND)
-if(ENABLE_AIRSPYHF)
- add_subdirectory(airspyhf)
-endif(ENABLE_AIRSPYHF)
-
-########################################################################
# Setup SoapySDR component
########################################################################
GR_REGISTER_COMPONENT("SoapySDR support" ENABLE_SOAPY SoapySDR_FOUND)
if(ENABLE_SOAPY)
- add_subdirectory(soapy)
+GR_INCLUDE_SUBDIRECTORY(soapy)
endif(ENABLE_SOAPY)
########################################################################
@@ -238,7 +231,7 @@ endif(ENABLE_SOAPY)
########################################################################
GR_REGISTER_COMPONENT("Red Pitaya SDR" ENABLE_REDPITAYA)
if(ENABLE_REDPITAYA)
- add_subdirectory(redpitaya)
+GR_INCLUDE_SUBDIRECTORY(redpitaya)
endif(ENABLE_REDPITAYA)
########################################################################
@@ -246,35 +239,37 @@ endif(ENABLE_REDPITAYA)
########################################################################
GR_REGISTER_COMPONENT("FreeSRP support" ENABLE_FREESRP LIBFREESRP_FOUND)
if(ENABLE_FREESRP)
- add_subdirectory(freesrp)
+GR_INCLUDE_SUBDIRECTORY(freesrp)
endif(ENABLE_FREESRP)
########################################################################
-# Setup XTRX component
-########################################################################
-GR_REGISTER_COMPONENT("XTRX SDR" ENABLE_XTRX LIBXTRX_FOUND)
-if(ENABLE_XTRX)
- add_subdirectory(xtrx)
-endif(ENABLE_XTRX)
-
-########################################################################
# Setup configuration file
########################################################################
-add_definitions(-DHAVE_CONFIG_H=1)
+ADD_DEFINITIONS(-DHAVE_CONFIG_H=1)
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-configure_file(
+CONFIGURE_FILE(
${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h
@ONLY)
########################################################################
-# Finalize target
+# Set up Windows DLL resource files
########################################################################
-set_target_properties(gnuradio-osmosdr PROPERTIES SOURCES "${gr_osmosdr_srcs}")
-target_link_libraries(gnuradio-osmosdr ${gr_osmosdr_libs})
+IF(MSVC)
+ include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake)
+
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-osmosdr.rc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-osmosdr.rc
+ @ONLY)
+
+ GR_OSMOSDR_APPEND_SRCS(${CMAKE_CURRENT_BINARY_DIR}/gnuradio-osmosdr.rc)
+ENDIF(MSVC)
########################################################################
-# Install built library files
+# Setup libgnuradio-osmosdr library
########################################################################
-include(GrMiscUtils)
+ADD_LIBRARY(gnuradio-osmosdr SHARED ${gr_osmosdr_srcs})
+TARGET_LINK_LIBRARIES(gnuradio-osmosdr ${gr_osmosdr_libs})
+SET_TARGET_PROPERTIES(gnuradio-osmosdr PROPERTIES DEFINE_SYMBOL "gnuradio_osmosdr_EXPORTS")
GR_LIBRARY_FOO(gnuradio-osmosdr)
diff --git a/lib/airspy/CMakeLists.txt b/lib/airspy/CMakeLists.txt
index 187d938..3e34aa6 100644
--- a/lib/airspy/CMakeLists.txt
+++ b/lib/airspy/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,18 +21,17 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${LIBAIRSPY_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- gnuradio::gnuradio-filter
- ${Gnuradio-blocks_LIBRARIES}
- ${LIBAIRSPY_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(airspy_srcs
${CMAKE_CURRENT_SOURCE_DIR}/airspy_source_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${airspy_srcs})
+list(APPEND gr_osmosdr_libs ${LIBAIRSPY_LIBRARIES} ${GNURADIO_FILTER_LIBRARIES} ${GNURADIO_BLOCKS_LIBRARIES})
diff --git a/lib/airspy/airspy_source_c.cc b/lib/airspy/airspy_source_c.cc
index 7fd3be8..50150e5 100644
--- a/lib/airspy/airspy_source_c.cc
+++ b/lib/airspy/airspy_source_c.cc
@@ -33,6 +33,7 @@
#include <boost/assign.hpp>
#include <boost/format.hpp>
+#include <boost/detail/endian.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/thread/thread.hpp>
@@ -290,7 +291,7 @@ int airspy_source_c::work( int noutput_items,
if ( ! running )
return WORK_DONE;
- std::unique_lock<std::mutex> lock(_fifo_lock);
+ boost::unique_lock<boost::mutex> lock(_fifo_lock);
/* Wait until we have the requested number of samples */
int n_samples_avail = _fifo->size();
diff --git a/lib/airspy/airspy_source_c.h b/lib/airspy/airspy_source_c.h
index a7d817f..f8617e6 100644
--- a/lib/airspy/airspy_source_c.h
+++ b/lib/airspy/airspy_source_c.h
@@ -23,9 +23,8 @@
#define INCLUDED_AIRSPY_SOURCE_C_H
#include <boost/circular_buffer.hpp>
-
-#include <mutex>
-#include <condition_variable>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
#include <gnuradio/sync_block.h>
@@ -129,8 +128,8 @@ private:
airspy_device *_dev;
boost::circular_buffer<gr_complex> *_fifo;
- std::mutex _fifo_lock;
- std::condition_variable _samp_avail;
+ boost::mutex _fifo_lock;
+ boost::condition_variable _samp_avail;
std::vector< std::pair<double, uint32_t> > _sample_rates;
double _sample_rate;
diff --git a/lib/airspyhf/airspyhf_source_c.cc b/lib/airspyhf/airspyhf_source_c.cc
deleted file mode 100644
index 26e0134..0000000
--- a/lib/airspyhf/airspyhf_source_c.cc
+++ /dev/null
@@ -1,437 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-/*
- * config.h is generated by configure. It contains the results
- * of probing for features, options etc. It should be the first
- * file included in your .cc file.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdexcept>
-#include <iostream>
-#include <algorithm>
-
-#include <boost/assign.hpp>
-#include <boost/format.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/thread/thread.hpp>
-
-#include <gnuradio/io_signature.h>
-
-#include "airspyhf_source_c.h"
-#include "arg_helpers.h"
-
-using namespace boost::assign;
-
-#define AIRSPYHF_FORMAT_ERROR(ret, msg) \
- boost::str( boost::format(msg " (%1%)") % ret )
-
-#define AIRSPYHF_THROW_ON_ERROR(ret, msg) \
- if ( ret != AIRSPYHF_SUCCESS ) \
- { \
- throw std::runtime_error( AIRSPYHF_FORMAT_ERROR(ret, msg) ); \
- }
-
-#define AIRSPYHF_FUNC_STR(func, arg) \
- boost::str(boost::format(func "(%1%)") % arg) + " has failed"
-
-airspyhf_source_c_sptr make_airspyhf_source_c (const std::string & args)
-{
- return gnuradio::get_initial_sptr(new airspyhf_source_c (args));
-}
-
-/*
- * Specify constraints on number of input and output streams.
- * This info is used to construct the input and output signatures
- * (2nd & 3rd args to gr::block's constructor). The input and
- * output signatures are used by the runtime system to
- * check that a valid number and type of inputs and outputs
- * are connected to this block. In this case, we accept
- * only 0 input and 1 output.
- */
-static const int MIN_IN = 0; // mininum number of input streams
-static const int MAX_IN = 0; // maximum number of input streams
-static const int MIN_OUT = 1; // minimum number of output streams
-static const int MAX_OUT = 1; // maximum number of output streams
-
-/*
- * The private constructor
- */
-airspyhf_source_c::airspyhf_source_c (const std::string &args)
- : gr::sync_block ("airspyhf_source_c",
- gr::io_signature::make(MIN_IN, MAX_IN, sizeof (gr_complex)),
- gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof (gr_complex))),
- _dev(NULL),
- _sample_rate(0),
- _center_freq(0),
- _freq_corr(0)
-{
- int ret;
-
- dict_t dict = params_to_dict(args);
-
- _dev = NULL;
- ret = airspyhf_open( &_dev );
- AIRSPYHF_THROW_ON_ERROR(ret, "Failed to open Airspy HF+ device")
-
- uint32_t num_rates;
- airspyhf_get_samplerates(_dev, &num_rates, 0);
- uint32_t *samplerates = (uint32_t *) malloc(num_rates * sizeof(uint32_t));
- airspyhf_get_samplerates(_dev, samplerates, num_rates);
- for (size_t i = 0; i < num_rates; i++)
- _sample_rates.push_back( std::pair<double, uint32_t>( samplerates[i], i ) );
- free(samplerates);
-
- /* since they may (and will) give us an unsorted array we have to sort it here
- * to play nice with the monotonic requirement of meta-range later on */
- std::sort(_sample_rates.begin(), _sample_rates.end());
-
- std::cerr << "Using libairspyhf" << AIRSPYHF_VERSION << ", samplerates: ";
-
- for (size_t i = 0; i < _sample_rates.size(); i++)
- std::cerr << boost::format("%gM ") % (_sample_rates[i].first / 1e6);
-
- std::cerr << std::endl;
-
- set_center_freq( (get_freq_range().start() + get_freq_range().stop()) / 2.0 );
- set_sample_rate( get_sample_rates().start() );
-
- _fifo = new boost::circular_buffer<gr_complex>(5000000);
- if (!_fifo) {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "Failed to allocate a sample FIFO!" );
- }
-}
-
-/*
- * Our virtual destructor.
- */
-airspyhf_source_c::~airspyhf_source_c ()
-{
- int ret;
-
- if (_dev) {
- if ( airspyhf_is_streaming( _dev ) )
- {
- ret = airspyhf_stop( _dev );
- if ( ret != AIRSPYHF_SUCCESS )
- {
- std::cerr << AIRSPYHF_FORMAT_ERROR(ret, "Failed to stop RX streaming") << std::endl;
- }
- }
-
- ret = airspyhf_close( _dev );
- if ( ret != AIRSPYHF_SUCCESS )
- {
- std::cerr << AIRSPYHF_FORMAT_ERROR(ret, "Failed to close AirSpy") << std::endl;
- }
- _dev = NULL;
- }
-
- if (_fifo)
- {
- delete _fifo;
- _fifo = NULL;
- }
-}
-
-int airspyhf_source_c::_airspyhf_rx_callback(airspyhf_transfer_t *transfer)
-{
- airspyhf_source_c *obj = (airspyhf_source_c *)transfer->ctx;
-
- return obj->airspyhf_rx_callback((float *)transfer->samples, transfer->sample_count);
-}
-
-int airspyhf_source_c::airspyhf_rx_callback(void *samples, int sample_count)
-{
- size_t i, n_avail, to_copy, num_samples = sample_count;
- float *sample = (float *)samples;
-
- _fifo_lock.lock();
-
- n_avail = _fifo->capacity() - _fifo->size();
- to_copy = (n_avail < num_samples ? n_avail : num_samples);
-
- for (i = 0; i < to_copy; i++ )
- {
- /* Push sample to the fifo */
- _fifo->push_back( gr_complex( *sample, *(sample+1) ) );
-
- /* offset to the next I+Q sample */
- sample += 2;
- }
-
- _fifo_lock.unlock();
-
- /* We have made some new samples available to the consumer in work() */
- if (to_copy) {
- //std::cerr << "+" << std::flush;
- _samp_avail.notify_one();
- }
-
- /* Indicate overrun, if neccesary */
- if (to_copy < num_samples)
- std::cerr << "O" << std::flush;
-
- return 0; // TODO: return -1 on error/stop
-}
-
-bool airspyhf_source_c::start()
-{
- if ( ! _dev )
- return false;
-
- int ret = airspyhf_start( _dev, _airspyhf_rx_callback, (void *)this );
- if ( ret != AIRSPYHF_SUCCESS ) {
- std::cerr << "Failed to start RX streaming (" << ret << ")" << std::endl;
- return false;
- }
-
- return true;
-}
-
-bool airspyhf_source_c::stop()
-{
- if ( ! _dev )
- return false;
-
- int ret = airspyhf_stop( _dev );
- if ( ret != AIRSPYHF_SUCCESS ) {
- std::cerr << "Failed to stop RX streaming (" << ret << ")" << std::endl;
- return false;
- }
-
- return true;
-}
-
-int airspyhf_source_c::work( int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items )
-{
- gr_complex *out = (gr_complex *)output_items[0];
-
- bool running = false;
-
- if ( _dev )
- running = airspyhf_is_streaming( _dev );
-
- if ( ! running )
- return WORK_DONE;
-
- std::unique_lock<std::mutex> lock(_fifo_lock);
-
- /* Wait until we have the requested number of samples */
- int n_samples_avail = _fifo->size();
-
- while (n_samples_avail < noutput_items) {
- _samp_avail.wait(lock);
- n_samples_avail = _fifo->size();
- }
-
- for(int i = 0; i < noutput_items; ++i) {
- out[i] = _fifo->at(0);
- _fifo->pop_front();
- }
-
- return noutput_items;
-}
-
-std::vector<std::string> airspyhf_source_c::get_devices()
-{
- std::vector<std::string> devices;
- std::string label;
-
- int ret;
- airspyhf_device *dev = NULL;
- ret = airspyhf_open(&dev);
- if ( AIRSPYHF_SUCCESS == ret )
- {
- std::string args = "airspyhf=0,label='AirspyHF'";
- devices.push_back( args );
- ret = airspyhf_close(dev);
- }
-
- return devices;
-}
-
-size_t airspyhf_source_c::get_num_channels()
-{
- return 1;
-}
-
-osmosdr::meta_range_t airspyhf_source_c::get_sample_rates()
-{
- osmosdr::meta_range_t range;
-
- for (size_t i = 0; i < _sample_rates.size(); i++)
- range += osmosdr::range_t( _sample_rates[i].first );
-
- return range;
-}
-
-double airspyhf_source_c::set_sample_rate( double rate )
-{
- int ret = AIRSPYHF_SUCCESS;
-
- if (_dev) {
- bool found_supported_rate = false;
- uint32_t samp_rate_index = 0;
-
- for( unsigned int i = 0; i < _sample_rates.size(); i++ )
- {
- if( _sample_rates[i].first == rate )
- {
- samp_rate_index = _sample_rates[i].second;
-
- found_supported_rate = true;
- }
- }
-
- if ( ! found_supported_rate )
- {
- throw std::runtime_error(
- boost::str( boost::format("Unsupported samplerate: %gM") % (rate/1e6) ) );
- }
-
- ret = airspyhf_set_samplerate( _dev, samp_rate_index );
- if ( AIRSPYHF_SUCCESS == ret ) {
- _sample_rate = rate;
- } else {
- AIRSPYHF_THROW_ON_ERROR( ret, AIRSPYHF_FUNC_STR( "airspyhf_set_samplerate", rate ) )
- }
- }
-
- return get_sample_rate();
-}
-
-double airspyhf_source_c::get_sample_rate()
-{
- return _sample_rate;
-}
-
-osmosdr::freq_range_t airspyhf_source_c::get_freq_range( size_t chan )
-{
- osmosdr::freq_range_t range;
-
- range += osmosdr::range_t( 0.0, 260.0e6 );
-
- return range;
-}
-
-double airspyhf_source_c::set_center_freq( double freq, size_t chan )
-{
- int ret;
-
- if (_dev) {
- ret = airspyhf_set_freq( _dev, freq );
- if ( AIRSPYHF_SUCCESS == ret ) {
- _center_freq = freq;
- } else {
- AIRSPYHF_THROW_ON_ERROR( ret, AIRSPYHF_FUNC_STR( "airspyhf_set_freq", freq ) )
- }
- }
-
- return get_center_freq( chan );
-}
-
-double airspyhf_source_c::get_center_freq( size_t chan )
-{
- return _center_freq;
-}
-
-double airspyhf_source_c::set_freq_corr( double ppm, size_t chan )
-{
- int ret;
- int32_t ppb = (int32_t) (ppm * 1.0e3);
-
- if (_dev) {
- ret = airspyhf_set_calibration( _dev, ppb );
- if ( AIRSPYHF_SUCCESS == ret ) {
- _freq_corr = ppm;
- } else {
- AIRSPYHF_THROW_ON_ERROR( ret, AIRSPYHF_FUNC_STR( "airspyhf_set_calibration", ppm ) )
- }
- }
-
- return ppm;
-}
-
-double airspyhf_source_c::get_freq_corr( size_t chan )
-{
- return _freq_corr;
-}
-
-std::vector<std::string> airspyhf_source_c::get_gain_names( size_t chan )
-{
- return {};
-}
-
-osmosdr::gain_range_t airspyhf_source_c::get_gain_range( size_t chan )
-{
- return osmosdr::gain_range_t();
-}
-
-osmosdr::gain_range_t airspyhf_source_c::get_gain_range( const std::string & name, size_t chan )
-{
- return osmosdr::gain_range_t();
-}
-
-
-double airspyhf_source_c::set_gain( double gain, size_t chan )
-{
- return gain;
-}
-
-double airspyhf_source_c::set_gain( double gain, const std::string & name, size_t chan)
-{
- return gain;
-}
-
-double airspyhf_source_c::get_gain( size_t chan )
-{
- return 0.0;
-}
-
-double airspyhf_source_c::get_gain( const std::string & name, size_t chan )
-{
- return 0.0;
-}
-
-std::vector< std::string > airspyhf_source_c::get_antennas( size_t chan )
-{
- std::vector< std::string > antennas;
-
- antennas += get_antenna( chan );
-
- return antennas;
-}
-
-std::string airspyhf_source_c::set_antenna( const std::string & antenna, size_t chan )
-{
- return get_antenna( chan );
-}
-
-std::string airspyhf_source_c::get_antenna( size_t chan )
-{
- return "RX";
-}
diff --git a/lib/arg_helpers.h b/lib/arg_helpers.h
index 3b02b8f..2278fa9 100644
--- a/lib/arg_helpers.h
+++ b/lib/arg_helpers.h
@@ -29,6 +29,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
+#include <boost/foreach.hpp>
#include <ciso646>
typedef std::map< std::string, std::string > dict_t;
@@ -37,7 +38,7 @@ typedef std::pair< std::string, std::string > pair_t;
inline std::string dict_to_args_string( const dict_t &d )
{
std::string out;
- for (const pair_t pair : d)
+ BOOST_FOREACH(const pair_t pair, d)
{
if (not out.empty()) out += ",";
out += pair.first + "='" + pair.second + "'";
@@ -53,7 +54,7 @@ inline std::vector< std::string > args_to_vector( const std::string &args )
typedef boost::tokenizer< boost::escaped_list_separator<char> > tokenizer_t;
tokenizer_t tokens(args, separator);
- for (std::string token : tokens)
+ BOOST_FOREACH(std::string token, tokens)
result.push_back(token);
return result;
@@ -67,7 +68,7 @@ inline std::vector< std::string > params_to_vector( const std::string &params )
typedef boost::tokenizer< boost::escaped_list_separator<char> > tokenizer_t;
tokenizer_t tokens(params, separator);
- for (std::string token : tokens)
+ BOOST_FOREACH(std::string token, tokens)
result.push_back(token);
return result;
@@ -97,7 +98,7 @@ inline dict_t params_to_dict( const std::string &params )
dict_t result;
std::vector< std::string > param_list = params_to_vector( params );
- for (std::string param : param_list)
+ BOOST_FOREACH(std::string param, param_list)
{
pair_t pair = param_to_pair( param );
std::string value = pair.second;
@@ -123,7 +124,7 @@ inline gr::io_signature::sptr args_to_io_signature( const std::string &args )
size_t dev_nchan = 0;
std::vector< std::string > arg_list = args_to_vector( args );
- for (std::string arg : arg_list)
+ BOOST_FOREACH( std::string arg, arg_list )
{
if ( arg.find( "numchan=" ) == 0 ) // try to parse global nchan value
{
@@ -140,7 +141,7 @@ inline gr::io_signature::sptr args_to_io_signature( const std::string &args )
// try to parse device specific nchan values, assume 1 channel if none given
- for (std::string arg : arg_list)
+ BOOST_FOREACH( std::string arg, arg_list )
{
dict_t dict = params_to_dict(arg);
if (dict.count("nchan"))
@@ -153,6 +154,8 @@ inline gr::io_signature::sptr args_to_io_signature( const std::string &args )
}
}
+ if (arg_list.size() <= 2 && max_nchan > dev_nchan)
+ dev_nchan = max_nchan;
// if at least one nchan was given, perform a sanity check
if ( max_nchan && dev_nchan && max_nchan != dev_nchan )
throw std::runtime_error("Wrong device arguments specified. Missing nchan?");
diff --git a/lib/bladerf/CMakeLists.txt b/lib/bladerf/CMakeLists.txt
index ea9cf49..c253a22 100644
--- a/lib/bladerf/CMakeLists.txt
+++ b/lib/bladerf/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2013 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,20 +21,20 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${LIBBLADERF_INCLUDE_DIRS}
- ${Volk_INCLUDE_DIRS}
+ ${VOLK_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- ${LIBBLADERF_LIBRARIES}
- ${Volk_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(bladerf_srcs
${CMAKE_CURRENT_SOURCE_DIR}/bladerf_source_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/bladerf_sink_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/bladerf_common.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${bladerf_srcs})
+list(APPEND gr_osmosdr_libs ${LIBBLADERF_LIBRARIES} ${VOLK_LIBRARIES})
diff --git a/lib/bladerf/bladerf_common.cc b/lib/bladerf/bladerf_common.cc
index 67bf736..93b039d 100644
--- a/lib/bladerf/bladerf_common.cc
+++ b/lib/bladerf/bladerf_common.cc
@@ -35,8 +35,10 @@
#include <string>
#include <boost/assign.hpp>
+#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
+#include <boost/weak_ptr.hpp>
#include "bladerf_common.h"
@@ -48,8 +50,8 @@ static size_t const STREAM_TIMEOUT_MS = 3000;
using namespace boost::assign;
-std::mutex bladerf_common::_devs_mutex;
-std::list<std::weak_ptr<struct bladerf>> bladerf_common::_devs;
+boost::mutex bladerf_common::_devs_mutex;
+std::list<boost::weak_ptr<struct bladerf> > bladerf_common::_devs;
/* name for system-wide gain (which is not its own libbladeRF gain stage) */
static const char *SYSTEM_GAIN_NAME = "system";
@@ -133,7 +135,7 @@ size_t num_streams(bladerf_channel_layout layout)
* Public methods
******************************************************************************/
bladerf_common::bladerf_common() :
- _dev(NULL),
+ _dev(boost::shared_ptr<struct bladerf>()),
_pfx("[bladeRF common] "),
_failures(0),
_num_buffers(NUM_BUFFERS),
@@ -497,7 +499,7 @@ int bladerf_common::channel2rfport(bladerf_channel ch)
bladerf_channel bladerf_common::chan2channel(bladerf_direction direction,
size_t chan)
{
- for (bladerf_channel_map::value_type &i : _chanmap) {
+ BOOST_FOREACH(bladerf_channel_map::value_type &i, _chanmap) {
bladerf_channel ch = i.first;
if (
(i.second == (int)chan) && (
@@ -641,7 +643,7 @@ osmosdr::freq_range_t bladerf_common::filter_bandwidths(bladerf_channel ch)
0.75, 0.875, 1.25, 1.375, 1.5, 1.92, 2.5,
2.75, 3, 3.5, 4.375, 5, 6, 7, 10, 14;
- for (double half_bw : half_bandwidths)
+ BOOST_FOREACH( double half_bw, half_bandwidths )
bandwidths += osmosdr::range_t( half_bw * 2e6 );
#else
@@ -1077,7 +1079,7 @@ bladerf_sptr bladerf_common::open(std::string const &device_name)
struct bladerf *raw_dev = NULL;
struct bladerf_devinfo devinfo;
- std::lock_guard<std::mutex> lock(_devs_mutex);
+ boost::unique_lock<boost::mutex> lock(_devs_mutex);
/* Initialize the information used to identify the desired device
* to all wildcard (i.e., "any device") values */
@@ -1107,15 +1109,15 @@ bladerf_sptr bladerf_common::open(std::string const &device_name)
/* Add the device handle to our cache */
bladerf_sptr dev = bladerf_sptr(raw_dev, bladerf_common::close);
- _devs.push_back(static_cast<std::weak_ptr<struct bladerf>>(dev));
+ _devs.push_back(static_cast<boost::weak_ptr<struct bladerf> >(dev));
return dev;
}
void bladerf_common::close(void *dev)
{
- std::lock_guard<std::mutex> lock(_devs_mutex);
- std::list<std::weak_ptr<struct bladerf>>::iterator it(_devs.begin());
+ boost::unique_lock<boost::mutex> lock(_devs_mutex);
+ std::list<boost::weak_ptr<struct bladerf> >::iterator it(_devs.begin());
/* Prune expired entries from device cache */
while (it != _devs.end()) {
@@ -1135,7 +1137,7 @@ bladerf_sptr bladerf_common::get_cached_device(struct bladerf_devinfo devinfo)
int status;
struct bladerf_devinfo other_devinfo;
- for (std::weak_ptr<struct bladerf> dev : _devs) {
+ BOOST_FOREACH(boost::weak_ptr<struct bladerf> dev, _devs) {
status = bladerf_get_devinfo(bladerf_sptr(dev).get(), &other_devinfo);
if (status < 0) {
BLADERF_THROW_STATUS(status, "Failed to get devinfo for cached device");
@@ -1198,7 +1200,7 @@ void bladerf_common::print_device_info()
bool bladerf_common::is_antenna_valid(bladerf_direction dir,
const std::string &antenna)
{
- for (std::string ant : get_antennas(dir)) {
+ BOOST_FOREACH(std::string ant, get_antennas(dir)) {
if (antenna == ant) {
return true;
}
diff --git a/lib/bladerf/bladerf_common.h b/lib/bladerf/bladerf_common.h
index 741b1e7..51dedc9 100644
--- a/lib/bladerf/bladerf_common.h
+++ b/lib/bladerf/bladerf_common.h
@@ -23,11 +23,12 @@
#include <list>
#include <map>
-#include <memory>
-#include <mutex>
#include <string>
#include <vector>
+#include <boost/thread/mutex.hpp>
+#include <boost/weak_ptr.hpp>
+
#include <libbladeRF.h>
#include "osmosdr/ranges.h"
@@ -42,7 +43,7 @@ typedef ptrdiff_t ssize_t;
#define BLADERF_DEBUG_ENABLE
-typedef std::shared_ptr<struct bladerf> bladerf_sptr;
+typedef boost::shared_ptr<struct bladerf> bladerf_sptr;
/* Identification of the bladeRF hardware in use */
typedef enum {
@@ -286,8 +287,8 @@ private:
/*****************************************************************************
* Private members
****************************************************************************/
- static std::mutex _devs_mutex; /**< mutex for access to _devs */
- static std::list<std::weak_ptr<struct bladerf>> _devs; /**< dev cache */
+ static boost::mutex _devs_mutex; /**< mutex for access to _devs */
+ static std::list<boost::weak_ptr<struct bladerf> > _devs; /**< dev cache */
};
#endif
diff --git a/lib/bladerf/bladerf_compat.h b/lib/bladerf/bladerf_compat.h
index 2ad24be..45e6a16 100644
--- a/lib/bladerf/bladerf_compat.h
+++ b/lib/bladerf/bladerf_compat.h
@@ -66,7 +66,7 @@
}
/* Changed enums/defines */
- #define BLADERF_GAIN_DEFAULT BLADERF_GAIN_AUTOMATIC
+ #define BLADERF_GAIN_DEFAULT BLADERF_GAIN_MANUAL
#define BLADERF_GAIN_MGC BLADERF_GAIN_MANUAL
#define BLADERF_RX_MUX_BASEBAND BLADERF_RX_MUX_BASEBAND_LMS
diff --git a/lib/bladerf/bladerf_sink_c.cc b/lib/bladerf/bladerf_sink_c.cc
index 6ee3acd..d3d607b 100644
--- a/lib/bladerf/bladerf_sink_c.cc
+++ b/lib/bladerf/bladerf_sink_c.cc
@@ -96,7 +96,7 @@ bladerf_sink_c::bladerf_sink_c(const std::string &args) :
}
/* Initialize channel <-> antenna map */
- for (std::string ant : get_antennas()) {
+ BOOST_FOREACH(std::string ant, get_antennas()) {
_chanmap[str2channel(ant)] = -1;
}
@@ -174,11 +174,9 @@ bool bladerf_sink_c::start()
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
bladerf_channel brfch = BLADERF_CHANNEL_TX(ch);
- if (get_channel_enable(brfch)) {
- status = bladerf_enable_module(_dev.get(), brfch, true);
- if (status != 0) {
- BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
- }
+ status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
+ if (status != 0) {
+ BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
}
@@ -210,11 +208,9 @@ bool bladerf_sink_c::stop()
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
bladerf_channel brfch = BLADERF_CHANNEL_TX(ch);
- if (get_channel_enable(brfch)) {
- status = bladerf_enable_module(_dev.get(), brfch, false);
- if (status != 0) {
- BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
- }
+ status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
+ if (status != 0) {
+ BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
}
@@ -241,6 +237,11 @@ int bladerf_sink_c::work(int noutput_items,
return 0;
}
+ noutput_items &= ~(3ULL);
+ if (!noutput_items) {
+ return 0;
+ }
+
// copy the samples from input_items
gr_complex const **in = reinterpret_cast<gr_complex const **>(&input_items[0]);
@@ -329,7 +330,7 @@ int bladerf_sink_c::transmit_with_tags(int16_t const *samples,
}
}
- for (gr::tag_t tag : tags) {
+ BOOST_FOREACH(gr::tag_t tag, tags) {
// Upon seeing an SOB tag, update our offset. We'll TX the start of the
// burst when we see an EOB or at the end of this function - whichever
// occurs first.
diff --git a/lib/bladerf/bladerf_source_c.cc b/lib/bladerf/bladerf_source_c.cc
index 83db677..e37bd67 100644
--- a/lib/bladerf/bladerf_source_c.cc
+++ b/lib/bladerf/bladerf_source_c.cc
@@ -144,7 +144,7 @@ bladerf_source_c::bladerf_source_c(const std::string &args) :
}
/* Initialize channel <-> antenna map */
- for (std::string ant : get_antennas()) {
+ BOOST_FOREACH(std::string ant, get_antennas()) {
_chanmap[str2channel(ant)] = -1;
}
@@ -180,7 +180,7 @@ bladerf_source_c::bladerf_source_c(const std::string &args) :
bool bladerf_source_c::is_antenna_valid(const std::string &antenna)
{
- for (std::string ant : get_antennas()) {
+ BOOST_FOREACH(std::string ant, get_antennas()) {
if (antenna == ant) {
return true;
}
@@ -230,11 +230,9 @@ bool bladerf_source_c::start()
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
bladerf_channel brfch = BLADERF_CHANNEL_RX(ch);
- if (get_channel_enable(brfch)) {
- status = bladerf_enable_module(_dev.get(), brfch, true);
- if (status != 0) {
- BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
- }
+ status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
+ if (status != 0) {
+ BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
}
@@ -344,7 +342,7 @@ int bladerf_source_c::work(int noutput_items,
memcpy(out[0], _32fcbuf, sizeof(gr_complex) * noutput_items);
}
- return noutput_items;
+ return noutput_items/(get_num_channels());
}
osmosdr::meta_range_t bladerf_source_c::get_sample_rates()
diff --git a/lib/config.h.in b/lib/config.h.in
index d96cd80..42e72f1 100644
--- a/lib/config.h.in
+++ b/lib/config.h.in
@@ -4,21 +4,21 @@
#define GR_OSMOSDR_VERSION "@VERSION@"
#define GR_OSMOSDR_LIBVER "@LIBVER@"
+#cmakedefine ENABLE_OSMOSDR
#cmakedefine ENABLE_FCD
#cmakedefine ENABLE_FILE
#cmakedefine ENABLE_RTL
#cmakedefine ENABLE_RTL_TCP
#cmakedefine ENABLE_UHD
+#cmakedefine ENABLE_MIRI
#cmakedefine ENABLE_SDRPLAY
#cmakedefine ENABLE_HACKRF
#cmakedefine ENABLE_BLADERF
#cmakedefine ENABLE_RFSPACE
#cmakedefine ENABLE_AIRSPY
-#cmakedefine ENABLE_AIRSPYHF
#cmakedefine ENABLE_SOAPY
#cmakedefine ENABLE_REDPITAYA
#cmakedefine ENABLE_FREESRP
-#cmakedefine ENABLE_XTRX
//provide NAN define for MSVC older than VC12
#if defined(_MSC_VER) && (_MSC_VER < 1800)
diff --git a/lib/device.cc b/lib/device.cc
index d072e27..025a22b 100644
--- a/lib/device.cc
+++ b/lib/device.cc
@@ -20,15 +20,20 @@
#include <osmosdr/device.h>
#include <stdexcept>
+#include <boost/foreach.hpp>
#include <boost/format.hpp>
+#include <boost/thread/mutex.hpp>
#include <algorithm>
-#include <mutex>
#include <sstream>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#ifdef ENABLE_OSMOSDR
+#include <osmosdr_src_c.h>
+#endif
+
#ifdef ENABLE_FCD
#include <fcd_source_c.h>
#endif
@@ -49,6 +54,10 @@
#include <uhd_source_c.h>
#endif
+#ifdef ENABLE_MIRI
+#include <miri_source_c.h>
+#endif
+
#ifdef ENABLE_SDRPLAY
#include <sdrplay_source_c.h>
#endif
@@ -69,10 +78,6 @@
#include <airspy_source_c.h>
#endif
-#ifdef ENABLE_AIRSPYHF
-#include <airspyhf_source_c.h>
-#endif
-
#ifdef ENABLE_SOAPY
#include <soapy_source_c.h>
#endif
@@ -93,13 +98,13 @@ static const std::string args_delim = " ";
static const std::string pairs_delim = ",";
static const std::string pair_delim = "=";
-static std::mutex _device_mutex;
+static boost::mutex _device_mutex;
device_t::device_t(const std::string &args)
{
dict_t dict = params_to_dict(args);
- for (dict_t::value_type &entry : dict)
+ BOOST_FOREACH( dict_t::value_type &entry, dict )
(*this)[entry.first] = entry.second;
}
@@ -109,7 +114,7 @@ std::string device_t::to_pp_string(void) const
std::stringstream ss;
ss << "Device Address:" << std::endl;
- for (const device_t::value_type &entry : *this) {
+ BOOST_FOREACH(const device_t::value_type &entry, *this) {
ss << boost::format(" %s: %s") % entry.first % entry.second << std::endl;
}
return ss.str();
@@ -119,7 +124,7 @@ std::string device_t::to_string(void) const
{
std::stringstream ss;
size_t count = 0;
- for (const device_t::value_type &entry : *this) {
+ BOOST_FOREACH(const device_t::value_type &entry, *this) {
std::string value = entry.second;
if (value.find(" ") != std::string::npos)
value = "'" + value + "'";
@@ -132,7 +137,7 @@ std::string device_t::to_string(void) const
devices_t device::find(const device_t &hint)
{
- std::lock_guard<std::mutex> lock(_device_mutex);
+ boost::mutex::scoped_lock lock(_device_mutex);
bool fake = true;
@@ -141,48 +146,52 @@ devices_t device::find(const device_t &hint)
devices_t devices;
+#ifdef ENABLE_OSMOSDR
+ BOOST_FOREACH( std::string dev, osmosdr_src_c::get_devices() )
+ devices.push_back( device_t(dev) );
+#endif
#ifdef ENABLE_FCD
- for (std::string dev : fcd_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, fcd_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_RTL
- for (std::string dev : rtl_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, rtl_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_UHD
- for (std::string dev : uhd_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
+ devices.push_back( device_t(dev) );
+#endif
+#ifdef ENABLE_MIRI
+ BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_SDRPLAY
- for (std::string dev : sdrplay_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, sdrplay_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_BLADERF
- for (std::string dev : bladerf_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, bladerf_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_HACKRF
- for (std::string dev : hackrf_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, hackrf_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_RFSPACE
- for (std::string dev : rfspace_source_c::get_devices( fake ))
+ BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices( fake ) )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_AIRSPY
- for (std::string dev : airspy_source_c::get_devices())
- devices.push_back( device_t(dev) );
-#endif
-#ifdef ENABLE_AIRSPYHF
- for (std::string dev : airspyhf_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, airspy_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_FREESRP
- for (std::string dev : freesrp_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, freesrp_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_SOAPY
- for (std::string dev : soapy_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, soapy_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
@@ -191,15 +200,15 @@ devices_t device::find(const device_t &hint)
* in a graphical interface etc... */
#ifdef ENABLE_RTL_TCP
- for (std::string dev : rtl_tcp_source_c::get_devices( fake ))
+ BOOST_FOREACH( std::string dev, rtl_tcp_source_c::get_devices( fake ) )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_REDPITAYA
- for (std::string dev : redpitaya_source_c::get_devices( fake ))
+ BOOST_FOREACH( std::string dev, redpitaya_source_c::get_devices( fake ) )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_FILE
- for (std::string dev : file_source_c::get_devices( fake ))
+ BOOST_FOREACH( std::string dev, file_source_c::get_devices( fake ) )
devices.push_back( device_t(dev) );
#endif
diff --git a/lib/fcd/CMakeLists.txt b/lib/fcd/CMakeLists.txt
index 768c5b2..e71b153 100644
--- a/lib/fcd/CMakeLists.txt
+++ b/lib/fcd/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,16 +21,29 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${GNURADIO_FCDPP_INCLUDE_DIRS}
-)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-APPEND_LIB_LIST(
- ${GNURADIO_FCDPP_LIBRARIES}
-)
+if(ENABLE_FCD)
+include_directories(${GNURADIO_FCD_INCLUDE_DIRS})
+endif(ENABLE_FCD)
-list(APPEND gr_osmosdr_srcs
+if(ENABLE_FCDPP)
+include_directories(${GNURADIO_FCDPP_INCLUDE_DIRS})
+endif(ENABLE_FCDPP)
+
+set(fcd_srcs
${CMAKE_CURRENT_SOURCE_DIR}/fcd_source_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${fcd_srcs})
+
+if(ENABLE_FCD)
+list(APPEND gr_osmosdr_libs ${GNURADIO_FCD_LIBRARIES})
+endif(ENABLE_FCD)
+
+if(ENABLE_FCDPP)
+list(APPEND gr_osmosdr_libs ${GNURADIO_FCDPP_LIBRARIES})
+endif(ENABLE_FCDPP)
diff --git a/lib/fcd/fcd_source_c.cc b/lib/fcd/fcd_source_c.cc
index 854e4c0..885d514 100644
--- a/lib/fcd/fcd_source_c.cc
+++ b/lib/fcd/fcd_source_c.cc
@@ -23,6 +23,7 @@
#include <sstream>
#include <boost/assign.hpp>
+#include <boost/foreach.hpp>
#include <gnuradio/io_signature.h>
@@ -141,15 +142,18 @@ fcd_source_c::fcd_source_c(const std::string &args) :
std::cerr << "Using " << name() << " (" << dev_name << ")" << std::endl;
+#ifdef HAVE_FCD
if ( FUNCUBE_V1 == _type )
{
- _src_v1 = gr::fcdproplus::fcd::make( dev_name );
+ _src_v1 = gr::fcd::source_c::make( dev_name );
connect( _src_v1, 0, self(), 0 );
set_gain( 20, "LNA" );
set_gain( 12, "MIX" );
}
+#endif
+#ifdef HAVE_FCDPP
if ( FUNCUBE_V2 == _type )
{
_src_v2 = gr::fcdproplus::fcdproplus::make( dev_name );
@@ -159,6 +163,7 @@ fcd_source_c::fcd_source_c(const std::string &args) :
set_gain( 1, "MIX" );
set_gain( 15, "BB" );
}
+#endif
}
fcd_source_c::~fcd_source_c()
@@ -170,7 +175,7 @@ std::vector< std::string > fcd_source_c::get_devices()
int id = 0;
std::vector< std::string > devices;
- for (device_t dev : _get_devices())
+ BOOST_FOREACH( device_t dev, _get_devices() )
{
std::string args = "fcd=" + boost::lexical_cast< std::string >( id++ );
@@ -236,11 +241,15 @@ osmosdr::freq_range_t fcd_source_c::get_freq_range( size_t chan )
double fcd_source_c::set_center_freq( double freq, size_t chan )
{
+#ifdef HAVE_FCD
if ( FUNCUBE_V1 == _type )
_src_v1->set_freq( float(freq) );
+#endif
+#ifdef HAVE_FCDPP
if ( FUNCUBE_V2 == _type )
_src_v2->set_freq( float(freq) );
+#endif
_freq = freq;
@@ -254,11 +263,15 @@ double fcd_source_c::get_center_freq( size_t chan )
double fcd_source_c::set_freq_corr( double ppm, size_t chan )
{
+#ifdef HAVE_FCD
if ( FUNCUBE_V1 == _type )
_src_v1->set_freq_corr( ppm );
+#endif
+#ifdef HAVE_FCDPP
if ( FUNCUBE_V2 == _type )
_src_v2->set_freq_corr( ppm );
+#endif
_correct = ppm;
@@ -330,6 +343,7 @@ double fcd_source_c::set_gain( double gain, size_t chan )
double fcd_source_c::set_gain( double gain, const std::string & name, size_t chan )
{
+#ifdef HAVE_FCD
if ( FUNCUBE_V1 == _type )
{
if ( "LNA" == name )
@@ -343,7 +357,9 @@ double fcd_source_c::set_gain( double gain, const std::string & name, size_t cha
_src_v1->set_mixer_gain(_mix_gain);
}
}
+#endif
+#ifdef HAVE_FCDPP
if ( FUNCUBE_V2 == _type )
{
if ( "LNA" == name )
@@ -362,6 +378,7 @@ double fcd_source_c::set_gain( double gain, const std::string & name, size_t cha
_src_v2->set_if_gain(_bb_gain);
}
}
+#endif
return get_gain( name, chan );
}
diff --git a/lib/fcd/fcd_source_c.h b/lib/fcd/fcd_source_c.h
index 2b02eb1..70239f8 100644
--- a/lib/fcd/fcd_source_c.h
+++ b/lib/fcd/fcd_source_c.h
@@ -22,8 +22,13 @@
#include <gnuradio/hier_block2.h>
-#include <fcdproplus/fcd.h>
+#ifdef HAVE_FCD
+#include <gnuradio/fcd/source_c.h>
+#endif
+
+#ifdef HAVE_FCDPP
#include <fcdproplus/fcdproplus.h>
+#endif
#include "source_iface.h"
@@ -81,8 +86,12 @@ public:
private:
dongle_type _type;
- gr::fcdproplus::fcd::sptr _src_v1;
+#ifdef HAVE_FCD
+ gr::fcd::source_c::sptr _src_v1;
+#endif
+#ifdef HAVE_FCDPP
gr::fcdproplus::fcdproplus::sptr _src_v2;
+#endif
double _lna_gain, _mix_gain, _bb_gain, _freq;
int _correct;
};
diff --git a/lib/file/CMakeLists.txt b/lib/file/CMakeLists.txt
index c96632d..6c55e85 100644
--- a/lib/file/CMakeLists.txt
+++ b/lib/file/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,17 +21,18 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
-APPEND_LIB_LIST(
- gnuradio::gnuradio-blocks
-)
-message(STATUS ${gnuradio-blocks_LIBRARIES})
-
-list(APPEND gr_osmosdr_srcs
+set(file_srcs
${CMAKE_CURRENT_SOURCE_DIR}/file_source_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/file_sink_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${file_srcs})
+#list(APPEND gr_osmosdr_libs ${GNURADIO_BLOCKS_LIBRARIES})
+
diff --git a/lib/freesrp/CMakeLists.txt b/lib/freesrp/CMakeLists.txt
index aca0d8c..46df7e4 100644
--- a/lib/freesrp/CMakeLists.txt
+++ b/lib/freesrp/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,18 +21,19 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${LIBFREESRP_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- ${LIBFREESRP_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(freesrp_srcs
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_common.cc
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_source_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_sink_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${freesrp_srcs})
+list(APPEND gr_osmosdr_libs ${LIBFREESRP_LIBRARIES})
diff --git a/lib/freesrp/freesrp_common.cc b/lib/freesrp/freesrp_common.cc
index 57bbdbb..d60fbb8 100644
--- a/lib/freesrp/freesrp_common.cc
+++ b/lib/freesrp/freesrp_common.cc
@@ -2,6 +2,7 @@
#include <cstdlib>
+#include <boost/make_shared.hpp>
#include <boost/assign.hpp>
#include <arg_helpers.h>
@@ -10,7 +11,7 @@ using namespace FreeSRP;
using namespace std;
using namespace boost::assign;
-std::shared_ptr<::FreeSRP::FreeSRP> freesrp_common::_srp;
+boost::shared_ptr<::FreeSRP::FreeSRP> freesrp_common::_srp;
freesrp_common::freesrp_common(const string &args)
{
diff --git a/lib/freesrp/freesrp_common.h b/lib/freesrp/freesrp_common.h
index 8d13c47..9a5687c 100644
--- a/lib/freesrp/freesrp_common.h
+++ b/lib/freesrp/freesrp_common.h
@@ -1,7 +1,6 @@
#ifndef INCLUDED_FREESRP_COMMON_H
#define INCLUDED_FREESRP_COMMON_H
-#include <memory>
#include <vector>
#include <string>
@@ -23,7 +22,7 @@ public:
double set_freq_corr( double ppm, size_t chan = 0 );
double get_freq_corr( size_t chan = 0 );
protected:
- static std::shared_ptr<::FreeSRP::FreeSRP> _srp;
+ static boost::shared_ptr<::FreeSRP::FreeSRP> _srp;
bool _ignore_overflow = false;
};
diff --git a/lib/gnuradio-osmosdr.rc.in b/lib/gnuradio-osmosdr.rc.in
new file mode 100644
index 0000000..62fd5ea
--- /dev/null
+++ b/lib/gnuradio-osmosdr.rc.in
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <afxres.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@
+ PRODUCTVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@
+ FILEFLAGSMASK 0x3fL
+#ifndef NDEBUG
+ FILEFLAGS 0x0L
+#else
+ FILEFLAGS 0x1L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_DRV_INSTALLABLE
+ BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "gnuradio-osmosdr"
+ VALUE "FileVersion", "@VERSION@"
+ VALUE "InternalName", "gnuradio-osmosdr.dll"
+ VALUE "LegalCopyright", "Licensed under GPLv3 or any later version"
+ VALUE "OriginalFilename", "gnuradio-osmosdr.dll"
+ VALUE "ProductName", "gnuradio-osmosdr"
+ VALUE "ProductVersion", "@VERSION@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+ END
diff --git a/lib/hackrf/CMakeLists.txt b/lib/hackrf/CMakeLists.txt
index a0ec70a..c7af0c9 100644
--- a/lib/hackrf/CMakeLists.txt
+++ b/lib/hackrf/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,18 +21,27 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${LIBHACKRF_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- ${LIBHACKRF_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
- ${CMAKE_CURRENT_SOURCE_DIR}/hackrf_common.cc
+set(hackrf_srcs
${CMAKE_CURRENT_SOURCE_DIR}/hackrf_source_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/hackrf_sink_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+INCLUDE(CheckFunctionExists)
+set(CMAKE_REQUIRED_LIBRARIES ${LIBHACKRF_LIBRARIES})
+CHECK_FUNCTION_EXISTS(hackrf_device_list LIBHACKRF_HAVE_DEVICE_LIST)
+
+if(LIBHACKRF_HAVE_DEVICE_LIST)
+ message(STATUS "HackRF multiple device support enabled")
+ add_definitions(-DLIBHACKRF_HAVE_DEVICE_LIST)
+endif(LIBHACKRF_HAVE_DEVICE_LIST)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${hackrf_srcs})
+list(APPEND gr_osmosdr_libs ${LIBHACKRF_LIBRARIES})
diff --git a/lib/hackrf/hackrf_common.cc b/lib/hackrf/hackrf_common.cc
deleted file mode 100644
index 666dc60..0000000
--- a/lib/hackrf/hackrf_common.cc
+++ /dev/null
@@ -1,427 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2020 Clayton Smith <argilo@gmail.com>
- *
- * gr-osmosdr is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * gr-osmosdr is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with gr-osmosdr; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "hackrf_common.h"
-
-#include "arg_helpers.h"
-
-int hackrf_common::_usage = 0;
-std::mutex hackrf_common::_usage_mutex;
-
-std::map<std::string, std::weak_ptr<hackrf_device>> hackrf_common::_devs;
-std::mutex hackrf_common::_devs_mutex;
-
-hackrf_common::hackrf_common(const std::string &args) :
- _dev(NULL),
- _sample_rate(0),
- _center_freq(0),
- _freq_corr(0),
- _auto_gain(false),
- _requested_bandwidth(0),
- _bandwidth(0),
- _bias(false),
- _started(false)
-{
- int ret;
- hackrf_device *raw_dev;
- hackrf_device_list_t *list;
- int dev_index;
- std::string target_serial = "0";
- std::string final_serial = "";
-
- dict_t dict = params_to_dict(args);
- if (dict.count("hackrf") > 0 && dict["hackrf"].length() > 0) {
- target_serial = dict["hackrf"];
- }
-
- {
- std::lock_guard<std::mutex> guard(_usage_mutex);
-
- if (_usage == 0) {
- hackrf_init(); /* call only once before the first open */
- }
-
- _usage++;
- }
-
- list = hackrf_device_list();
-
- if (target_serial.length() > 1) {
- for (dev_index = 0; dev_index < list->devicecount; dev_index++) {
- if (list->serial_numbers[dev_index]) {
- std::string serial(list->serial_numbers[dev_index]);
- if (serial.compare(serial.length() - target_serial.length(),
- target_serial.length(), target_serial) == 0) {
- break;
- }
- }
- }
-
- if (dev_index >= list->devicecount) {
- hackrf_device_list_free(list);
- throw std::runtime_error(
- "No device found with serial number '" + target_serial + "'");
- }
- } else {
- try {
- dev_index = std::stoi(target_serial);
- } catch (std::exception &ex) {
- hackrf_device_list_free(list);
- throw std::runtime_error(
- "Failed to use '" + target_serial + "' as HackRF device index number");
- }
-
- if (dev_index >= list->devicecount) {
- hackrf_device_list_free(list);
- throw std::runtime_error(
- "Failed to use '" + target_serial + "' as HackRF device index: not enough devices");
- }
- }
-
- if (list->serial_numbers[dev_index]) {
- final_serial = list->serial_numbers[dev_index];
- }
-
- {
- std::lock_guard<std::mutex> guard(_devs_mutex);
-
- if (_devs.count(final_serial) > 0 && !_devs[final_serial].expired()) {
- _dev = hackrf_sptr(_devs[final_serial]);
- } else {
- ret = hackrf_device_list_open(list, dev_index, &raw_dev);
- HACKRF_THROW_ON_ERROR(ret, "Failed to open HackRF device")
- _dev = hackrf_sptr(raw_dev, hackrf_common::close);
- _devs[final_serial] = static_cast<std::weak_ptr<struct hackrf_device>>(_dev);
- }
- }
-
- hackrf_device_list_free(list);
-
- uint8_t board_id;
- ret = hackrf_board_id_read(_dev.get(), &board_id);
- HACKRF_THROW_ON_ERROR(ret, "Failed to get HackRF board id")
-
- char version[40];
- memset(version, 0, sizeof(version));
- ret = hackrf_version_string_read(_dev.get(), version, sizeof(version));
- HACKRF_THROW_ON_ERROR(ret, "Failed to read version string")
-
- std::cerr << "Using " << hackrf_board_id_name(hackrf_board_id(board_id)) << " "
- << "with firmware " << version
- << std::endl;
-}
-
-void hackrf_common::close(void *dev)
-{
- int ret = hackrf_close(static_cast<hackrf_device *>(dev));
- if (ret != HACKRF_SUCCESS)
- {
- std::cerr << HACKRF_FORMAT_ERROR(ret, "Failed to close HackRF") << std::endl;
- }
-
- {
- std::lock_guard<std::mutex> guard(_usage_mutex);
-
- _usage--;
-
- if (_usage == 0) {
- hackrf_exit(); /* call only once after last close */
- }
- }
-}
-
-std::vector<std::string> hackrf_common::get_devices()
-{
- std::vector<std::string> devices;
- std::string label;
-
- {
- std::lock_guard<std::mutex> guard(_usage_mutex);
-
- if (_usage == 0) {
- hackrf_init(); /* call only once before the first open */
- }
-
- _usage++;
- }
-
- hackrf_device_list_t *list = hackrf_device_list();
-
- for (int i = 0; i < list->devicecount; i++) {
- label = "HackRF ";
- label += hackrf_usb_board_id_name(list->usb_board_ids[i]);
-
- std::string args;
- if (list->serial_numbers[i]) {
- std::string serial(list->serial_numbers[i]);
- if (serial.length() > 6)
- serial = serial.substr(serial.length() - 6, 6);
- args = "hackrf=" + serial;
- if (serial.length() )
- label += " " + serial;
- } else {
- args = "hackrf"; /* will pick the first one, serial number is required for choosing a specific one */
- }
-
- args += ",label='" + label + "'";
- devices.push_back(args);
- }
-
- hackrf_device_list_free(list);
-
- {
- std::lock_guard<std::mutex> guard(_usage_mutex);
-
- _usage--;
-
- if (_usage == 0) {
- hackrf_exit(); /* call only once after last close */
- }
- }
-
- return devices;
-}
-
-osmosdr::meta_range_t hackrf_common::get_sample_rates()
-{
- osmosdr::meta_range_t range;
-
- /* we only add integer rates here because of better phase noise performance.
- * the user is allowed to request arbitrary (fractional) rates within these
- * boundaries. */
-
- range.push_back(osmosdr::range_t( 8e6 ));
- range.push_back(osmosdr::range_t( 10e6 ));
- range.push_back(osmosdr::range_t( 12.5e6 ));
- range.push_back(osmosdr::range_t( 16e6 ));
- range.push_back(osmosdr::range_t( 20e6 )); /* confirmed to work on fast machines */
-
- return range;
-}
-
-double hackrf_common::set_sample_rate( double rate )
-{
- int ret;
-
- if (_dev.get() && _started) {
- ret = hackrf_set_sample_rate( _dev.get(), rate );
- if ( HACKRF_SUCCESS != ret ) {
- HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_sample_rate", rate ) )
- }
- }
-
- _sample_rate = rate;
- return get_sample_rate();
-}
-
-double hackrf_common::get_sample_rate()
-{
- return _sample_rate;
-}
-
-osmosdr::freq_range_t hackrf_common::get_freq_range( size_t chan )
-{
- osmosdr::freq_range_t range;
-
- range.push_back(osmosdr::range_t( _sample_rate / 2, 7250e6 - _sample_rate / 2 ));
-
- return range;
-}
-
-double hackrf_common::set_center_freq( double freq, size_t chan )
-{
- int ret;
-
- #define APPLY_PPM_CORR(val, ppm) ((val) * (1.0 + (ppm) * 0.000001))
-
- if (_dev.get() && _started) {
- double corr_freq = APPLY_PPM_CORR( freq, _freq_corr );
- ret = hackrf_set_freq( _dev.get(), uint64_t(corr_freq) );
- if ( HACKRF_SUCCESS != ret ) {
- HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_freq", corr_freq ) )
- }
- }
-
- _center_freq = freq;
- return get_center_freq( chan );
-}
-
-double hackrf_common::get_center_freq( size_t chan )
-{
- return _center_freq;
-}
-
-double hackrf_common::set_freq_corr( double ppm, size_t chan )
-{
- _freq_corr = ppm;
-
- set_center_freq( _center_freq );
-
- return get_freq_corr( chan );
-}
-
-double hackrf_common::get_freq_corr( size_t chan )
-{
- return _freq_corr;
-}
-
-bool hackrf_common::set_gain_mode( bool automatic, size_t chan )
-{
- _auto_gain = automatic;
-
- return get_gain_mode(chan);
-}
-
-bool hackrf_common::get_gain_mode( size_t chan )
-{
- return _auto_gain;
-}
-
-double hackrf_common::set_gain( double gain, size_t chan )
-{
- int ret;
- double clip_gain = (gain >= 14.0) ? 14.0 : 0.0;
-
- if (_dev.get() && _started) {
- uint8_t value = (clip_gain == 14.0) ? 1 : 0;
-
- ret = hackrf_set_amp_enable( _dev.get(), value );
- if ( HACKRF_SUCCESS != ret ) {
- HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_amp_enable", value ) )
- }
- }
-
- _amp_gain = clip_gain;
- return hackrf_common::get_gain(chan);
-}
-
-double hackrf_common::get_gain( size_t chan )
-{
- return _amp_gain;
-}
-
-std::vector< std::string > hackrf_common::get_antennas( size_t chan )
-{
- return { get_antenna( chan ) };
-}
-
-std::string hackrf_common::set_antenna( const std::string & antenna, size_t chan )
-{
- return get_antenna( chan );
-}
-
-std::string hackrf_common::get_antenna( size_t chan )
-{
- return "TX/RX";
-}
-
-double hackrf_common::set_bandwidth( double bandwidth, size_t chan )
-{
- int ret;
-// osmosdr::freq_range_t bandwidths = get_bandwidth_range( chan );
-
- _requested_bandwidth = bandwidth;
- if ( bandwidth == 0.0 ) /* bandwidth of 0 means automatic filter selection */
- bandwidth = _sample_rate * 0.75; /* select narrower filters to prevent aliasing */
-
- /* compute best default value depending on sample rate (auto filter) */
- uint32_t bw = hackrf_compute_baseband_filter_bw( uint32_t(bandwidth) );
-
- if (_dev.get() && _started) {
- ret = hackrf_set_baseband_filter_bandwidth( _dev.get(), bw );
- if (HACKRF_SUCCESS != ret) {
- HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_baseband_filter_bandwidth", bw ) )
- }
- }
-
- _bandwidth = bw;
- return get_bandwidth(chan);
-}
-
-double hackrf_common::get_bandwidth( size_t chan )
-{
- return _bandwidth;
-}
-
-osmosdr::freq_range_t hackrf_common::get_bandwidth_range( size_t chan )
-{
- osmosdr::freq_range_t bandwidths;
-
- // TODO: read out from libhackrf when an API is available
-
- bandwidths.push_back(osmosdr::range_t( 1750000 ));
- bandwidths.push_back(osmosdr::range_t( 2500000 ));
- bandwidths.push_back(osmosdr::range_t( 3500000 ));
- bandwidths.push_back(osmosdr::range_t( 5000000 ));
- bandwidths.push_back(osmosdr::range_t( 5500000 ));
- bandwidths.push_back(osmosdr::range_t( 6000000 ));
- bandwidths.push_back(osmosdr::range_t( 7000000 ));
- bandwidths.push_back(osmosdr::range_t( 8000000 ));
- bandwidths.push_back(osmosdr::range_t( 9000000 ));
- bandwidths.push_back(osmosdr::range_t( 10000000 ));
- bandwidths.push_back(osmosdr::range_t( 12000000 ));
- bandwidths.push_back(osmosdr::range_t( 14000000 ));
- bandwidths.push_back(osmosdr::range_t( 15000000 ));
- bandwidths.push_back(osmosdr::range_t( 20000000 ));
- bandwidths.push_back(osmosdr::range_t( 24000000 ));
- bandwidths.push_back(osmosdr::range_t( 28000000 ));
-
- return bandwidths;
-}
-
-bool hackrf_common::set_bias( bool bias )
-{
- int ret;
-
- if (_dev.get() && _started) {
- ret = hackrf_set_antenna_enable(_dev.get(), static_cast<uint8_t>(bias));
- if (ret != HACKRF_SUCCESS)
- {
- std::cerr << "Failed to apply antenna bias voltage state: " << bias << HACKRF_FORMAT_ERROR(ret, "") << std::endl;
- }
- }
-
- _bias = bias;
- return get_bias();
-}
-
-bool hackrf_common::get_bias()
-{
- return _bias;
-}
-
-void hackrf_common::start()
-{
- _started = true;
- set_center_freq(get_center_freq());
- set_sample_rate(get_sample_rate());
- if (_requested_bandwidth != 0)
- set_bandwidth(get_bandwidth());
- set_gain(get_gain());
- set_bias(get_bias());
-}
-
-void hackrf_common::stop()
-{
- _started = false;
-}
diff --git a/lib/hackrf/hackrf_common.h b/lib/hackrf/hackrf_common.h
deleted file mode 100644
index d1ab47b..0000000
--- a/lib/hackrf/hackrf_common.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2020 Clayton Smith <argilo@gmail.com>
- *
- * gr-osmosdr is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * gr-osmosdr is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with gr-osmosdr; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef INCLUDED_HACKRF_COMMON_H
-#define INCLUDED_HACKRF_COMMON_H
-
-#include <map>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <vector>
-
-#include <boost/format.hpp>
-
-#include <osmosdr/ranges.h>
-#include <libhackrf/hackrf.h>
-
-#define BUF_LEN (16 * 32 * 512) /* must be multiple of 512 */
-#define BUF_NUM 15
-
-#define BYTES_PER_SAMPLE 2 /* HackRF device produces/consumes 8 bit signed IQ data */
-
-#define HACKRF_FORMAT_ERROR(ret, msg) \
- boost::str( boost::format(msg " (%1%) %2%") \
- % ret % hackrf_error_name((enum hackrf_error)ret) )
-
-#define HACKRF_THROW_ON_ERROR(ret, msg) \
- if ( ret != HACKRF_SUCCESS ) \
- { \
- throw std::runtime_error( HACKRF_FORMAT_ERROR(ret, msg) ); \
- }
-
-#define HACKRF_FUNC_STR(func, arg) \
- boost::str(boost::format(func "(%1%)") % arg) + " has failed"
-
-typedef std::shared_ptr<hackrf_device> hackrf_sptr;
-
-class hackrf_common
-{
-public:
- hackrf_common(const std::string &args);
-
-protected:
- static std::vector< std::string > get_devices();
-
- osmosdr::meta_range_t get_sample_rates( void );
- double set_sample_rate( double rate );
- double get_sample_rate( void );
-
- osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
- double set_center_freq( double freq, size_t chan = 0 );
- double get_center_freq( size_t chan = 0 );
- double set_freq_corr( double ppm, size_t chan = 0 );
- double get_freq_corr( size_t chan = 0 );
-
- bool set_gain_mode( bool automatic, size_t chan = 0 );
- bool get_gain_mode( size_t chan = 0 );
- double set_gain( double gain, size_t chan = 0 );
- double get_gain( size_t chan = 0 );
-
- std::vector< std::string > get_antennas( size_t chan = 0 );
- std::string set_antenna( const std::string & antenna, size_t chan = 0 );
- std::string get_antenna( size_t chan = 0 );
-
- double set_bandwidth( double bandwidth, size_t chan = 0 );
- double get_bandwidth( size_t chan = 0 );
- osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 );
-
- bool set_bias( bool bias );
- bool get_bias();
-
- void start();
- void stop();
-
- hackrf_sptr _dev;
-
-private:
- static void close(void *dev);
-
- static int _usage;
- static std::mutex _usage_mutex;
-
- static std::map<std::string, std::weak_ptr<hackrf_device>> _devs;
- static std::mutex _devs_mutex;
-
- double _sample_rate;
- double _center_freq;
- double _freq_corr;
- bool _auto_gain;
- double _amp_gain;
- double _requested_bandwidth;
- double _bandwidth;
- bool _bias;
- bool _started;
-};
-
-#endif /* INCLUDED_HACKRF_COMMON_H */
diff --git a/lib/hackrf/hackrf_sink_c.cc b/lib/hackrf/hackrf_sink_c.cc
index 1762934..ee089c6 100644
--- a/lib/hackrf/hackrf_sink_c.cc
+++ b/lib/hackrf/hackrf_sink_c.cc
@@ -2,20 +2,19 @@
/*
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
* Copyright 2014 Hoernchen <la@tfc-server.de>
- * Copyright 2020 Clayton Smith <argilo@gmail.com>
*
- * gr-osmosdr is free software; you can redistribute it and/or modify
+ * GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
- * gr-osmosdr is distributed in the hope that it will be useful,
+ * GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with gr-osmosdr; see the file COPYING. If not, write to
+ * along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
@@ -38,12 +37,38 @@
#include <emmintrin.h>
#endif
+#include <boost/assign.hpp>
+#include <boost/format.hpp>
+#include <boost/detail/endian.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/thread/thread.hpp>
+
#include <gnuradio/io_signature.h>
#include "hackrf_sink_c.h"
#include "arg_helpers.h"
+using namespace boost::assign;
+
+#define BUF_LEN (16 * 32 * 512) /* must be multiple of 512 */
+#define BUF_NUM 15
+
+#define BYTES_PER_SAMPLE 2 /* HackRF device consumes 8 bit unsigned IQ data */
+
+#define HACKRF_FORMAT_ERROR(ret, msg) \
+ boost::str( boost::format(msg " (%1%) %2%") \
+ % ret % hackrf_error_name((enum hackrf_error)ret) )
+
+#define HACKRF_THROW_ON_ERROR(ret, msg) \
+ if ( ret != HACKRF_SUCCESS ) \
+ { \
+ throw std::runtime_error( HACKRF_FORMAT_ERROR(ret, msg) ); \
+ }
+
+#define HACKRF_FUNC_STR(func, arg) \
+ boost::str(boost::format(func "(%1%)") % arg) + " has failed"
+
static inline bool cb_init(circular_buffer_t *cb, size_t capacity, size_t sz)
{
cb->buffer = malloc(capacity * sz);
@@ -78,11 +103,6 @@ static inline bool cb_has_room(circular_buffer_t *cb)
return true;
}
-static inline bool cb_is_empty(circular_buffer_t *cb)
-{
- return cb->count == 0;
-}
-
static inline bool cb_push_back(circular_buffer_t *cb, const void *item)
{
if(cb->count == cb->capacity)
@@ -107,6 +127,9 @@ static inline bool cb_pop_front(circular_buffer_t *cb, void *item)
return true;
}
+int hackrf_sink_c::_usage = 0;
+boost::mutex hackrf_sink_c::_usage_mutex;
+
hackrf_sink_c_sptr make_hackrf_sink_c (const std::string & args)
{
return gnuradio::get_initial_sptr(new hackrf_sink_c (args));
@@ -133,21 +156,66 @@ hackrf_sink_c::hackrf_sink_c (const std::string &args)
: gr::sync_block ("hackrf_sink_c",
gr::io_signature::make(MIN_IN, MAX_IN, sizeof (gr_complex)),
gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof (gr_complex))),
- hackrf_common::hackrf_common(args),
+ _dev(NULL),
_buf(NULL),
- _vga_gain(0)
+ _sample_rate(0),
+ _center_freq(0),
+ _freq_corr(0),
+ _auto_gain(false),
+ _amp_gain(0),
+ _vga_gain(0),
+ _bandwidth(0)
{
+ int ret;
+ std::string *hackrf_serial = NULL;
+
dict_t dict = params_to_dict(args);
+ if (dict.count("hackrf") && dict["hackrf"].length() > 0)
+ hackrf_serial = &dict["hackrf"];
+
_buf_num = 0;
if (dict.count("buffers"))
- _buf_num = std::stoi(dict["buffers"]);
+ _buf_num = boost::lexical_cast< unsigned int >( dict["buffers"] );
if (0 == _buf_num)
_buf_num = BUF_NUM;
- _stopping = false;
+ {
+ boost::mutex::scoped_lock lock( _usage_mutex );
+
+ if ( _usage == 0 )
+ hackrf_init(); /* call only once before the first open */
+
+ _usage++;
+ }
+
+ _dev = NULL;
+#ifdef LIBHACKRF_HAVE_DEVICE_LIST
+ if ( hackrf_serial )
+ ret = hackrf_open_by_serial( hackrf_serial->c_str(), &_dev );
+ else
+#endif
+ ret = hackrf_open( &_dev );
+ HACKRF_THROW_ON_ERROR(ret, "Failed to open HackRF device")
+
+ uint8_t board_id;
+ ret = hackrf_board_id_read( _dev, &board_id );
+ HACKRF_THROW_ON_ERROR(ret, "Failed to get HackRF board id")
+
+ char version[40];
+ memset(version, 0, sizeof(version));
+ ret = hackrf_version_string_read( _dev, version, sizeof(version));
+ HACKRF_THROW_ON_ERROR(ret, "Failed to read version string")
+#if 0
+ read_partid_serialno_t serial_number;
+ ret = hackrf_board_partid_serialno_read( _dev, &serial_number );
+ HACKRF_THROW_ON_ERROR(ret, "Failed to read serial number")
+#endif
+ std::cerr << "Using " << hackrf_board_id_name(hackrf_board_id(board_id)) << " "
+ << "with firmware " << version << " "
+ << std::endl;
if ( BUF_NUM != _buf_num ) {
std::cerr << "Using " << _buf_num << " buffers of size " << BUF_LEN << "."
@@ -164,12 +232,26 @@ hackrf_sink_c::hackrf_sink_c (const std::string &args)
// Check device args to find out if bias/phantom power is desired.
if ( dict.count("bias_tx") ) {
- hackrf_common::set_bias(dict["bias_tx"] == "1");
+ bool bias = boost::lexical_cast<bool>( dict["bias_tx"] );
+ ret = hackrf_set_antenna_enable(_dev, static_cast<uint8_t>(bias));
+ if ( ret != HACKRF_SUCCESS )
+ {
+ std::cerr << "Failed to apply antenna bias voltage state: " << bias << HACKRF_FORMAT_ERROR(ret, "") << std::endl;
+ }
+ else
+ {
+ std::cerr << (bias ? "Enabled" : "Disabled") << " antenna bias voltage" << std::endl;
+ }
}
_buf = (int8_t *) malloc( BUF_LEN );
cb_init( &_cbuf, _buf_num, BUF_LEN );
+
+// _thread = gr::thread::thread(_hackrf_wait, this);
+
+ ret = hackrf_start_tx( _dev, _hackrf_tx_callback, (void *)this );
+ HACKRF_THROW_ON_ERROR(ret, "Failed to start TX streaming")
}
/*
@@ -177,6 +259,30 @@ hackrf_sink_c::hackrf_sink_c (const std::string &args)
*/
hackrf_sink_c::~hackrf_sink_c ()
{
+ if (_dev) {
+// _thread.join();
+ int ret = hackrf_stop_tx( _dev );
+ if ( ret != HACKRF_SUCCESS )
+ {
+ std::cerr << HACKRF_FORMAT_ERROR(ret, "Failed to stop TX streaming") << std::endl;
+ }
+ ret = hackrf_close( _dev );
+ if ( ret != HACKRF_SUCCESS )
+ {
+ std::cerr << HACKRF_FORMAT_ERROR(ret, "Failed to close HackRF") << std::endl;
+ }
+ _dev = NULL;
+
+ {
+ boost::mutex::scoped_lock lock( _usage_mutex );
+
+ _usage--;
+
+ if ( _usage == 0 )
+ hackrf_exit(); /* call only once after last close */
+ }
+ }
+
free(_buf);
_buf = NULL;
@@ -196,16 +302,11 @@ int hackrf_sink_c::hackrf_tx_callback(unsigned char *buffer, uint32_t length)
*buffer++ = rand() % 255;
#else
{
- std::lock_guard<std::mutex> lock(_buf_mutex);
+ boost::mutex::scoped_lock lock( _buf_mutex );
if ( ! cb_pop_front( &_cbuf, buffer ) ) {
memset(buffer, 0, length);
- if (_stopping) {
- _buf_cond.notify_one();
- return -1;
- } else {
- std::cerr << "U" << std::flush;
- }
+ std::cerr << "U" << std::flush;
} else {
// std::cerr << "-" << std::flush;
_buf_cond.notify_one();
@@ -215,61 +316,42 @@ int hackrf_sink_c::hackrf_tx_callback(unsigned char *buffer, uint32_t length)
return 0; // TODO: return -1 on error/stop
}
+void hackrf_sink_c::_hackrf_wait(hackrf_sink_c *obj)
+{
+ obj->hackrf_wait();
+}
+
+void hackrf_sink_c::hackrf_wait()
+{
+}
+
bool hackrf_sink_c::start()
{
- if ( ! _dev.get() )
+ if ( ! _dev )
return false;
- _stopping = false;
_buf_used = 0;
- hackrf_common::start();
- int ret = hackrf_start_tx( _dev.get(), _hackrf_tx_callback, (void *)this );
+#if 0
+ int ret = hackrf_start_tx( _dev, _hackrf_tx_callback, (void *)this );
if ( ret != HACKRF_SUCCESS ) {
std::cerr << "Failed to start TX streaming (" << ret << ")" << std::endl;
return false;
}
+#endif
return true;
}
bool hackrf_sink_c::stop()
{
- int i;
-
- if ( ! _dev.get() )
+ if ( ! _dev )
return false;
-
- {
- std::unique_lock<std::mutex> lock(_buf_mutex);
-
- while ( ! cb_has_room(&_cbuf) )
- _buf_cond.wait( lock );
-
- // Fill the rest of the current buffer with silence.
- memset(_buf + _buf_used, 0, BUF_LEN - _buf_used);
- cb_push_back( &_cbuf, _buf );
- _buf_used = 0;
-
- // Add some more silence so the end doesn't get cut off.
- memset(_buf, 0, BUF_LEN);
- for (i = 0; i < 5; i++) {
- while ( ! cb_has_room(&_cbuf) )
- _buf_cond.wait( lock );
-
- cb_push_back( &_cbuf, _buf );
- }
-
- _stopping = true;
-
- while (hackrf_is_streaming(_dev.get()) == HACKRF_TRUE)
- _buf_cond.wait( lock );
- }
-
- hackrf_common::stop();
- int ret = hackrf_stop_tx( _dev.get() );
+#if 0
+ int ret = hackrf_stop_tx( _dev );
if ( ret != HACKRF_SUCCESS ) {
std::cerr << "Failed to stop TX streaming (" << ret << ")" << std::endl;
return false;
}
+#endif
return true;
}
@@ -342,7 +424,7 @@ int hackrf_sink_c::work( int noutput_items,
const gr_complex *in = (const gr_complex *) input_items[0];
{
- std::unique_lock<std::mutex> lock(_buf_mutex);
+ boost::mutex::scoped_lock lock( _buf_mutex );
while ( ! cb_has_room(&_cbuf) )
_buf_cond.wait( lock );
@@ -372,7 +454,7 @@ int hackrf_sink_c::work( int noutput_items,
if((unsigned int)noutput_items >= remaining) {
{
- std::lock_guard<std::mutex> lock(_buf_mutex);
+ boost::mutex::scoped_lock lock( _buf_mutex );
if ( ! cb_push_back( &_cbuf, _buf ) ) {
_buf_used = prev_buf_used;
@@ -395,7 +477,78 @@ int hackrf_sink_c::work( int noutput_items,
std::vector<std::string> hackrf_sink_c::get_devices()
{
- return hackrf_common::get_devices();
+ std::vector<std::string> devices;
+ std::string label;
+
+ {
+ boost::mutex::scoped_lock lock( _usage_mutex );
+
+ if ( _usage == 0 )
+ hackrf_init(); /* call only once before the first open */
+
+ _usage++;
+ }
+
+#ifdef LIBHACKRF_HAVE_DEVICE_LIST
+ hackrf_device_list_t *list = hackrf_device_list();
+
+ for (int i = 0; i < list->devicecount; i++) {
+ label = "HackRF ";
+ label += hackrf_usb_board_id_name( list->usb_board_ids[i] );
+
+ std::string args;
+ if (list->serial_numbers[i]) {
+ std::string serial = boost::lexical_cast< std::string >( list->serial_numbers[i] );
+ if (serial.length() > 6)
+ serial = serial.substr(serial.length() - 6, 6);
+ args = "hackrf=" + serial;
+ label += " " + serial;
+ } else
+ args = "hackrf"; /* will pick the first one, serial number is required for choosing a specific one */
+
+ boost::algorithm::trim(label);
+
+ args += ",label='" + label + "'";
+ devices.push_back( args );
+ }
+
+ hackrf_device_list_free(list);
+#else
+
+ int ret;
+ hackrf_device *dev = NULL;
+ ret = hackrf_open(&dev);
+ if ( HACKRF_SUCCESS == ret )
+ {
+ std::string args = "hackrf=0";
+
+ label = "HackRF";
+
+ uint8_t board_id;
+ ret = hackrf_board_id_read( dev, &board_id );
+ if ( HACKRF_SUCCESS == ret )
+ {
+ label += std::string(" ") + hackrf_board_id_name(hackrf_board_id(board_id));
+ }
+
+ args += ",label='" + label + "'";
+ devices.push_back( args );
+
+ ret = hackrf_close(dev);
+ }
+
+#endif
+
+ {
+ boost::mutex::scoped_lock lock( _usage_mutex );
+
+ _usage--;
+
+ if ( _usage == 0 )
+ hackrf_exit(); /* call only once after last close */
+ }
+
+ return devices;
}
size_t hackrf_sink_c::get_num_channels()
@@ -405,47 +558,98 @@ size_t hackrf_sink_c::get_num_channels()
osmosdr::meta_range_t hackrf_sink_c::get_sample_rates()
{
- return hackrf_common::get_sample_rates();
+ osmosdr::meta_range_t range;
+
+ /* we only add integer rates here because of better phase noise performance.
+ * the user is allowed to request arbitrary (fractional) rates within these
+ * boundaries. */
+
+ range += osmosdr::range_t( 8e6 );
+ range += osmosdr::range_t( 10e6 );
+ range += osmosdr::range_t( 12.5e6 );
+ range += osmosdr::range_t( 16e6 );
+ range += osmosdr::range_t( 20e6 ); /* confirmed to work on fast machines */
+
+ return range;
}
double hackrf_sink_c::set_sample_rate( double rate )
{
- return hackrf_common::set_sample_rate(rate);
+ int ret;
+
+ if (_dev) {
+ ret = hackrf_set_sample_rate( _dev, rate );
+ if ( HACKRF_SUCCESS == ret ) {
+ _sample_rate = rate;
+ //set_bandwidth( 0.0 ); /* bandwidth of 0 means automatic filter selection */
+ } else {
+ HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_sample_rate", rate ) )
+ }
+ }
+
+ return get_sample_rate();
}
double hackrf_sink_c::get_sample_rate()
{
- return hackrf_common::get_sample_rate();
+ return _sample_rate;
}
osmosdr::freq_range_t hackrf_sink_c::get_freq_range( size_t chan )
{
- return hackrf_common::get_freq_range(chan);
+ osmosdr::freq_range_t range;
+
+ range += osmosdr::range_t( _sample_rate / 2, 7250e6 - _sample_rate / 2 );
+
+ return range;
}
double hackrf_sink_c::set_center_freq( double freq, size_t chan )
{
- return hackrf_common::set_center_freq(freq, chan);
+ int ret;
+
+ #define APPLY_PPM_CORR(val, ppm) ((val) * (1.0 + (ppm) * 0.000001))
+
+ if (_dev) {
+ double corr_freq = APPLY_PPM_CORR( freq, _freq_corr );
+ ret = hackrf_set_freq( _dev, uint64_t(corr_freq) );
+ if ( HACKRF_SUCCESS == ret ) {
+ _center_freq = freq;
+ } else {
+ HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_freq", corr_freq ) )
+ }
+ }
+
+ return get_center_freq( chan );
}
double hackrf_sink_c::get_center_freq( size_t chan )
{
- return hackrf_common::get_center_freq(chan);
+ return _center_freq;
}
double hackrf_sink_c::set_freq_corr( double ppm, size_t chan )
{
- return hackrf_common::set_freq_corr(ppm, chan);
+ _freq_corr = ppm;
+
+ set_center_freq( _center_freq );
+
+ return get_freq_corr( chan );
}
double hackrf_sink_c::get_freq_corr( size_t chan )
{
- return hackrf_common::get_freq_corr(chan);
+ return _freq_corr;
}
std::vector<std::string> hackrf_sink_c::get_gain_names( size_t chan )
{
- return { "RF", "IF" };
+ std::vector< std::string > names;
+
+ names += "RF";
+ names += "IF";
+
+ return names;
}
osmosdr::gain_range_t hackrf_sink_c::get_gain_range( size_t chan )
@@ -468,17 +672,34 @@ osmosdr::gain_range_t hackrf_sink_c::get_gain_range( const std::string & name, s
bool hackrf_sink_c::set_gain_mode( bool automatic, size_t chan )
{
- return hackrf_common::set_gain_mode(automatic, chan);
+ _auto_gain = automatic;
+
+ return get_gain_mode(chan);
}
bool hackrf_sink_c::get_gain_mode( size_t chan )
{
- return hackrf_common::get_gain_mode(chan);
+ return _auto_gain;
}
double hackrf_sink_c::set_gain( double gain, size_t chan )
{
- return hackrf_common::set_gain(gain, chan);
+ int ret;
+ osmosdr::gain_range_t rf_gains = get_gain_range( "RF", chan );
+
+ if (_dev) {
+ double clip_gain = rf_gains.clip( gain, true );
+ uint8_t value = clip_gain == 14.0f ? 1 : 0;
+
+ ret = hackrf_set_amp_enable( _dev, value );
+ if ( HACKRF_SUCCESS == ret ) {
+ _amp_gain = clip_gain;
+ } else {
+ HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_amp_enable", value ) )
+ }
+ }
+
+ return _amp_gain;
}
double hackrf_sink_c::set_gain( double gain, const std::string & name, size_t chan)
@@ -496,7 +717,7 @@ double hackrf_sink_c::set_gain( double gain, const std::string & name, size_t ch
double hackrf_sink_c::get_gain( size_t chan )
{
- return hackrf_common::get_gain(chan);
+ return _amp_gain;
}
double hackrf_sink_c::get_gain( const std::string & name, size_t chan )
@@ -517,10 +738,10 @@ double hackrf_sink_c::set_if_gain( double gain, size_t chan )
int ret;
osmosdr::gain_range_t if_gains = get_gain_range( "IF", chan );
- if (_dev.get()) {
+ if (_dev) {
double clip_gain = if_gains.clip( gain, true );
- ret = hackrf_set_txvga_gain( _dev.get(), uint32_t(clip_gain) );
+ ret = hackrf_set_txvga_gain( _dev, uint32_t(clip_gain) );
if ( HACKRF_SUCCESS == ret ) {
_vga_gain = clip_gain;
} else {
@@ -538,30 +759,72 @@ double hackrf_sink_c::set_bb_gain( double gain, size_t chan )
std::vector< std::string > hackrf_sink_c::get_antennas( size_t chan )
{
- return hackrf_common::get_antennas(chan);
+ std::vector< std::string > antennas;
+
+ antennas += get_antenna( chan );
+
+ return antennas;
}
std::string hackrf_sink_c::set_antenna( const std::string & antenna, size_t chan )
{
- return hackrf_common::set_antenna(antenna, chan);
+ return get_antenna( chan );
}
std::string hackrf_sink_c::get_antenna( size_t chan )
{
- return hackrf_common::get_antenna(chan);
+ return "TX/RX";
}
double hackrf_sink_c::set_bandwidth( double bandwidth, size_t chan )
{
- return hackrf_common::set_bandwidth(bandwidth, chan);
+ int ret;
+// osmosdr::freq_range_t bandwidths = get_bandwidth_range( chan );
+
+ if ( bandwidth == 0.0 ) /* bandwidth of 0 means automatic filter selection */
+ bandwidth = _sample_rate * 0.75; /* select narrower filters to prevent aliasing */
+
+ if ( _dev ) {
+ /* compute best default value depending on sample rate (auto filter) */
+ uint32_t bw = hackrf_compute_baseband_filter_bw( uint32_t(bandwidth) );
+ ret = hackrf_set_baseband_filter_bandwidth( _dev, bw );
+ if ( HACKRF_SUCCESS == ret ) {
+ _bandwidth = bw;
+ } else {
+ HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_baseband_filter_bandwidth", bw ) )
+ }
+ }
+
+ return _bandwidth;
}
double hackrf_sink_c::get_bandwidth( size_t chan )
{
- return hackrf_common::get_bandwidth(chan);
+ return _bandwidth;
}
osmosdr::freq_range_t hackrf_sink_c::get_bandwidth_range( size_t chan )
{
- return hackrf_common::get_bandwidth_range(chan);
+ osmosdr::freq_range_t bandwidths;
+
+ // TODO: read out from libhackrf when an API is available
+
+ bandwidths += osmosdr::range_t( 1750000 );
+ bandwidths += osmosdr::range_t( 2500000 );
+ bandwidths += osmosdr::range_t( 3500000 );
+ bandwidths += osmosdr::range_t( 5000000 );
+ bandwidths += osmosdr::range_t( 5500000 );
+ bandwidths += osmosdr::range_t( 6000000 );
+ bandwidths += osmosdr::range_t( 7000000 );
+ bandwidths += osmosdr::range_t( 8000000 );
+ bandwidths += osmosdr::range_t( 9000000 );
+ bandwidths += osmosdr::range_t( 10000000 );
+ bandwidths += osmosdr::range_t( 12000000 );
+ bandwidths += osmosdr::range_t( 14000000 );
+ bandwidths += osmosdr::range_t( 15000000 );
+ bandwidths += osmosdr::range_t( 20000000 );
+ bandwidths += osmosdr::range_t( 24000000 );
+ bandwidths += osmosdr::range_t( 28000000 );
+
+ return bandwidths;
}
diff --git a/lib/hackrf/hackrf_sink_c.h b/lib/hackrf/hackrf_sink_c.h
index 08ff2ca..a7e7ab8 100644
--- a/lib/hackrf/hackrf_sink_c.h
+++ b/lib/hackrf/hackrf_sink_c.h
@@ -1,35 +1,34 @@
/* -*- c++ -*- */
/*
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
- * Copyright 2020 Clayton Smith <argilo@gmail.com>
*
- * gr-osmosdr is free software; you can redistribute it and/or modify
+ * GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
- * gr-osmosdr is distributed in the hope that it will be useful,
+ * GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with gr-osmosdr; see the file COPYING. If not, write to
+ * along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_HACKRF_SINK_C_H
#define INCLUDED_HACKRF_SINK_C_H
+#include <gnuradio/thread/thread.h>
#include <gnuradio/sync_block.h>
-#include <condition_variable>
-#include <mutex>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
#include <libhackrf/hackrf.h>
#include "sink_iface.h"
-#include "hackrf_common.h"
class hackrf_sink_c;
@@ -68,8 +67,7 @@ hackrf_sink_c_sptr make_hackrf_sink_c (const std::string & args = "");
class hackrf_sink_c :
public gr::sync_block,
- public sink_iface,
- protected hackrf_common
+ public sink_iface
{
private:
// The friend declaration allows hackrf_make_sink_c to
@@ -126,16 +124,29 @@ public:
private:
static int _hackrf_tx_callback(hackrf_transfer* transfer);
int hackrf_tx_callback(unsigned char *buffer, uint32_t length);
+ static void _hackrf_wait(hackrf_sink_c *obj);
+ void hackrf_wait();
+
+ static int _usage;
+ static boost::mutex _usage_mutex;
+
+ hackrf_device *_dev;
+// gr::thread::thread _thread;
circular_buffer_t _cbuf;
int8_t *_buf;
unsigned int _buf_num;
unsigned int _buf_used;
- bool _stopping;
- std::mutex _buf_mutex;
- std::condition_variable _buf_cond;
-
+ boost::mutex _buf_mutex;
+ boost::condition_variable _buf_cond;
+
+ double _sample_rate;
+ double _center_freq;
+ double _freq_corr;
+ bool _auto_gain;
+ double _amp_gain;
double _vga_gain;
+ double _bandwidth;
};
#endif /* INCLUDED_HACKRF_SINK_C_H */
diff --git a/lib/hackrf/hackrf_source_c.cc b/lib/hackrf/hackrf_source_c.cc
index 03ea3bd..30b63c7 100644
--- a/lib/hackrf/hackrf_source_c.cc
+++ b/lib/hackrf/hackrf_source_c.cc
@@ -1,20 +1,19 @@
/* -*- c++ -*- */
/*
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
- * Copyright 2020 Clayton Smith <argilo@gmail.com>
*
- * gr-osmosdr is free software; you can redistribute it and/or modify
+ * GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
- * gr-osmosdr is distributed in the hope that it will be useful,
+ * GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with gr-osmosdr; see the file COPYING. If not, write to
+ * along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
@@ -30,7 +29,12 @@
#include <stdexcept>
#include <iostream>
-#include <chrono>
+
+#include <boost/assign.hpp>
+#include <boost/format.hpp>
+#include <boost/detail/endian.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/thread/thread.hpp>
#include <gnuradio/io_signature.h>
@@ -38,6 +42,29 @@
#include "arg_helpers.h"
+using namespace boost::assign;
+
+#define BUF_LEN (16 * 32 * 512) /* must be multiple of 512 */
+#define BUF_NUM 15
+
+#define BYTES_PER_SAMPLE 2 /* HackRF device produces 8 bit unsigned IQ data */
+
+#define HACKRF_FORMAT_ERROR(ret, msg) \
+ boost::str( boost::format(msg " (%1%) %2%") \
+ % ret % hackrf_error_name((enum hackrf_error)ret) )
+
+#define HACKRF_THROW_ON_ERROR(ret, msg) \
+ if ( ret != HACKRF_SUCCESS ) \
+ { \
+ throw std::runtime_error( HACKRF_FORMAT_ERROR(ret, msg) ); \
+ }
+
+#define HACKRF_FUNC_STR(func, arg) \
+ boost::str(boost::format(func "(%1%)") % arg) + " has failed"
+
+int hackrf_source_c::_usage = 0;
+boost::mutex hackrf_source_c::_usage_mutex;
+
hackrf_source_c_sptr make_hackrf_source_c (const std::string & args)
{
return gnuradio::get_initial_sptr(new hackrf_source_c (args));
@@ -64,20 +91,29 @@ hackrf_source_c::hackrf_source_c (const std::string &args)
: gr::sync_block ("hackrf_source_c",
gr::io_signature::make(MIN_IN, MAX_IN, sizeof (gr_complex)),
gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof (gr_complex))),
- hackrf_common::hackrf_common(args),
+ _dev(NULL),
_buf(NULL),
+ _sample_rate(0),
+ _center_freq(0),
+ _freq_corr(0),
+ _auto_gain(false),
+ _amp_gain(0),
_lna_gain(0),
- _vga_gain(0)
+ _vga_gain(0),
+ _bandwidth(0)
{
+ int ret;
+ std::string hackrf_serial;
+
dict_t dict = params_to_dict(args);
_buf_num = _buf_len = _buf_head = _buf_used = _buf_offset = 0;
if (dict.count("buffers"))
- _buf_num = std::stoi(dict["buffers"]);
+ _buf_num = boost::lexical_cast< unsigned int >( dict["buffers"] );
// if (dict.count("buflen"))
-// _buf_len = std::stoi(dict["buflen"]);
+// _buf_len = boost::lexical_cast< unsigned int >( dict["buflen"] );
if (0 == _buf_num)
_buf_num = BUF_NUM;
@@ -88,10 +124,76 @@ hackrf_source_c::hackrf_source_c (const std::string &args)
_samp_avail = _buf_len / BYTES_PER_SAMPLE;
// create a lookup table for gr_complex values
- for (unsigned int i = 0; i <= 0xff; i++) {
- _lut.push_back( float(int8_t(i)) * (1.0f/128.0f) );
+ for (unsigned int i = 0; i <= 0xffff; i++) {
+#ifdef BOOST_LITTLE_ENDIAN
+ _lut.push_back( gr_complex( (float(int8_t(i & 0xff))) * (1.0f/128.0f),
+ (float(int8_t(i >> 8))) * (1.0f/128.0f) ) );
+#else // BOOST_BIG_ENDIAN
+ _lut.push_back( gr_complex( (float(int8_t(i >> 8))) * (1.0f/128.0f),
+ (float(int8_t(i & 0xff))) * (1.0f/128.0f) ) );
+#endif
+ }
+
+ {
+ boost::mutex::scoped_lock lock( _usage_mutex );
+
+ if ( _usage == 0 )
+ hackrf_init(); /* call only once before the first open */
+
+ _usage++;
}
+ _dev = NULL;
+
+#ifdef LIBHACKRF_HAVE_DEVICE_LIST
+ if (dict.count("hackrf") && dict["hackrf"].length() > 0) {
+ hackrf_serial = dict["hackrf"];
+
+ if (hackrf_serial.length() > 1) {
+ ret = hackrf_open_by_serial( hackrf_serial.c_str(), &_dev );
+ } else {
+ int dev_index = 0;
+ try {
+ dev_index = boost::lexical_cast< int >( hackrf_serial );
+ } catch ( std::exception &ex ) {
+ throw std::runtime_error(
+ "Failed to use '" + hackrf_serial + "' as HackRF device index number: " + ex.what());
+ }
+
+ hackrf_device_list_t *list = hackrf_device_list();
+ if (dev_index < list->devicecount) {
+ ret = hackrf_device_list_open(list, dev_index, &_dev);
+ } else {
+ hackrf_device_list_free(list);
+ throw std::runtime_error(
+ "Failed to use '" + hackrf_serial + "' as HackRF device index: not enough devices");
+ }
+ hackrf_device_list_free(list);
+ }
+ } else
+#endif
+ ret = hackrf_open( &_dev );
+
+ HACKRF_THROW_ON_ERROR(ret, "Failed to open HackRF device")
+
+ uint8_t board_id;
+ ret = hackrf_board_id_read( _dev, &board_id );
+ HACKRF_THROW_ON_ERROR(ret, "Failed to get HackRF board id")
+
+ char version[40];
+ memset(version, 0, sizeof(version));
+ ret = hackrf_version_string_read( _dev, version, sizeof(version));
+ HACKRF_THROW_ON_ERROR(ret, "Failed to read version string")
+
+#if 0
+ read_partid_serialno_t serial_number;
+ ret = hackrf_board_partid_serialno_read( _dev, &serial_number );
+ HACKRF_THROW_ON_ERROR(ret, "Failed to read serial number")
+#endif
+ std::cerr << "Using " << hackrf_board_id_name(hackrf_board_id(board_id)) << " "
+ << "with firmware " << version << " "
+ << std::endl;
+
if ( BUF_NUM != _buf_num || BUF_LEN != _buf_len ) {
std::cerr << "Using " << _buf_num << " buffers of size " << _buf_len << "."
<< std::endl;
@@ -109,15 +211,29 @@ hackrf_source_c::hackrf_source_c (const std::string &args)
// Check device args to find out if bias/phantom power is desired.
if ( dict.count("bias") ) {
- hackrf_common::set_bias(dict["bias"] == "1");
+ bool bias = boost::lexical_cast<bool>( dict["bias"] );
+ ret = hackrf_set_antenna_enable(_dev, static_cast<uint8_t>(bias));
+ if ( ret != HACKRF_SUCCESS )
+ {
+ std::cerr << "Failed to apply antenna bias voltage state: " << bias << HACKRF_FORMAT_ERROR(ret, "") << std::endl;
+ }
+ else
+ {
+ std::cerr << (bias ? "Enabled" : "Disabled") << " antenna bias voltage" << std::endl;
+ }
}
- _buf = (unsigned char **) malloc(_buf_num * sizeof(unsigned char *));
+ _buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
if (_buf) {
for(unsigned int i = 0; i < _buf_num; ++i)
- _buf[i] = (unsigned char *) malloc(_buf_len);
+ _buf[i] = (unsigned short *) malloc(_buf_len);
}
+
+// _thread = gr::thread::thread(_hackrf_wait, this);
+
+ ret = hackrf_start_rx( _dev, _hackrf_rx_callback, (void *)this );
+ HACKRF_THROW_ON_ERROR(ret, "Failed to start RX streaming")
}
/*
@@ -125,6 +241,30 @@ hackrf_source_c::hackrf_source_c (const std::string &args)
*/
hackrf_source_c::~hackrf_source_c ()
{
+ if (_dev) {
+// _thread.join();
+ int ret = hackrf_stop_rx( _dev );
+ if ( ret != HACKRF_SUCCESS )
+ {
+ std::cerr << HACKRF_FORMAT_ERROR(ret, "Failed to stop RX streaming") << std::endl;
+ }
+ ret = hackrf_close( _dev );
+ if ( ret != HACKRF_SUCCESS )
+ {
+ std::cerr << HACKRF_FORMAT_ERROR(ret, "Failed to close HackRF") << std::endl;
+ }
+ _dev = NULL;
+
+ {
+ boost::mutex::scoped_lock lock( _usage_mutex );
+
+ _usage--;
+
+ if ( _usage == 0 )
+ hackrf_exit(); /* call only once after last close */
+ }
+ }
+
if (_buf) {
for(unsigned int i = 0; i < _buf_num; ++i) {
free(_buf[i]);
@@ -144,7 +284,7 @@ int hackrf_source_c::_hackrf_rx_callback(hackrf_transfer *transfer)
int hackrf_source_c::hackrf_rx_callback(unsigned char *buf, uint32_t len)
{
{
- std::lock_guard<std::mutex> lock(_buf_mutex);
+ boost::mutex::scoped_lock lock( _buf_mutex );
int buf_tail = (_buf_head + _buf_used) % _buf_num;
memcpy(_buf[buf_tail], buf, len);
@@ -162,31 +302,40 @@ int hackrf_source_c::hackrf_rx_callback(unsigned char *buf, uint32_t len)
return 0; // TODO: return -1 on error/stop
}
+void hackrf_source_c::_hackrf_wait(hackrf_source_c *obj)
+{
+ obj->hackrf_wait();
+}
+
+void hackrf_source_c::hackrf_wait()
+{
+}
+
bool hackrf_source_c::start()
{
- if ( ! _dev.get() )
+ if ( ! _dev )
return false;
-
- hackrf_common::start();
- int ret = hackrf_start_rx( _dev.get(), _hackrf_rx_callback, (void *)this );
+#if 0
+ int ret = hackrf_start_rx( _dev, _hackrf_rx_callback, (void *)this );
if ( ret != HACKRF_SUCCESS ) {
std::cerr << "Failed to start RX streaming (" << ret << ")" << std::endl;
return false;
}
+#endif
return true;
}
bool hackrf_source_c::stop()
{
- if ( ! _dev.get() )
+ if ( ! _dev )
return false;
-
- hackrf_common::stop();
- int ret = hackrf_stop_rx( _dev.get() );
+#if 0
+ int ret = hackrf_stop_rx( _dev );
if ( ret != HACKRF_SUCCESS ) {
std::cerr << "Failed to stop RX streaming (" << ret << ")" << std::endl;
return false;
}
+#endif
return true;
}
@@ -198,41 +347,33 @@ int hackrf_source_c::work( int noutput_items,
bool running = false;
- if ( _dev.get() )
- running = (hackrf_is_streaming( _dev.get() ) == HACKRF_TRUE);
+ if ( _dev )
+ running = (hackrf_is_streaming( _dev ) == HACKRF_TRUE);
{
- std::unique_lock<std::mutex> lock(_buf_mutex);
+ boost::mutex::scoped_lock lock( _buf_mutex );
- while (_buf_used < 3 && running) { // collect at least 3 buffers
- _buf_cond.wait_for( lock , std::chrono::milliseconds(100));
-
- // Re-check whether the device has closed or stopped streaming
- if ( _dev.get() )
- running = (hackrf_is_streaming( _dev.get() ) == HACKRF_TRUE);
- else
- running = false;
- }
+ while (_buf_used < 3 && running) // collect at least 3 buffers
+ _buf_cond.wait( lock );
}
if ( ! running )
return WORK_DONE;
- const uint8_t *buf = _buf[_buf_head] + _buf_offset * BYTES_PER_SAMPLE;
-#define TO_COMPLEX(p) gr_complex( _lut[(p)[0]], _lut[(p)[1]] )
+ unsigned short *buf = _buf[_buf_head] + _buf_offset;
if (noutput_items <= _samp_avail) {
for (int i = 0; i < noutput_items; ++i)
- *out++ = TO_COMPLEX( buf + i*BYTES_PER_SAMPLE );
+ *out++ = _lut[ *(buf + i) ];
_buf_offset += noutput_items;
_samp_avail -= noutput_items;
} else {
for (int i = 0; i < _samp_avail; ++i)
- *out++ = TO_COMPLEX( buf + i*BYTES_PER_SAMPLE );
+ *out++ = _lut[ *(buf + i) ];
{
- std::lock_guard<std::mutex> lock(_buf_mutex);
+ boost::mutex::scoped_lock lock( _buf_mutex );
_buf_head = (_buf_head + 1) % _buf_num;
_buf_used--;
@@ -243,7 +384,7 @@ int hackrf_source_c::work( int noutput_items,
int remaining = noutput_items - _samp_avail;
for (int i = 0; i < remaining; ++i)
- *out++ = TO_COMPLEX( buf + i*BYTES_PER_SAMPLE );
+ *out++ = _lut[ *(buf + i) ];
_buf_offset = remaining;
_samp_avail = (_buf_len / BYTES_PER_SAMPLE) - remaining;
@@ -254,7 +395,78 @@ int hackrf_source_c::work( int noutput_items,
std::vector<std::string> hackrf_source_c::get_devices()
{
- return hackrf_common::get_devices();
+ std::vector<std::string> devices;
+ std::string label;
+
+ {
+ boost::mutex::scoped_lock lock( _usage_mutex );
+
+ if ( _usage == 0 )
+ hackrf_init(); /* call only once before the first open */
+
+ _usage++;
+ }
+
+#ifdef LIBHACKRF_HAVE_DEVICE_LIST
+ hackrf_device_list_t *list = hackrf_device_list();
+
+ for (int i = 0; i < list->devicecount; i++) {
+ label = "HackRF ";
+ label += hackrf_usb_board_id_name( list->usb_board_ids[i] );
+
+ std::string args;
+ if (list->serial_numbers[i]) {
+ std::string serial = boost::lexical_cast< std::string >( list->serial_numbers[i] );
+ if (serial.length() > 6)
+ serial = serial.substr(serial.length() - 6, 6);
+ args = "hackrf=" + serial;
+ label += " " + serial;
+ } else
+ args = "hackrf"; /* will pick the first one, serial number is required for choosing a specific one */
+
+ boost::algorithm::trim(label);
+
+ args += ",label='" + label + "'";
+ devices.push_back( args );
+ }
+
+ hackrf_device_list_free(list);
+#else
+
+ int ret;
+ hackrf_device *dev = NULL;
+ ret = hackrf_open(&dev);
+ if ( HACKRF_SUCCESS == ret )
+ {
+ std::string args = "hackrf=0";
+
+ label = "HackRF";
+
+ uint8_t board_id;
+ ret = hackrf_board_id_read( dev, &board_id );
+ if ( HACKRF_SUCCESS == ret )
+ {
+ label += std::string(" ") + hackrf_board_id_name(hackrf_board_id(board_id));
+ }
+
+ args += ",label='" + label + "'";
+ devices.push_back( args );
+
+ ret = hackrf_close(dev);
+ }
+
+#endif
+
+ {
+ boost::mutex::scoped_lock lock( _usage_mutex );
+
+ _usage--;
+
+ if ( _usage == 0 )
+ hackrf_exit(); /* call only once after last close */
+ }
+
+ return devices;
}
size_t hackrf_source_c::get_num_channels()
@@ -264,47 +476,99 @@ size_t hackrf_source_c::get_num_channels()
osmosdr::meta_range_t hackrf_source_c::get_sample_rates()
{
- return hackrf_common::get_sample_rates();
+ osmosdr::meta_range_t range;
+
+ /* we only add integer rates here because of better phase noise performance.
+ * the user is allowed to request arbitrary (fractional) rates within these
+ * boundaries. */
+
+ range += osmosdr::range_t( 8e6 );
+ range += osmosdr::range_t( 10e6 );
+ range += osmosdr::range_t( 12.5e6 );
+ range += osmosdr::range_t( 16e6 );
+ range += osmosdr::range_t( 20e6 ); /* confirmed to work on fast machines */
+
+ return range;
}
double hackrf_source_c::set_sample_rate( double rate )
{
- return hackrf_common::set_sample_rate(rate);
+ int ret;
+
+ if (_dev) {
+ ret = hackrf_set_sample_rate( _dev, rate );
+ if ( HACKRF_SUCCESS == ret ) {
+ _sample_rate = rate;
+ //set_bandwidth( 0.0 ); /* bandwidth of 0 means automatic filter selection */
+ } else {
+ HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_sample_rate", rate ) )
+ }
+ }
+
+ return get_sample_rate();
}
double hackrf_source_c::get_sample_rate()
{
- return hackrf_common::get_sample_rate();
+ return _sample_rate;
}
osmosdr::freq_range_t hackrf_source_c::get_freq_range( size_t chan )
{
- return hackrf_common::get_freq_range(chan);
+ osmosdr::freq_range_t range;
+
+ range += osmosdr::range_t( _sample_rate / 2, 7250e6 - _sample_rate / 2 );
+
+ return range;
}
double hackrf_source_c::set_center_freq( double freq, size_t chan )
{
- return hackrf_common::set_center_freq(freq, chan);
+ int ret;
+
+ #define APPLY_PPM_CORR(val, ppm) ((val) * (1.0 + (ppm) * 0.000001))
+
+ if (_dev) {
+ double corr_freq = APPLY_PPM_CORR( freq, _freq_corr );
+ ret = hackrf_set_freq( _dev, uint64_t(corr_freq) );
+ if ( HACKRF_SUCCESS == ret ) {
+ _center_freq = freq;
+ } else {
+ HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_freq", corr_freq ) )
+ }
+ }
+
+ return get_center_freq( chan );
}
double hackrf_source_c::get_center_freq( size_t chan )
{
- return hackrf_common::get_center_freq(chan);
+ return _center_freq;
}
double hackrf_source_c::set_freq_corr( double ppm, size_t chan )
{
- return hackrf_common::set_freq_corr(ppm, chan);
+ _freq_corr = ppm;
+
+ set_center_freq( _center_freq );
+
+ return get_freq_corr( chan );
}
double hackrf_source_c::get_freq_corr( size_t chan )
{
- return hackrf_common::get_freq_corr(chan);
+ return _freq_corr;
}
std::vector<std::string> hackrf_source_c::get_gain_names( size_t chan )
{
- return { "RF", "IF", "BB" };
+ std::vector< std::string > names;
+
+ names += "RF";
+ names += "IF";
+ names += "BB";
+
+ return names;
}
osmosdr::gain_range_t hackrf_source_c::get_gain_range( size_t chan )
@@ -331,17 +595,34 @@ osmosdr::gain_range_t hackrf_source_c::get_gain_range( const std::string & name,
bool hackrf_source_c::set_gain_mode( bool automatic, size_t chan )
{
- return hackrf_common::set_gain_mode(automatic, chan);
+ _auto_gain = automatic;
+
+ return get_gain_mode(chan);
}
bool hackrf_source_c::get_gain_mode( size_t chan )
{
- return hackrf_common::get_gain_mode(chan);
+ return _auto_gain;
}
double hackrf_source_c::set_gain( double gain, size_t chan )
{
- return hackrf_common::set_gain(gain, chan);
+ int ret;
+ osmosdr::gain_range_t rf_gains = get_gain_range( "RF", chan );
+
+ if (_dev) {
+ double clip_gain = rf_gains.clip( gain, true );
+ uint8_t value = clip_gain == 14.0f ? 1 : 0;
+
+ ret = hackrf_set_amp_enable( _dev, value );
+ if ( HACKRF_SUCCESS == ret ) {
+ _amp_gain = clip_gain;
+ } else {
+ HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_amp_enable", value ) )
+ }
+ }
+
+ return _amp_gain;
}
double hackrf_source_c::set_gain( double gain, const std::string & name, size_t chan)
@@ -363,7 +644,7 @@ double hackrf_source_c::set_gain( double gain, const std::string & name, size_t
double hackrf_source_c::get_gain( size_t chan )
{
- return hackrf_common::get_gain(chan);
+ return _amp_gain;
}
double hackrf_source_c::get_gain( const std::string & name, size_t chan )
@@ -388,10 +669,10 @@ double hackrf_source_c::set_if_gain(double gain, size_t chan)
int ret;
osmosdr::gain_range_t rf_gains = get_gain_range( "IF", chan );
- if (_dev.get()) {
+ if (_dev) {
double clip_gain = rf_gains.clip( gain, true );
- ret = hackrf_set_lna_gain( _dev.get(), uint32_t(clip_gain) );
+ ret = hackrf_set_lna_gain( _dev, uint32_t(clip_gain) );
if ( HACKRF_SUCCESS == ret ) {
_lna_gain = clip_gain;
} else {
@@ -407,10 +688,10 @@ double hackrf_source_c::set_bb_gain( double gain, size_t chan )
int ret;
osmosdr::gain_range_t if_gains = get_gain_range( "BB", chan );
- if (_dev.get()) {
+ if (_dev) {
double clip_gain = if_gains.clip( gain, true );
- ret = hackrf_set_vga_gain( _dev.get(), uint32_t(clip_gain) );
+ ret = hackrf_set_vga_gain( _dev, uint32_t(clip_gain) );
if ( HACKRF_SUCCESS == ret ) {
_vga_gain = clip_gain;
} else {
@@ -423,30 +704,72 @@ double hackrf_source_c::set_bb_gain( double gain, size_t chan )
std::vector< std::string > hackrf_source_c::get_antennas( size_t chan )
{
- return hackrf_common::get_antennas(chan);
+ std::vector< std::string > antennas;
+
+ antennas += get_antenna( chan );
+
+ return antennas;
}
std::string hackrf_source_c::set_antenna( const std::string & antenna, size_t chan )
{
- return hackrf_common::set_antenna(antenna, chan);
+ return get_antenna( chan );
}
std::string hackrf_source_c::get_antenna( size_t chan )
{
- return hackrf_common::get_antenna(chan);
+ return "TX/RX";
}
double hackrf_source_c::set_bandwidth( double bandwidth, size_t chan )
{
- return hackrf_common::set_bandwidth(bandwidth, chan);
+ int ret;
+// osmosdr::freq_range_t bandwidths = get_bandwidth_range( chan );
+
+ if ( bandwidth == 0.0 ) /* bandwidth of 0 means automatic filter selection */
+ bandwidth = _sample_rate * 0.75; /* select narrower filters to prevent aliasing */
+
+ if ( _dev ) {
+ /* compute best default value depending on sample rate (auto filter) */
+ uint32_t bw = hackrf_compute_baseband_filter_bw( uint32_t(bandwidth) );
+ ret = hackrf_set_baseband_filter_bandwidth( _dev, bw );
+ if ( HACKRF_SUCCESS == ret ) {
+ _bandwidth = bw;
+ } else {
+ HACKRF_THROW_ON_ERROR( ret, HACKRF_FUNC_STR( "hackrf_set_baseband_filter_bandwidth", bw ) )
+ }
+ }
+
+ return _bandwidth;
}
double hackrf_source_c::get_bandwidth( size_t chan )
{
- return hackrf_common::get_bandwidth(chan);
+ return _bandwidth;
}
osmosdr::freq_range_t hackrf_source_c::get_bandwidth_range( size_t chan )
{
- return hackrf_common::get_bandwidth_range(chan);
+ osmosdr::freq_range_t bandwidths;
+
+ // TODO: read out from libhackrf when an API is available
+
+ bandwidths += osmosdr::range_t( 1750000 );
+ bandwidths += osmosdr::range_t( 2500000 );
+ bandwidths += osmosdr::range_t( 3500000 );
+ bandwidths += osmosdr::range_t( 5000000 );
+ bandwidths += osmosdr::range_t( 5500000 );
+ bandwidths += osmosdr::range_t( 6000000 );
+ bandwidths += osmosdr::range_t( 7000000 );
+ bandwidths += osmosdr::range_t( 8000000 );
+ bandwidths += osmosdr::range_t( 9000000 );
+ bandwidths += osmosdr::range_t( 10000000 );
+ bandwidths += osmosdr::range_t( 12000000 );
+ bandwidths += osmosdr::range_t( 14000000 );
+ bandwidths += osmosdr::range_t( 15000000 );
+ bandwidths += osmosdr::range_t( 20000000 );
+ bandwidths += osmosdr::range_t( 24000000 );
+ bandwidths += osmosdr::range_t( 28000000 );
+
+ return bandwidths;
}
diff --git a/lib/hackrf/hackrf_source_c.h b/lib/hackrf/hackrf_source_c.h
index 0d38ac0..6ae81d2 100644
--- a/lib/hackrf/hackrf_source_c.h
+++ b/lib/hackrf/hackrf_source_c.h
@@ -1,35 +1,36 @@
/* -*- c++ -*- */
/*
* Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
- * Copyright 2020 Clayton Smith <argilo@gmail.com>
*
- * gr-osmosdr is free software; you can redistribute it and/or modify
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
- * gr-osmosdr is distributed in the hope that it will be useful,
+ * GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with gr-osmosdr; see the file COPYING. If not, write to
+ * along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_HACKRF_SOURCE_C_H
#define INCLUDED_HACKRF_SOURCE_C_H
+#include <gnuradio/thread/thread.h>
#include <gnuradio/sync_block.h>
-#include <condition_variable>
-#include <mutex>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
#include <libhackrf/hackrf.h>
#include "source_iface.h"
-#include "hackrf_common.h"
class hackrf_source_c;
@@ -61,12 +62,12 @@ hackrf_source_c_sptr make_hackrf_source_c (const std::string & args = "");
*/
class hackrf_source_c :
public gr::sync_block,
- public source_iface,
- protected hackrf_common
+ public source_iface
{
private:
// The friend declaration allows make_hackrf_source_c to
// access the private constructor.
+
friend hackrf_source_c_sptr make_hackrf_source_c (const std::string & args);
/*!
@@ -122,22 +123,35 @@ public:
private:
static int _hackrf_rx_callback(hackrf_transfer* transfer);
int hackrf_rx_callback(unsigned char *buf, uint32_t len);
+ static void _hackrf_wait(hackrf_source_c *obj);
+ void hackrf_wait();
+
+ static int _usage;
+ static boost::mutex _usage_mutex;
- std::vector<float> _lut;
+ std::vector<gr_complex> _lut;
- unsigned char **_buf;
+ hackrf_device *_dev;
+ gr::thread::thread _thread;
+ unsigned short **_buf;
unsigned int _buf_num;
unsigned int _buf_len;
unsigned int _buf_head;
unsigned int _buf_used;
- std::mutex _buf_mutex;
- std::condition_variable _buf_cond;
+ boost::mutex _buf_mutex;
+ boost::condition_variable _buf_cond;
unsigned int _buf_offset;
int _samp_avail;
+ double _sample_rate;
+ double _center_freq;
+ double _freq_corr;
+ bool _auto_gain;
+ double _amp_gain;
double _lna_gain;
double _vga_gain;
+ double _bandwidth;
};
#endif /* INCLUDED_HACKRF_SOURCE_C_H */
diff --git a/lib/xtrx/CMakeLists.txt b/lib/miri/CMakeLists.txt
index 9297bf0..ddaeb0a 100644
--- a/lib/xtrx/CMakeLists.txt
+++ b/lib/miri/CMakeLists.txt
@@ -21,15 +21,17 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
- ${LIBXTRX_INCLUDE_DIRS}
+ ${LIBMIRISDR_INCLUDE_DIRS}
)
-list(APPEND gr_osmosdr_srcs
- ${CMAKE_CURRENT_SOURCE_DIR}/xtrx_obj.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/xtrx_source_c.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/xtrx_sink_c.cc
+set(mirisdr_srcs
+ ${CMAKE_CURRENT_SOURCE_DIR}/miri_source_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+########################################################################
+# Append gnuradio-mirisdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${mirisdr_srcs})
+list(APPEND gr_osmosdr_libs ${LIBMIRISDR_LIBRARIES})
diff --git a/lib/miri/miri_source_c.cc b/lib/miri/miri_source_c.cc
new file mode 100644
index 0000000..c9f81fa
--- /dev/null
+++ b/lib/miri/miri_source_c.cc
@@ -0,0 +1,451 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
+ * Copyright 2012 Steve Markgraf <steve@steve-m.de>
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * config.h is generated by configure. It contains the results
+ * of probing for features, options etc. It should be the first
+ * file included in your .cc file.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "miri_source_c.h"
+#include <gnuradio/io_signature.h>
+
+#include <boost/assign.hpp>
+#include <boost/format.hpp>
+
+#include <stdexcept>
+#include <iostream>
+#include <stdio.h>
+
+#include <mirisdr.h>
+
+#include "arg_helpers.h"
+
+using namespace boost::assign;
+
+#define BUF_SIZE 2304 * 8 * 2
+#define BUF_NUM 15
+#define BUF_SKIP 1 // buffers to skip due to garbage
+
+#define BYTES_PER_SAMPLE 4 // mirisdr device delivers 16 bit signed IQ data
+ // containing 12 bits of information
+
+/*
+ * Create a new instance of miri_source_c and return
+ * a boost shared_ptr. This is effectively the public constructor.
+ */
+miri_source_c_sptr
+make_miri_source_c (const std::string &args)
+{
+ return gnuradio::get_initial_sptr(new miri_source_c (args));
+}
+
+/*
+ * Specify constraints on number of input and output streams.
+ * This info is used to construct the input and output signatures
+ * (2nd & 3rd args to gr::block's constructor). The input and
+ * output signatures are used by the runtime system to
+ * check that a valid number and type of inputs and outputs
+ * are connected to this block. In this case, we accept
+ * only 0 input and 1 output.
+ */
+static const int MIN_IN = 0; // mininum number of input streams
+static const int MAX_IN = 0; // maximum number of input streams
+static const int MIN_OUT = 1; // minimum number of output streams
+static const int MAX_OUT = 1; // maximum number of output streams
+
+/*
+ * The private constructor
+ */
+miri_source_c::miri_source_c (const std::string &args)
+ : gr::sync_block ("miri_source_c",
+ gr::io_signature::make(MIN_IN, MAX_IN, sizeof (gr_complex)),
+ gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof (gr_complex))),
+ _running(true),
+ _auto_gain(false),
+ _skipped(0)
+{
+ int ret;
+ unsigned int dev_index = 0;
+
+ dict_t dict = params_to_dict(args);
+
+ if (dict.count("miri"))
+ dev_index = boost::lexical_cast< unsigned int >( dict["miri"] );
+
+ _buf_num = _buf_head = _buf_used = _buf_offset = 0;
+ _samp_avail = BUF_SIZE / BYTES_PER_SAMPLE;
+
+ if (dict.count("buffers"))
+ _buf_num = boost::lexical_cast< unsigned int >( dict["buffers"] );
+
+ if (0 == _buf_num)
+ _buf_num = BUF_NUM;
+
+ if ( BUF_NUM != _buf_num ) {
+ std::cerr << "Using " << _buf_num << " buffers of size " << BUF_SIZE << "."
+ << std::endl;
+ }
+
+ if ( dev_index >= mirisdr_get_device_count() )
+ throw std::runtime_error("Wrong mirisdr device index given.");
+
+ std::cerr << "Using device #" << dev_index << ": "
+ << mirisdr_get_device_name(dev_index)
+ << std::endl;
+
+ _dev = NULL;
+ ret = mirisdr_open( &_dev, dev_index );
+ if (ret < 0)
+ throw std::runtime_error("Failed to open mirisdr device.");
+#if 0
+ ret = mirisdr_set_sample_rate( _dev, 500000 );
+ if (ret < 0)
+ throw std::runtime_error("Failed to set default samplerate.");
+
+ ret = mirisdr_set_tuner_gain_mode(_dev, int(!_auto_gain));
+ if (ret < 0)
+ throw std::runtime_error("Failed to enable manual gain mode.");
+#endif
+ ret = mirisdr_reset_buffer( _dev );
+ if (ret < 0)
+ throw std::runtime_error("Failed to reset usb buffers.");
+
+ _buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
+ _buf_lens = (unsigned int *) malloc(_buf_num * sizeof(unsigned int));
+
+ if (_buf && _buf_lens) {
+ for(unsigned int i = 0; i < _buf_num; ++i)
+ _buf[i] = (unsigned short *) malloc(BUF_SIZE);
+ }
+
+ _thread = gr::thread::thread(_mirisdr_wait, this);
+}
+
+/*
+ * Our virtual destructor.
+ */
+miri_source_c::~miri_source_c ()
+{
+ if (_dev) {
+ _running = false;
+ mirisdr_cancel_async( _dev );
+ _thread.join();
+ mirisdr_close( _dev );
+ _dev = NULL;
+ }
+
+ if (_buf) {
+ for(unsigned int i = 0; i < _buf_num; ++i) {
+ free(_buf[i]);
+ }
+
+ free(_buf);
+ _buf = NULL;
+ free(_buf_lens);
+ _buf_lens = NULL;
+ }
+}
+
+void miri_source_c::_mirisdr_callback(unsigned char *buf, uint32_t len, void *ctx)
+{
+ miri_source_c *obj = (miri_source_c *)ctx;
+ obj->mirisdr_callback(buf, len);
+}
+
+void miri_source_c::mirisdr_callback(unsigned char *buf, uint32_t len)
+{
+ if (_skipped < BUF_SKIP) {
+ _skipped++;
+ return;
+ }
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ if (len > BUF_SIZE)
+ throw std::runtime_error("Buffer too small.");
+
+ int buf_tail = (_buf_head + _buf_used) % _buf_num;
+ memcpy(_buf[buf_tail], buf, len);
+ _buf_lens[buf_tail] = len;
+
+ if (_buf_used == _buf_num) {
+ std::cerr << "O" << std::flush;
+ _buf_head = (_buf_head + 1) % _buf_num;
+ } else {
+ _buf_used++;
+ }
+ }
+
+ _buf_cond.notify_one();
+}
+
+void miri_source_c::_mirisdr_wait(miri_source_c *obj)
+{
+ obj->mirisdr_wait();
+}
+
+void miri_source_c::mirisdr_wait()
+{
+ int ret = mirisdr_read_async( _dev, _mirisdr_callback, (void *)this, _buf_num, BUF_SIZE );
+
+ _running = false;
+
+ if ( ret != 0 )
+ std::cerr << "mirisdr_read_async returned with " << ret << std::endl;
+
+ _buf_cond.notify_one();
+}
+
+int miri_source_c::work( int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items )
+{
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ while (_buf_used < 3 && _running) // collect at least 3 buffers
+ _buf_cond.wait( lock );
+ }
+
+ if (!_running)
+ return WORK_DONE;
+
+ short *buf = (short *)_buf[_buf_head] + _buf_offset;
+
+ if (noutput_items <= _samp_avail) {
+ for (int i = 0; i < noutput_items; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
+ float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
+
+ _buf_offset += noutput_items * 2;
+ _samp_avail -= noutput_items;
+ } else {
+ for (int i = 0; i < _samp_avail; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
+ float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ _buf_head = (_buf_head + 1) % _buf_num;
+ _buf_used--;
+ }
+
+ buf = (short *)_buf[_buf_head];
+
+ int remaining = noutput_items - _samp_avail;
+
+ for (int i = 0; i < remaining; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
+ float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
+
+ _buf_offset = remaining * 2;
+ _samp_avail = (_buf_lens[_buf_head] / BYTES_PER_SAMPLE) - remaining;
+ }
+
+ return noutput_items;
+}
+
+std::vector<std::string> miri_source_c::get_devices()
+{
+ std::vector<std::string> devices;
+
+ for (unsigned int i = 0; i < mirisdr_get_device_count(); i++) {
+ std::string args = "miri=" + boost::lexical_cast< std::string >( i );
+ args += ",label='" + std::string(mirisdr_get_device_name( i )) + "'";
+ devices.push_back( args );
+ }
+
+ return devices;
+}
+
+size_t miri_source_c::get_num_channels()
+{
+ return 1;
+}
+
+osmosdr::meta_range_t miri_source_c::get_sample_rates()
+{
+ osmosdr::meta_range_t range;
+
+ range += osmosdr::range_t( 8000000 ); // known to work
+
+ return range;
+}
+
+double miri_source_c::set_sample_rate(double rate)
+{
+ if (_dev) {
+ mirisdr_set_sample_rate( _dev, (uint32_t)rate );
+ }
+
+ return get_sample_rate();
+}
+
+double miri_source_c::get_sample_rate()
+{
+ if (_dev)
+ return (double)mirisdr_get_sample_rate( _dev );
+
+ return 0;
+}
+
+osmosdr::freq_range_t miri_source_c::get_freq_range( size_t chan )
+{
+ osmosdr::freq_range_t range;
+
+ range += osmosdr::range_t( 150e3, 30e6 ); /* LW/MW/SW (150 kHz - 30 MHz) */
+ range += osmosdr::range_t( 64e6, 108e6 ); /* VHF Band II (64 - 108 MHz) */
+ range += osmosdr::range_t( 162e6, 240e6 ); /* Band III (162 - 240 MHz) */
+ range += osmosdr::range_t( 470e6, 960e6 ); /* Band IV/V (470 - 960 MHz) */
+ range += osmosdr::range_t( 1450e6, 1675e6 ); /* L-Band (1450 - 1675 MHz) */
+
+ return range;
+}
+
+double miri_source_c::set_center_freq( double freq, size_t chan )
+{
+ if (_dev)
+ mirisdr_set_center_freq( _dev, (uint32_t)freq );
+
+ return get_center_freq( chan );
+}
+
+double miri_source_c::get_center_freq( size_t chan )
+{
+ if (_dev)
+ return (double)mirisdr_get_center_freq( _dev );
+
+ return 0;
+}
+
+double miri_source_c::set_freq_corr( double ppm, size_t chan )
+{
+ return get_freq_corr( chan );
+}
+
+double miri_source_c::get_freq_corr( size_t chan )
+{
+ return 0;
+}
+
+std::vector<std::string> miri_source_c::get_gain_names( size_t chan )
+{
+ std::vector< std::string > gains;
+
+ gains += "LNA";
+
+ return gains;
+}
+
+osmosdr::gain_range_t miri_source_c::get_gain_range( size_t chan )
+{
+ osmosdr::gain_range_t range;
+
+ if (_dev) {
+ int count = mirisdr_get_tuner_gains(_dev, NULL);
+ if (count > 0) {
+ int* gains = new int[ count ];
+ count = mirisdr_get_tuner_gains(_dev, gains);
+ for (int i = 0; i < count; i++)
+ range += osmosdr::range_t( gains[i] / 10.0 );
+ delete[] gains;
+ }
+ }
+
+ return range;
+}
+
+osmosdr::gain_range_t miri_source_c::get_gain_range( const std::string & name, size_t chan )
+{
+ return get_gain_range( chan );
+}
+
+bool miri_source_c::set_gain_mode( bool automatic, size_t chan )
+{
+ if (_dev) {
+ if (!mirisdr_set_tuner_gain_mode(_dev, int(!automatic))) {
+ _auto_gain = automatic;
+ }
+ }
+
+ return get_gain_mode(chan);
+}
+
+bool miri_source_c::get_gain_mode( size_t chan )
+{
+ return _auto_gain;
+}
+
+double miri_source_c::set_gain( double gain, size_t chan )
+{
+ osmosdr::gain_range_t rf_gains = miri_source_c::get_gain_range( chan );
+
+ if (_dev) {
+ mirisdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) );
+ }
+
+ return get_gain( chan );
+}
+
+double miri_source_c::set_gain( double gain, const std::string & name, size_t chan)
+{
+ return set_gain( gain, chan );
+}
+
+double miri_source_c::get_gain( size_t chan )
+{
+ if ( _dev )
+ return ((double)mirisdr_get_tuner_gain( _dev )) / 10.0;
+
+ return 0;
+}
+
+double miri_source_c::get_gain( const std::string & name, size_t chan )
+{
+ return get_gain( chan );
+}
+
+std::vector< std::string > miri_source_c::get_antennas( size_t chan )
+{
+ std::vector< std::string > antennas;
+
+ antennas += get_antenna( chan );
+
+ return antennas;
+}
+
+std::string miri_source_c::set_antenna( const std::string & antenna, size_t chan )
+{
+ return get_antenna( chan );
+}
+
+std::string miri_source_c::get_antenna( size_t chan )
+{
+ return "RX";
+}
diff --git a/lib/airspyhf/airspyhf_source_c.h b/lib/miri/miri_source_c.h
index dbdd87a..5363db5 100644
--- a/lib/airspyhf/airspyhf_source_c.h
+++ b/lib/miri/miri_source_c.h
@@ -1,8 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2013 Dimitri Stolnikov <horiz0n@gmx.net>
- *
- * This file is part of GNU Radio
+ * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,54 +17,63 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_AIRSPYHF_SOURCE_C_H
-#define INCLUDED_AIRSPYHF_SOURCE_C_H
-
-#include <boost/circular_buffer.hpp>
-
-#include <mutex>
-#include <condition_variable>
+#ifndef INCLUDED_MIRI_SOURCE_C_H
+#define INCLUDED_MIRI_SOURCE_C_H
#include <gnuradio/sync_block.h>
-#include <libairspyhf/airspyhf.h>
+#include <gnuradio/thread/thread.h>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
#include "source_iface.h"
-class airspyhf_source_c;
+class miri_source_c;
+typedef struct mirisdr_dev mirisdr_dev_t;
-typedef boost::shared_ptr<airspyhf_source_c> airspyhf_source_c_sptr;
+/*
+ * We use boost::shared_ptr's instead of raw pointers for all access
+ * to gr::blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+ * C++ / Python system.
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+ * As a convention, the _sptr suffix indicates a boost::shared_ptr
+ */
+typedef boost::shared_ptr<miri_source_c> miri_source_c_sptr;
/*!
- * \brief Return a shared_ptr to a new instance of airspyhf_source_c.
+ * \brief Return a shared_ptr to a new instance of miri_source_c.
*
- * To avoid accidental use of raw pointers, airspyhf_source_c's
- * constructor is private. make_airspyhf_source_c is the public
+ * To avoid accidental use of raw pointers, miri_source_c's
+ * constructor is private. make_miri_source_c is the public
* interface for creating new instances.
*/
-airspyhf_source_c_sptr make_airspyhf_source_c (const std::string & args = "");
+miri_source_c_sptr make_miri_source_c (const std::string & args = "");
/*!
* \brief Provides a stream of complex samples.
* \ingroup block
*/
-class airspyhf_source_c :
+class miri_source_c :
public gr::sync_block,
public source_iface
{
private:
- // The friend declaration allows make_airspyhf_source_c to
+ // The friend declaration allows make_miri_source_c to
// access the private constructor.
- friend airspyhf_source_c_sptr make_airspyhf_source_c (const std::string & args);
-
- airspyhf_source_c (const std::string & args);
+ friend miri_source_c_sptr make_miri_source_c (const std::string & args);
-public:
- ~airspyhf_source_c ();
+ /*!
+ * \brief Provides a stream of complex samples.
+ */
+ miri_source_c (const std::string & args); // private constructor
- bool start();
- bool stop();
+ public:
+ ~miri_source_c (); // public destructor
int work( int noutput_items,
gr_vector_const_void_star &input_items,
@@ -89,6 +96,8 @@ public:
std::vector<std::string> get_gain_names( size_t chan = 0 );
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
+ bool set_gain_mode( bool automatic, size_t chan = 0 );
+ bool get_gain_mode( size_t chan = 0 );
double set_gain( double gain, size_t chan = 0 );
double set_gain( double gain, const std::string & name, size_t chan = 0 );
double get_gain( size_t chan = 0 );
@@ -98,21 +107,28 @@ public:
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
std::string get_antenna( size_t chan = 0 );
-
private:
- static int _airspyhf_rx_callback(airspyhf_transfer_t* transfer);
- int airspyhf_rx_callback(void *samples, int sample_count);
-
- airspyhf_device *_dev;
-
- boost::circular_buffer<gr_complex> *_fifo;
- std::mutex _fifo_lock;
- std::condition_variable _samp_avail;
-
- std::vector< std::pair<double, uint32_t> > _sample_rates;
- double _sample_rate;
- double _center_freq;
- double _freq_corr;
+ static void _mirisdr_callback(unsigned char *buf, uint32_t len, void *ctx);
+ void mirisdr_callback(unsigned char *buf, uint32_t len);
+ static void _mirisdr_wait(miri_source_c *obj);
+ void mirisdr_wait();
+
+ mirisdr_dev_t *_dev;
+ gr::thread::thread _thread;
+ unsigned short **_buf;
+ unsigned int *_buf_lens;
+ unsigned int _buf_num;
+ unsigned int _buf_head;
+ unsigned int _buf_used;
+ boost::mutex _buf_mutex;
+ boost::condition_variable _buf_cond;
+ bool _running;
+
+ unsigned int _buf_offset;
+ int _samp_avail;
+
+ bool _auto_gain;
+ unsigned int _skipped;
};
-#endif /* INCLUDED_AIRSPY_SOURCE_C_H */
+#endif /* INCLUDED_MIRI_SOURCE_C_H */
diff --git a/lib/airspyhf/CMakeLists.txt b/lib/osmosdr/CMakeLists.txt
index fc13ce2..b0872f8 100644
--- a/lib/airspyhf/CMakeLists.txt
+++ b/lib/osmosdr/CMakeLists.txt
@@ -1,19 +1,19 @@
-# Copyright 2017 Free Software Foundation, Inc.
+# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,17 +21,17 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
- ${LIBAIRSPYHF_INCLUDE_DIRS}
+ ${LIBOSMOSDR_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- ${Gnuradio-blocks_LIBRARIES}
- ${LIBAIRSPYHF_LIBRARIES}
+set(osmosdr_srcs
+ ${CMAKE_CURRENT_SOURCE_DIR}/osmosdr_src_c.cc
)
-list(APPEND gr_osmosdr_srcs
- ${CMAKE_CURRENT_SOURCE_DIR}/airspyhf_source_c.cc
-)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${osmosdr_srcs})
+list(APPEND gr_osmosdr_libs ${LIBOSMOSDR_LIBRARIES})
diff --git a/lib/osmosdr/osmosdr_src_c.cc b/lib/osmosdr/osmosdr_src_c.cc
new file mode 100644
index 0000000..de65373
--- /dev/null
+++ b/lib/osmosdr/osmosdr_src_c.cc
@@ -0,0 +1,533 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * config.h is generated by configure. It contains the results
+ * of probing for features, options etc. It should be the first
+ * file included in your .cc file.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "osmosdr_src_c.h"
+#include <gnuradio/io_signature.h>
+
+#include <boost/assign.hpp>
+#include <boost/format.hpp>
+
+#include <stdexcept>
+#include <iostream>
+#include <stdio.h>
+
+#include <osmosdr.h>
+
+#include "arg_helpers.h"
+
+using namespace boost::assign;
+
+#define BUF_LEN (16 * 32 * 512) /* must be multiple of 512 */
+#define BUF_NUM 15
+#define BUF_SKIP 1 // buffers to skip due to garbage
+
+#define BYTES_PER_SAMPLE 4 // osmosdr device delivers 16 bit signed IQ data
+
+/*
+ * Create a new instance of osmosdr_src_c and return
+ * a boost shared_ptr. This is effectively the public constructor.
+ */
+osmosdr_src_c_sptr
+osmosdr_make_src_c (const std::string &args)
+{
+ return gnuradio::get_initial_sptr(new osmosdr_src_c (args));
+}
+
+/*
+ * The private constructor
+ */
+osmosdr_src_c::osmosdr_src_c (const std::string &args)
+ : gr::sync_block ("osmosdr_src_c",
+ gr::io_signature::make(0, 0, sizeof (gr_complex)),
+ gr::io_signature::make(1, 1, sizeof (gr_complex)) ),
+ _dev(NULL),
+ _buf(NULL),
+ _running(true),
+ _auto_gain(false),
+ _if_gain(0),
+ _skipped(0)
+{
+ int ret;
+ unsigned int dev_index = 0;
+
+ dict_t dict = params_to_dict(args);
+
+ if (dict.count("osmosdr"))
+ dev_index = boost::lexical_cast< unsigned int >( dict["osmosdr"] );
+
+ _buf_num = _buf_len = _buf_head = _buf_used = _buf_offset = 0;
+
+ if (dict.count("buffers"))
+ _buf_num = boost::lexical_cast< unsigned int >( dict["buffers"] );
+
+ if (dict.count("buflen"))
+ _buf_len = boost::lexical_cast< unsigned int >( dict["buflen"] );
+
+ if (0 == _buf_num)
+ _buf_num = BUF_NUM;
+
+ if (0 == _buf_len || _buf_len % 512 != 0) /* len must be multiple of 512 */
+ _buf_len = BUF_LEN;
+
+ if ( BUF_NUM != _buf_num || BUF_LEN != _buf_len ) {
+ std::cerr << "Using " << _buf_num << " buffers of size " << _buf_len << "."
+ << std::endl;
+ }
+
+ _samp_avail = _buf_len / BYTES_PER_SAMPLE;
+
+ if ( dev_index >= osmosdr_get_device_count() )
+ throw std::runtime_error("Wrong osmosdr device index given.");
+
+ std::cerr << "Using device #" << dev_index << ": "
+ << osmosdr_get_device_name(dev_index)
+ << std::endl;
+
+ _dev = NULL;
+ ret = osmosdr_open( &_dev, dev_index );
+ if (ret < 0)
+ throw std::runtime_error("Failed to open osmosdr device.");
+
+ ret = osmosdr_set_fpga_iq_swap(_dev, 0);
+ if (ret < 0)
+ throw std::runtime_error("Failed to disable IQ swapping.");
+
+ ret = osmosdr_set_sample_rate( _dev, 500000 );
+ if (ret < 0)
+ throw std::runtime_error("Failed to set default samplerate.");
+
+ ret = osmosdr_set_tuner_gain_mode(_dev, int(!_auto_gain));
+ if (ret < 0)
+ throw std::runtime_error("Failed to enable manual gain mode.");
+
+ ret = osmosdr_reset_buffer( _dev );
+ if (ret < 0)
+ throw std::runtime_error("Failed to reset usb buffers.");
+
+ set_if_gain( 24 ); /* preset to a reasonable default (non-GRC use case) */
+
+ _buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
+
+ if (_buf) {
+ for(unsigned int i = 0; i < _buf_num; ++i)
+ _buf[i] = (unsigned short *) malloc(_buf_len);
+ }
+
+ _thread = gr::thread::thread(_osmosdr_wait, this);
+}
+
+/*
+ * Our virtual destructor.
+ */
+osmosdr_src_c::~osmosdr_src_c ()
+{
+ if (_dev) {
+ _running = false;
+ osmosdr_cancel_async( _dev );
+ _thread.join();
+ osmosdr_close( _dev );
+ _dev = NULL;
+ }
+
+ if (_buf) {
+ for(unsigned int i = 0; i < _buf_num; ++i) {
+ free(_buf[i]);
+ }
+
+ free(_buf);
+ _buf = NULL;
+ }
+}
+
+void osmosdr_src_c::_osmosdr_callback(unsigned char *buf, uint32_t len, void *ctx)
+{
+ osmosdr_src_c *obj = (osmosdr_src_c *)ctx;
+ obj->osmosdr_callback(buf, len);
+}
+
+void osmosdr_src_c::osmosdr_callback(unsigned char *buf, uint32_t len)
+{
+ if (_skipped < BUF_SKIP) {
+ _skipped++;
+ return;
+ }
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ int buf_tail = (_buf_head + _buf_used) % _buf_num;
+ memcpy(_buf[buf_tail], buf, len);
+
+ if (_buf_used == _buf_num) {
+ std::cerr << "O" << std::flush;
+ _buf_head = (_buf_head + 1) % _buf_num;
+ } else {
+ _buf_used++;
+ }
+ }
+
+ _buf_cond.notify_one();
+}
+
+void osmosdr_src_c::_osmosdr_wait(osmosdr_src_c *obj)
+{
+ obj->osmosdr_wait();
+}
+
+void osmosdr_src_c::osmosdr_wait()
+{
+ int ret = osmosdr_read_async( _dev, _osmosdr_callback, (void *)this, _buf_num, _buf_len );
+
+ _running = false;
+
+ if ( ret != 0 )
+ std::cerr << "osmosdr_read_async returned with " << ret << std::endl;
+
+ _buf_cond.notify_one();
+}
+
+int osmosdr_src_c::work( int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items )
+{
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ while (_buf_used < 3 && _running) // collect at least 3 buffers
+ _buf_cond.wait( lock );
+ }
+
+ if (!_running)
+ return WORK_DONE;
+
+ short *buf = (short *)_buf[_buf_head] + _buf_offset;
+
+ if (noutput_items <= _samp_avail) {
+ for (int i = 0; i < noutput_items; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/32767.5f),
+ float(*(buf + i * 2 + 1)) * (1.0f/32767.5f) );
+
+ _buf_offset += noutput_items * 2;
+ _samp_avail -= noutput_items;
+ } else {
+ for (int i = 0; i < _samp_avail; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/32767.5f),
+ float(*(buf + i * 2 + 1)) * (1.0f/32767.5f) );
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ _buf_head = (_buf_head + 1) % _buf_num;
+ _buf_used--;
+ }
+
+ buf = (short *)_buf[_buf_head];
+
+ int remaining = noutput_items - _samp_avail;
+
+ for (int i = 0; i < remaining; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/32767.5f),
+ float(*(buf + i * 2 + 1)) * (1.0f/32767.5f) );
+
+ _buf_offset = remaining * 2;
+ _samp_avail = (_buf_len / BYTES_PER_SAMPLE) - remaining;
+ }
+
+ return noutput_items;
+}
+
+std::vector<std::string> osmosdr_src_c::get_devices()
+{
+ std::vector< std::string > devices;
+ char buffer[256];
+
+ for (unsigned int i = 0; i < osmosdr_get_device_count(); i++) {
+ std::string args = "osmosdr=" + boost::lexical_cast< std::string >( i );
+
+ std::string label = std::string(osmosdr_get_device_name( i ));
+
+ memset(buffer, 0, sizeof(buffer));
+ osmosdr_get_device_usb_strings( i, NULL, NULL, buffer );
+ std::string serial = std::string(buffer);
+
+ if (serial.length())
+ label += " " + serial;
+
+ args += ",label='" + label + + "'";
+
+ devices.push_back( args );
+ }
+
+ return devices;
+}
+
+size_t osmosdr_src_c::get_num_channels()
+{
+ return 1;
+}
+
+osmosdr::meta_range_t osmosdr_src_c::get_sample_rates()
+{
+ osmosdr::meta_range_t range;
+
+ if (_dev) {
+ int count = osmosdr_get_sample_rates(_dev, NULL);
+ if (count > 0) {
+ uint32_t* rates = new uint32_t[ count ];
+ count = osmosdr_get_sample_rates(_dev, rates);
+ for (int i = 0; i < count; i++)
+ range += osmosdr::range_t( rates[i] );
+ delete[] rates;
+ }
+ }
+
+ return range;
+}
+
+double osmosdr_src_c::set_sample_rate(double rate)
+{
+ if (_dev) {
+ osmosdr_set_sample_rate( _dev, (uint32_t)rate );
+ }
+
+ return get_sample_rate();
+}
+
+double osmosdr_src_c::get_sample_rate()
+{
+ if (_dev)
+ return (double)osmosdr_get_sample_rate( _dev );
+
+ return 0;
+}
+
+osmosdr::freq_range_t osmosdr_src_c::get_freq_range( size_t chan )
+{
+ osmosdr::freq_range_t range;
+
+ /* there is a (temperature dependent) gap between 1100 to 1250 MHz */
+ range += osmosdr::range_t( 52e6, 2.2e9 );
+
+ return range;
+}
+
+double osmosdr_src_c::set_center_freq( double freq, size_t chan )
+{
+ if (_dev)
+ osmosdr_set_center_freq( _dev, (uint32_t)freq );
+
+ return get_center_freq( chan );
+}
+
+double osmosdr_src_c::get_center_freq( size_t chan )
+{
+ if (_dev)
+ return (double)osmosdr_get_center_freq( _dev );
+
+ return 0;
+}
+
+double osmosdr_src_c::set_freq_corr( double ppm, size_t chan )
+{
+ return get_freq_corr( chan );
+}
+
+double osmosdr_src_c::get_freq_corr( size_t chan )
+{
+ return 0;
+}
+
+std::vector<std::string> osmosdr_src_c::get_gain_names( size_t chan )
+{
+ std::vector< std::string > names;
+
+ names += "LNA";
+ names += "IF";
+
+ return names;
+}
+
+osmosdr::gain_range_t osmosdr_src_c::get_gain_range( size_t chan )
+{
+ osmosdr::gain_range_t range;
+
+ if (_dev) {
+ int count = osmosdr_get_tuner_gains(_dev, NULL);
+ if (count > 0) {
+ int* gains = new int[ count ];
+ count = osmosdr_get_tuner_gains(_dev, gains);
+ for (int i = 0; i < count; i++)
+ range += osmosdr::range_t( gains[i] / 10.0 );
+ delete[] gains;
+ }
+ }
+
+ return range;
+}
+
+osmosdr::gain_range_t osmosdr_src_c::get_gain_range( const std::string & name, size_t chan )
+{
+ if ( "IF" == name ) {
+ return osmosdr::gain_range_t(3, 56, 1);
+ }
+
+ return get_gain_range( chan );
+}
+
+bool osmosdr_src_c::set_gain_mode( bool automatic, size_t chan )
+{
+ if (_dev) {
+ if (!osmosdr_set_tuner_gain_mode(_dev, int(!automatic))) {
+ _auto_gain = automatic;
+ }
+ }
+
+ return get_gain_mode(chan);
+}
+
+bool osmosdr_src_c::get_gain_mode( size_t chan )
+{
+ return _auto_gain;
+}
+
+double osmosdr_src_c::set_gain( double gain, size_t chan )
+{
+ osmosdr::gain_range_t rf_gains = osmosdr_src_c::get_gain_range( chan );
+
+ if (_dev) {
+ osmosdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) );
+ }
+
+ return get_gain( chan );
+}
+
+double osmosdr_src_c::set_gain( double gain, const std::string & name, size_t chan)
+{
+ if ( "IF" == name ) {
+ return set_if_gain( gain, chan );
+ }
+
+ return set_gain( gain, chan );
+}
+
+double osmosdr_src_c::get_gain( size_t chan )
+{
+ if ( _dev )
+ return ((double)osmosdr_get_tuner_gain( _dev )) / 10.0;
+
+ return 0;
+}
+
+double osmosdr_src_c::get_gain( const std::string & name, size_t chan )
+{
+ if ( "IF" == name ) {
+ return _if_gain;
+ }
+
+ return get_gain( chan );
+}
+
+double osmosdr_src_c::set_if_gain(double gain, size_t chan)
+{
+ std::vector< osmosdr::gain_range_t > if_gains;
+
+ if_gains += osmosdr::gain_range_t(-3, 6, 9);
+ if_gains += osmosdr::gain_range_t(0, 9, 3);
+ if_gains += osmosdr::gain_range_t(0, 9, 3);
+ if_gains += osmosdr::gain_range_t(0, 2, 1);
+ if_gains += osmosdr::gain_range_t(3, 15, 3);
+ if_gains += osmosdr::gain_range_t(3, 15, 3);
+
+ std::map< int, double > gains;
+
+ /* initialize with min gains */
+ for (unsigned int i = 0; i < if_gains.size(); i++) {
+ gains[ i + 1 ] = if_gains[ i ].start();
+ }
+
+ for (int i = if_gains.size() - 1; i >= 0; i--) {
+ osmosdr::gain_range_t range = if_gains[ i ];
+
+ double error = gain;
+
+ for( double g = range.start(); g <= range.stop(); g += range.step() ) {
+
+ double sum = 0;
+ for (int j = 0; j < int(gains.size()); j++) {
+ if ( i == j )
+ sum += g;
+ else
+ sum += gains[ j + 1 ];
+ }
+
+ double err = abs(gain - sum);
+ if (err < error) {
+ error = err;
+ gains[ i + 1 ] = g;
+ }
+ }
+ }
+#if 0
+ std::cerr << gain << " => "; double sum = 0;
+ for (unsigned int i = 0; i < gains.size(); i++) {
+ sum += gains[ i + 1 ];
+ std::cerr << gains[ i + 1 ] << " ";
+ }
+ std::cerr << " = " << sum << std::endl;
+#endif
+ if (_dev) {
+ for (unsigned int stage = 1; stage <= gains.size(); stage++) {
+ osmosdr_set_tuner_if_gain( _dev, stage, int(gains[ stage ] * 10.0));
+ }
+ }
+
+ _if_gain = gain;
+ return gain;
+}
+
+std::vector< std::string > osmosdr_src_c::get_antennas( size_t chan )
+{
+ std::vector< std::string > antennas;
+
+ antennas += get_antenna( chan );
+
+ return antennas;
+}
+
+std::string osmosdr_src_c::set_antenna( const std::string & antenna, size_t chan )
+{
+ return get_antenna( chan );
+}
+
+std::string osmosdr_src_c::get_antenna( size_t chan )
+{
+ return "RX";
+}
diff --git a/lib/osmosdr/osmosdr_src_c.h b/lib/osmosdr/osmosdr_src_c.h
new file mode 100644
index 0000000..0f62b09
--- /dev/null
+++ b/lib/osmosdr/osmosdr_src_c.h
@@ -0,0 +1,139 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_OSMOSDR_SRC_C_H
+#define INCLUDED_OSMOSDR_SRC_C_H
+
+#include <gnuradio/sync_block.h>
+
+#include <gnuradio/thread/thread.h>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+#include "source_iface.h"
+
+class osmosdr_src_c;
+typedef struct osmosdr_dev osmosdr_dev_t;
+
+/*
+ * We use boost::shared_ptr's instead of raw pointers for all access
+ * to gr::blocks (and many other data structures). The shared_ptr gets
+ * us transparent reference counting, which greatly simplifies storage
+ * management issues. This is especially helpful in our hybrid
+ * C++ / Python system.
+ *
+ * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
+ *
+ * As a convention, the _sptr suffix indicates a boost::shared_ptr
+ */
+typedef boost::shared_ptr<osmosdr_src_c> osmosdr_src_c_sptr;
+
+/*!
+ * \brief Return a shared_ptr to a new instance of osmosdr_src_c.
+ *
+ * To avoid accidental use of raw pointers, osmosdr_src_c's
+ * constructor is private. osmosdr_make_src_c is the public
+ * interface for creating new instances.
+ */
+osmosdr_src_c_sptr osmosdr_make_src_c (const std::string & args = "");
+
+/*!
+ * \brief Provides a stream of complex samples.
+ * \ingroup block
+ *
+ * \sa sink for a version that subclasses gr::hier_block2.
+ */
+class osmosdr_src_c :
+ public gr::sync_block,
+ public source_iface
+{
+private:
+ // The friend declaration allows osmosdr_make_src_c to
+ // access the private constructor.
+
+ friend osmosdr_src_c_sptr osmosdr_make_src_c (const std::string & args);
+
+ /*!
+ * \brief Provides a stream of complex samples.
+ */
+ osmosdr_src_c (const std::string & args); // private constructor
+
+ public:
+ ~osmosdr_src_c (); // public destructor
+
+ int work( int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items );
+
+ static std::vector< std::string > get_devices();
+
+ size_t get_num_channels( void );
+
+ osmosdr::meta_range_t get_sample_rates( void );
+ double set_sample_rate( double rate );
+ double get_sample_rate( void );
+
+ osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
+ double set_center_freq( double freq, size_t chan = 0 );
+ double get_center_freq( size_t chan = 0 );
+ double set_freq_corr( double ppm, size_t chan = 0 );
+ double get_freq_corr( size_t chan = 0 );
+
+ std::vector<std::string> get_gain_names( size_t chan = 0 );
+ osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
+ osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
+ bool set_gain_mode( bool automatic, size_t chan = 0 );
+ bool get_gain_mode( size_t chan = 0 );
+ double set_gain( double gain, size_t chan = 0 );
+ double set_gain( double gain, const std::string & name, size_t chan = 0 );
+ double get_gain( size_t chan = 0 );
+ double get_gain( const std::string & name, size_t chan = 0 );
+
+ double set_if_gain( double gain, size_t chan = 0 );
+
+ std::vector< std::string > get_antennas( size_t chan = 0 );
+ std::string set_antenna( const std::string & antenna, size_t chan = 0 );
+ std::string get_antenna( size_t chan = 0 );
+
+private:
+ static void _osmosdr_callback(unsigned char *buf, uint32_t len, void *ctx);
+ void osmosdr_callback(unsigned char *buf, uint32_t len);
+ static void _osmosdr_wait(osmosdr_src_c *obj);
+ void osmosdr_wait();
+
+ osmosdr_dev_t *_dev;
+ gr::thread::thread _thread;
+ unsigned short **_buf;
+ unsigned int _buf_num;
+ unsigned int _buf_len;
+ unsigned int _buf_head;
+ unsigned int _buf_used;
+ boost::mutex _buf_mutex;
+ boost::condition_variable _buf_cond;
+ bool _running;
+
+ unsigned int _buf_offset;
+ int _samp_avail;
+
+ bool _auto_gain;
+ double _if_gain;
+ unsigned int _skipped;
+};
+
+#endif /* INCLUDED_OSMOSDR_SRC_C_H */
diff --git a/lib/ranges.cc b/lib/ranges.cc
index 09c1dae..cdff969 100644
--- a/lib/ranges.cc
+++ b/lib/ranges.cc
@@ -18,6 +18,7 @@
#include <osmosdr/ranges.h>
#include <stdexcept>
#include <boost/math/special_functions/round.hpp>
+#include <boost/foreach.hpp>
#include <algorithm>
#include <sstream>
@@ -101,7 +102,7 @@ meta_range_t::meta_range_t(
double meta_range_t::start(void) const{
check_meta_range_monotonic(*this);
double min_start = this->front().start();
- for (const range_t &r : (*this)){
+ BOOST_FOREACH(const range_t &r, (*this)){
min_start = std::min(min_start, r.start());
}
return min_start;
@@ -110,7 +111,7 @@ double meta_range_t::start(void) const{
double meta_range_t::stop(void) const{
check_meta_range_monotonic(*this);
double max_stop = this->front().stop();
- for (const range_t &r : (*this)){
+ BOOST_FOREACH(const range_t &r, (*this)){
max_stop = std::max(max_stop, r.stop());
}
return max_stop;
@@ -120,7 +121,7 @@ double meta_range_t::step(void) const{
check_meta_range_monotonic(*this);
std::vector<double> non_zero_steps;
range_t last = this->front();
- for (const range_t &r : (*this)){
+ BOOST_FOREACH(const range_t &r, (*this)){
//steps at each range
if (r.step() > 0) non_zero_steps.push_back(r.step());
//and steps in-between ranges
@@ -136,7 +137,7 @@ double meta_range_t::step(void) const{
double meta_range_t::clip(double value, bool clip_step) const{
check_meta_range_monotonic(*this);
double last_stop = this->front().stop();
- for (const range_t &r : (*this)){
+ BOOST_FOREACH(const range_t &r, (*this)){
//in-between ranges, clip to nearest
if (value < r.start()){
return (std::abs(value - r.start()) < std::abs(value - last_stop))?
@@ -156,7 +157,7 @@ double meta_range_t::clip(double value, bool clip_step) const{
std::vector<double> meta_range_t::values() const {
std::vector<double> values;
- for (const range_t &r : (*this)) {
+ BOOST_FOREACH(const range_t &r, (*this)) {
if (r.start() != r.stop()) {
if ( r.step() == 0 ) {
values.push_back( r.start() );
@@ -176,7 +177,7 @@ std::vector<double> meta_range_t::values() const {
const std::string meta_range_t::to_pp_string(void) const{
std::stringstream ss;
- for (const range_t &r : (*this)){
+ BOOST_FOREACH(const range_t &r, (*this)){
ss << r.to_pp_string() << std::endl;
}
return ss.str();
diff --git a/lib/redpitaya/CMakeLists.txt b/lib/redpitaya/CMakeLists.txt
index 78f816b..a14dc9e 100644
--- a/lib/redpitaya/CMakeLists.txt
+++ b/lib/redpitaya/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,17 +21,18 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
-APPEND_LIB_LIST(
- ${Gnuradio-blocks_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(redpitaya_srcs
${CMAKE_CURRENT_SOURCE_DIR}/redpitaya_source_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/redpitaya_sink_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/redpitaya_common.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${redpitaya_srcs})
+#list(APPEND gr_osmosdr_libs ${GNURADIO_BLOCKS_LIBRARIES})
diff --git a/lib/rfspace/CMakeLists.txt b/lib/rfspace/CMakeLists.txt
index c096550..eebc15d 100644
--- a/lib/rfspace/CMakeLists.txt
+++ b/lib/rfspace/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,11 +21,17 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
-list(APPEND gr_osmosdr_srcs
+set(rfspace_srcs
${CMAKE_CURRENT_SOURCE_DIR}/rfspace_source_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${rfspace_srcs})
+#list(APPEND gr_osmosdr_libs ...)
+
diff --git a/lib/rfspace/rfspace_source_c.cc b/lib/rfspace/rfspace_source_c.cc
index 314dfc7..80f34df 100644
--- a/lib/rfspace/rfspace_source_c.cc
+++ b/lib/rfspace/rfspace_source_c.cc
@@ -27,6 +27,7 @@
#include "config.h"
#endif
+#ifndef USE_ASIO
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -34,6 +35,7 @@
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <netdb.h>
+#endif
#include <fcntl.h>
#include <unistd.h>
@@ -52,6 +54,9 @@
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
+#ifdef USE_ASIO
+#include <boost/asio/deadline_timer.hpp>
+#endif
#include <gnuradio/io_signature.h>
@@ -59,6 +64,9 @@
#include "rfspace_source_c.h"
using namespace boost::assign;
+#ifdef USE_ASIO
+using boost::asio::deadline_timer;
+#endif
#define DEFAULT_HOST "127.0.0.1" /* We assume a running "siqs" from CuteSDR project */
#define DEFAULT_PORT 50000
@@ -94,8 +102,15 @@ rfspace_source_c::rfspace_source_c (const std::string &args)
gr::io_signature::make (MIN_IN, MAX_IN, sizeof (gr_complex)),
gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (gr_complex))),
_radio(RADIO_UNKNOWN),
+#ifdef USE_ASIO
+ _io_service(),
+ _resolver(_io_service),
+ _t(_io_service),
+ _u(_io_service),
+#else
_tcp(-1),
_udp(-1),
+#endif
_usb(-1),
_running(false),
_keep_running(false),
@@ -224,6 +239,30 @@ rfspace_source_c::rfspace_source_c (const std::string &args)
/* SDR-IP 4.4.4 Data Output UDP IP and Port Address */
/* NETSDR 4.4.3 Data Output UDP IP and Port Address */
+#ifdef USE_ASIO
+
+ tcp::resolver::query query(tcp::v4(), host.c_str(), port_str.c_str());
+ tcp::resolver::iterator iterator = _resolver.resolve(query);
+
+ boost::system::error_code ec;
+
+ boost::asio::connect(_t, iterator, ec);
+ if ( ec )
+ throw std::runtime_error(ec.message() + " (" + host + ":" + port_str + ")");
+
+ _u.open(udp::v4(), ec);
+ if ( ec )
+ throw std::runtime_error(ec.message());
+
+ _u.bind(udp::endpoint(udp::v4(), DEFAULT_PORT), ec);
+ if ( ec )
+ throw std::runtime_error(ec.message());
+
+ _u.set_option(udp::socket::reuse_address(true));
+ _t.set_option(udp::socket::reuse_address(true));
+
+#else
+
if ( (_tcp = socket(AF_INET, SOCK_STREAM, 0) ) < 0)
{
throw std::runtime_error("Could not create TCP socket");
@@ -300,6 +339,8 @@ rfspace_source_c::rfspace_source_c (const std::string &args)
throw std::runtime_error("Bind of UDP socket failed: " + std::string(strerror(errno)));
}
+#endif
+
}
/* Wait 10 ms before sending queries to device (required for networked radios). */
@@ -465,8 +506,10 @@ rfspace_source_c::rfspace_source_c (const std::string &args)
*/
rfspace_source_c::~rfspace_source_c ()
{
+#ifndef USE_ASIO
close(_tcp);
close(_udp);
+#endif
if ( RFSPACE_SDR_IQ == _radio )
{
@@ -547,7 +590,7 @@ bool rfspace_source_c::transaction( const unsigned char *cmd, size_t size,
if ( write(_usb, cmd, size) != (int)size )
return false;
- std::unique_lock<std::mutex> lock(_resp_lock);
+ boost::unique_lock<boost::mutex> lock(_resp_lock);
_resp_avail.wait(lock);
rx_bytes = _resp.size();
@@ -555,8 +598,13 @@ bool rfspace_source_c::transaction( const unsigned char *cmd, size_t size,
}
else
{
- std::lock_guard<std::mutex> lock(_tcp_lock);
+ boost::mutex::scoped_lock lock(_tcp_lock);
+
+#ifdef USE_ASIO
+ _t.write_some( boost::asio::buffer(cmd, size) );
+ rx_bytes = _t.read_some( boost::asio::buffer(data, sizeof(data)) );
+#else
if ( write(_tcp, cmd, size) != (int)size )
return false;
@@ -576,6 +624,7 @@ bool rfspace_source_c::transaction( const unsigned char *cmd, size_t size,
return false;
rx_bytes = 2 + length; /* header + payload */
+#endif
}
response.resize( rx_bytes );
@@ -780,7 +829,7 @@ int rfspace_source_c::work( int noutput_items,
{
gr_complex *out = (gr_complex *)output_items[0];
- std::unique_lock<std::mutex> lock(_fifo_lock);
+ boost::unique_lock<boost::mutex> lock(_fifo_lock);
/* Wait until we have the requested number of samples */
int n_samples_avail = _fifo->size();
@@ -803,6 +852,10 @@ int rfspace_source_c::work( int noutput_items,
return noutput_items;
}
+#ifdef USE_ASIO
+ udp::endpoint ep;
+ size_t rx_bytes = _u.receive_from( boost::asio::buffer(data, sizeof(data)), ep );
+#else
struct sockaddr_in sa_in; /* remote address */
socklen_t addrlen = sizeof(sa_in); /* length of addresses */
ssize_t rx_bytes = recvfrom(_udp, data, sizeof(data), 0, (struct sockaddr *)&sa_in, &addrlen);
@@ -811,6 +864,7 @@ int rfspace_source_c::work( int noutput_items,
std::cerr << "recvfrom returned " << rx_bytes << std::endl;
return WORK_DONE;
}
+#endif
#define HEADER_SIZE 2
#define SEQNUM_SIZE 2
@@ -838,7 +892,11 @@ int rfspace_source_c::work( int noutput_items,
if ( diff > 1 )
{
std::cerr << "Lost " << diff << " packets from "
+#ifdef USE_ASIO
+ << ep
+#else
<< inet_ntoa(sa_in.sin_addr) << ":" << ntohs(sa_in.sin_port)
+#endif
<< std::endl;
}
@@ -919,11 +977,48 @@ typedef struct
uint16_t port;
} unit_t;
+#ifdef USE_ASIO
+static void handle_receive( const boost::system::error_code& ec,
+ std::size_t length,
+ boost::system::error_code* out_ec,
+ std::size_t* out_length )
+{
+ *out_ec = ec;
+ *out_length = length;
+}
+
+static void handle_timer( const boost::system::error_code& ec,
+ boost::system::error_code* out_ec )
+{
+ *out_ec = boost::asio::error::timed_out;
+}
+#endif
static std::vector < unit_t > discover_netsdr()
{
std::vector < unit_t > units;
+#ifdef USE_ASIO
+ boost::system::error_code ec;
+ boost::asio::io_service ios;
+ udp::socket socket(ios);
+ deadline_timer timer(ios);
+
+ timer.expires_at(boost::posix_time::pos_infin);
+
+ socket.open(udp::v4(), ec);
+
+ if ( ec )
+ return units;
+
+ socket.bind(udp::endpoint(udp::v4(), DISCOVER_CLIENT_PORT), ec);
+
+ if ( ec )
+ return units;
+
+ socket.set_option(udp::socket::reuse_address(true));
+ socket.set_option(boost::asio::socket_base::broadcast(true));
+#else
int sock;
if ( (sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
@@ -963,6 +1058,7 @@ static std::vector < unit_t > discover_netsdr()
close(sock);
return units;
}
+#endif
discover_common_msg_t tx_msg;
memset( (void *)&tx_msg, 0, sizeof(discover_common_msg_t) );
@@ -971,18 +1067,64 @@ static std::vector < unit_t > discover_netsdr()
tx_msg.key[0] = KEY0;
tx_msg.key[1] = KEY1;
tx_msg.op = MSG_REQ;
+#ifdef USE_ASIO
+ udp::endpoint ep(boost::asio::ip::address_v4::broadcast(), DISCOVER_SERVER_PORT);
+ socket.send_to(boost::asio::buffer(&tx_msg, sizeof(tx_msg)), ep);
+#else
sendto(sock, &tx_msg, sizeof(tx_msg), 0, (struct sockaddr *)&peer_sa, sizeof(peer_sa));
+#endif
while ( true )
{
std::size_t rx_bytes = 0;
unsigned char data[1024*2];
+#ifdef USE_ASIO
+ // Set up the variables that receive the result of the asynchronous
+ // operation. The error code is set to would_block to signal that the
+ // operation is incomplete. Asio guarantees that its asynchronous
+ // operations will never fail with would_block, so any other value in
+ // ec indicates completion.
+ ec = boost::asio::error::would_block;
+
+ // Start the asynchronous receive operation. The handle_receive function
+ // used as a callback will update the ec and rx_bytes variables.
+ socket.async_receive( boost::asio::buffer(data, sizeof(data)),
+ boost::bind(handle_receive, _1, _2, &ec, &rx_bytes) );
+
+ // Set a deadline for the asynchronous operation.
+ timer.expires_from_now( boost::posix_time::milliseconds(10) );
+
+ // Start an asynchronous wait on the timer. The handle_timer function
+ // used as a callback will update the ec variable.
+ timer.async_wait( boost::bind(handle_timer, _1, &ec) );
+
+ // Reset the io_service in preparation for a subsequent run_one() invocation.
+ ios.reset();
+
+ // Block until at least one asynchronous operation has completed.
+ do ios.run_one(); while ( ec == boost::asio::error::would_block );
+
+ if ( boost::asio::error::timed_out == ec ) /* timer was first to complete */
+ {
+ // Please note that cancel() has portability issues on some versions of
+ // Microsoft Windows, and it may be necessary to use close() instead.
+ // Consult the documentation for cancel() for further information.
+ socket.cancel();
+
+ break;
+ }
+ else /* socket was first to complete */
+ {
+ timer.cancel();
+ }
+#else
socklen_t addrlen = sizeof(peer_sa); /* length of addresses */
int nbytes = recvfrom(sock, data, sizeof(data), 0, (struct sockaddr *)&peer_sa, &addrlen);
if ( nbytes <= 0 )
break;
rx_bytes = nbytes;
+#endif
if ( rx_bytes >= sizeof(discover_common_msg_t) )
{
@@ -1009,7 +1151,11 @@ static std::vector < unit_t > discover_netsdr()
}
}
}
+#ifdef USE_ASIO
+ socket.close(ec);
+#else
close(sock);
+#endif
return units;
}
@@ -1150,7 +1296,7 @@ std::vector<std::string> rfspace_source_c::get_devices( bool fake )
std::vector < unit_t > units = discover_netsdr();
- for (unit_t u : units)
+ BOOST_FOREACH( unit_t u, units )
{
// std::cerr << u.name << " " << u.sn << " " << u.addr << ":" << u.port
// << std::endl;
@@ -1164,7 +1310,7 @@ std::vector<std::string> rfspace_source_c::get_devices( bool fake )
units = discover_sdr_iq();
- for (unit_t u : units)
+ BOOST_FOREACH( unit_t u, units )
{
// std::cerr << u.name << " " << u.sn << " " << u.addr << ":" << u.port
// << std::endl;
diff --git a/lib/rfspace/rfspace_source_c.h b/lib/rfspace/rfspace_source_c.h
index d2bf66d..c656063 100644
--- a/lib/rfspace/rfspace_source_c.h
+++ b/lib/rfspace/rfspace_source_c.h
@@ -20,17 +20,25 @@
#ifndef INCLUDED_RFSPACE_SOURCE_C_H
#define INCLUDED_RFSPACE_SOURCE_C_H
+//#define USE_ASIO
+
+#ifdef USE_ASIO
+#include <boost/asio.hpp>
+#endif
#include <gnuradio/thread/thread.h>
#include <gnuradio/block.h>
#include <gnuradio/sync_block.h>
#include <boost/circular_buffer.hpp>
-
-#include <mutex>
-#include <condition_variable>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
#include "osmosdr/ranges.h"
#include "source_iface.h"
+#ifdef USE_ASIO
+using boost::asio::ip::tcp;
+using boost::asio::ip::udp;
+#endif
class rfspace_source_c;
#ifndef SOCKET
@@ -135,8 +143,15 @@ private: /* members */
radio_type _radio;
+#ifdef USE_ASIO
+ boost::asio::io_service _io_service;
+ tcp::resolver _resolver;
+ tcp::socket _t;
+ udp::socket _u;
+#else
SOCKET _tcp;
SOCKET _udp;
+#endif
int _usb;
bool _running;
bool _keep_running;
@@ -149,15 +164,15 @@ private: /* members */
gr::thread::thread _thread;
bool _run_usb_read_task;
bool _run_tcp_keepalive_task;
- std::mutex _tcp_lock;
+ boost::mutex _tcp_lock;
boost::circular_buffer<gr_complex> *_fifo;
- std::mutex _fifo_lock;
- std::condition_variable _samp_avail;
+ boost::mutex _fifo_lock;
+ boost::condition_variable _samp_avail;
std::vector< unsigned char > _resp;
- std::mutex _resp_lock;
- std::condition_variable _resp_avail;
+ boost::mutex _resp_lock;
+ boost::condition_variable _resp_avail;
};
#endif /* INCLUDED_RFSPACE_SOURCE_C_H */
diff --git a/lib/rtl/CMakeLists.txt b/lib/rtl/CMakeLists.txt
index 443f3c0..f438df5 100644
--- a/lib/rtl/CMakeLists.txt
+++ b/lib/rtl/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,16 +21,18 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${LIBRTLSDR_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- ${LIBRTLSDR_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(rtl_srcs
${CMAKE_CURRENT_SOURCE_DIR}/rtl_source_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${rtl_srcs})
+list(APPEND gr_osmosdr_libs ${LIBRTLSDR_LIBRARIES})
+
diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc
index 5e3306b..a371464 100644
--- a/lib/rtl/rtl_source_c.cc
+++ b/lib/rtl/rtl_source_c.cc
@@ -32,6 +32,7 @@
#include <boost/assign.hpp>
#include <boost/format.hpp>
+#include <boost/detail/endian.hpp>
#include <boost/algorithm/string.hpp>
#include <stdexcept>
@@ -297,7 +298,7 @@ void rtl_source_c::rtlsdr_callback(unsigned char *buf, uint32_t len)
}
{
- std::lock_guard<std::mutex> lock( _buf_mutex );
+ boost::mutex::scoped_lock lock( _buf_mutex );
int buf_tail = (_buf_head + _buf_used) % _buf_num;
memcpy(_buf[buf_tail], buf, len);
@@ -337,7 +338,7 @@ int rtl_source_c::work( int noutput_items,
gr_complex *out = (gr_complex *)output_items[0];
{
- std::unique_lock<std::mutex> lock( _buf_mutex );
+ boost::mutex::scoped_lock lock( _buf_mutex );
while (_buf_used < 3 && _running) // collect at least 3 buffers
_buf_cond.wait( lock );
@@ -358,7 +359,7 @@ int rtl_source_c::work( int noutput_items,
if (!_samp_avail) {
{
- std::lock_guard<std::mutex> lock( _buf_mutex );
+ boost::mutex::scoped_lock lock( _buf_mutex );
_buf_head = (_buf_head + 1) % _buf_num;
_buf_used--;
diff --git a/lib/rtl/rtl_source_c.h b/lib/rtl/rtl_source_c.h
index de3e349..902b386 100644
--- a/lib/rtl/rtl_source_c.h
+++ b/lib/rtl/rtl_source_c.h
@@ -25,9 +25,8 @@
#include <gnuradio/sync_block.h>
#include <gnuradio/thread/thread.h>
-
-#include <mutex>
-#include <condition_variable>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
#include "source_iface.h"
@@ -132,8 +131,8 @@ private:
unsigned int _buf_len;
unsigned int _buf_head;
unsigned int _buf_used;
- std::mutex _buf_mutex;
- std::condition_variable _buf_cond;
+ boost::mutex _buf_mutex;
+ boost::condition_variable _buf_cond;
bool _running;
unsigned int _buf_offset;
diff --git a/lib/rtl_tcp/CMakeLists.txt b/lib/rtl_tcp/CMakeLists.txt
index 2de6cee..9f7c201 100644
--- a/lib/rtl_tcp/CMakeLists.txt
+++ b/lib/rtl_tcp/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,15 +21,17 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
-APPEND_LIB_LIST(
- ${Gnuradio-blocks_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(rtl_tcp_srcs
${CMAKE_CURRENT_SOURCE_DIR}/rtl_tcp_source_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${rtl_tcp_srcs})
+#list(APPEND gr_osmosdr_libs ${GNURADIO_BLOCKS_LIBRARIES})
+
diff --git a/lib/rtl_tcp/rtl_tcp_source_c.cc b/lib/rtl_tcp/rtl_tcp_source_c.cc
index af8e300..ecdeee0 100644
--- a/lib/rtl_tcp/rtl_tcp_source_c.cc
+++ b/lib/rtl_tcp/rtl_tcp_source_c.cc
@@ -98,7 +98,7 @@ static int is_error( int perr )
case WSAENOPROTOOPT:
return( perr == ENOPROTOOPT );
default:
- fprintf(stderr,"rtl_tcp_source_c: unknown error %d WS err %d \n", perr, werr );
+ fprintf(stderr,"rtl_tcp_source_f: unknown error %d WS err %d \n", perr, werr );
throw std::runtime_error("internal error");
}
return 0;
@@ -200,7 +200,7 @@ rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) :
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if( iResult != NO_ERROR ) {
- report_error( "rtl_tcp_source_c WSAStartup", "can't open socket" );
+ report_error( "rtl_tcp_source_f WSAStartup", "can't open socket" );
}
#endif
@@ -219,7 +219,7 @@ rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) :
// FIXME leaks if report_error throws below
int ret = getaddrinfo(host.c_str(), port_str, &hints, &ip_src);
if (ret != 0)
- report_error("rtl_tcp_source_c/getaddrinfo",
+ report_error("rtl_tcp_source_f/getaddrinfo",
"can't initialize source socket" );
d_temp_buff = new unsigned char[payload_size]; // allow it to hold up to payload_size bytes
@@ -261,8 +261,8 @@ rtl_tcp_source_c::rtl_tcp_source_c(const std::string &args) :
report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO");
#endif // USE_RCV_TIMEO
- if (::connect(d_socket, ip_src->ai_addr, ip_src->ai_addrlen) != 0)
- report_error("rtl_tcp_source_c/connect","can't open TCP connection");
+ while (::connect(d_socket, ip_src->ai_addr, ip_src->ai_addrlen) != 0)
+ ; // FIXME handle errors?
freeaddrinfo(ip_src);
int flag = 1;
diff --git a/lib/sdrplay/CMakeLists.txt b/lib/sdrplay/CMakeLists.txt
index 3d20a6f..382ab33 100644
--- a/lib/sdrplay/CMakeLists.txt
+++ b/lib/sdrplay/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,16 +21,17 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${LIBSDRPLAY_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- ${LIBSDRPLAY_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(sdrplay_srcs
${CMAKE_CURRENT_SOURCE_DIR}/sdrplay_source_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-sdrplay library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${sdrplay_srcs})
+list(APPEND gr_osmosdr_libs ${LIBSDRPLAY_LIBRARIES})
diff --git a/lib/sdrplay/sdrplay_source_c.h b/lib/sdrplay/sdrplay_source_c.h
index b59f44a..2e4631e 100644
--- a/lib/sdrplay/sdrplay_source_c.h
+++ b/lib/sdrplay/sdrplay_source_c.h
@@ -24,9 +24,8 @@
#include <gnuradio/sync_block.h>
#include <gnuradio/thread/thread.h>
-
-#include <mutex>
-#include <condition_variable>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
#include "osmosdr/ranges.h"
@@ -127,7 +126,7 @@ private:
std::vector< short > _bufi;
std::vector< short > _bufq;
int _buf_offset;
- std::mutex _buf_mutex;
+ boost::mutex _buf_mutex;
bool _running;
bool _uninit;
diff --git a/lib/sink_impl.cc b/lib/sink_impl.cc
index 317855a..d25e860 100644
--- a/lib/sink_impl.cc
+++ b/lib/sink_impl.cc
@@ -48,9 +48,6 @@
#ifdef ENABLE_FREESRP
#include <freesrp_sink_c.h>
#endif
-#ifdef ENABLE_XTRX
-#include "xtrx_sink_c.h"
-#endif
#ifdef ENABLE_FILE
#include "file_sink_c.h"
#endif
@@ -102,9 +99,6 @@ sink_impl::sink_impl( const std::string &args )
#ifdef ENABLE_FREESRP
dev_types.push_back("freesrp");
#endif
-#ifdef ENABLE_XTRX
- dev_types.push_back("xtrx");
-#endif
#ifdef ENABLE_FILE
dev_types.push_back("file");
#endif
@@ -113,13 +107,13 @@ sink_impl::sink_impl( const std::string &args )
<< GR_OSMOSDR_VERSION << " (" << GR_OSMOSDR_LIBVER << ") "
<< "gnuradio " << gr::version() << std::endl;
std::cerr << "built-in sink types: ";
- for (std::string dev_type : dev_types)
+ BOOST_FOREACH(std::string dev_type, dev_types)
std::cerr << dev_type << " ";
std::cerr << std::endl;
- for (std::string arg : arg_list) {
+ BOOST_FOREACH(std::string arg, arg_list) {
dict_t dict = params_to_dict(arg);
- for (std::string dev_type : dev_types) {
+ BOOST_FOREACH(std::string dev_type, dev_types) {
if ( dict.count( dev_type ) ) {
device_specified = true;
break;
@@ -130,40 +124,36 @@ sink_impl::sink_impl( const std::string &args )
if ( ! device_specified ) {
std::vector< std::string > dev_list;
#ifdef ENABLE_UHD
- for (std::string dev : uhd_sink_c::get_devices())
+ BOOST_FOREACH( std::string dev, uhd_sink_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_BLADERF
- for (std::string dev : bladerf_sink_c::get_devices())
+ BOOST_FOREACH( std::string dev, bladerf_sink_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_HACKRF
- for (std::string dev : hackrf_sink_c::get_devices())
+ BOOST_FOREACH( std::string dev, hackrf_sink_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_SOAPY
- for (std::string dev : soapy_sink_c::get_devices())
+ BOOST_FOREACH( std::string dev, soapy_sink_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_REDPITAYA
- for (std::string dev : redpitaya_sink_c::get_devices())
+ BOOST_FOREACH( std::string dev, redpitaya_sink_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_FREESRP
- for (std::string dev : freesrp_sink_c::get_devices())
- dev_list.push_back( dev );
-#endif
-#ifdef ENABLE_XTRX
- for (std::string dev : xtrx_sink_c::get_devices())
+ BOOST_FOREACH( std::string dev, freesrp_sink_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_FILE
- for (std::string dev : file_sink_c::get_devices())
+ BOOST_FOREACH( std::string dev, file_sink_c::get_devices() )
dev_list.push_back( dev );
#endif
// std::cerr << std::endl;
-// for (std::string dev : dev_list)
+// BOOST_FOREACH( std::string dev, dev_list )
// std::cerr << "'" << dev << "'" << std::endl;
if ( dev_list.size() )
@@ -172,12 +162,12 @@ sink_impl::sink_impl( const std::string &args )
throw std::runtime_error("No supported devices found (check the connection and/or udev rules).");
}
- for (std::string arg : arg_list) {
+ BOOST_FOREACH(std::string arg, arg_list) {
dict_t dict = params_to_dict(arg);
// std::cerr << std::endl;
-// for (dict_t::value_type &entry : dict)
+// BOOST_FOREACH( dict_t::value_type &entry, dict )
// std::cerr << "'" << entry.first << "' = '" << entry.second << "'" << std::endl;
sink_iface *iface = NULL;
@@ -219,12 +209,6 @@ sink_impl::sink_impl( const std::string &args )
block = sink; iface = sink.get();
}
#endif
-#ifdef ENABLE_XTRX
- if ( dict.count("xtrx") ) {
- xtrx_sink_c_sptr sink = make_xtrx_sink_c( arg );
- block = sink; iface = sink.get();
- }
-#endif
#ifdef ENABLE_FILE
if ( dict.count("file") ) {
file_sink_c_sptr sink = make_file_sink_c( arg );
@@ -245,13 +229,20 @@ sink_impl::sink_impl( const std::string &args )
if (!_devs.size())
throw std::runtime_error("No devices specified via device arguments.");
+
+ /* Populate the _gain and _gain_mode arrays with the hardware state */
+ BOOST_FOREACH( sink_iface *dev, _devs )
+ for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
+ _gain_mode[dev_chan] = dev->get_gain_mode(dev_chan);
+ _gain[dev_chan] = dev->get_gain(dev_chan);
+ }
}
size_t sink_impl::get_num_channels()
{
size_t channels = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
channels += dev->get_num_channels();
return channels;
@@ -279,13 +270,13 @@ double sink_impl::set_sample_rate(double rate)
if (_devs.empty())
throw std::runtime_error(NO_DEVICES_MSG);
#endif
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
sample_rate = dev->set_sample_rate(rate);
_sample_rate = sample_rate;
}
- return _sample_rate;
+ return sample_rate;
}
double sink_impl::get_sample_rate()
@@ -304,7 +295,7 @@ double sink_impl::get_sample_rate()
osmosdr::freq_range_t sink_impl::get_freq_range( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_freq_range( dev_chan );
@@ -315,7 +306,7 @@ osmosdr::freq_range_t sink_impl::get_freq_range( size_t chan )
double sink_impl::set_center_freq( double freq, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _center_freq[ chan ] != freq ) {
@@ -330,7 +321,7 @@ double sink_impl::set_center_freq( double freq, size_t chan )
double sink_impl::get_center_freq( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_center_freq( dev_chan );
@@ -341,7 +332,7 @@ double sink_impl::get_center_freq( size_t chan )
double sink_impl::set_freq_corr( double ppm, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _freq_corr[ chan ] != ppm ) {
@@ -356,7 +347,7 @@ double sink_impl::set_freq_corr( double ppm, size_t chan )
double sink_impl::get_freq_corr( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_freq_corr( dev_chan );
@@ -367,7 +358,7 @@ double sink_impl::get_freq_corr( size_t chan )
std::vector<std::string> sink_impl::get_gain_names( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain_names( dev_chan );
@@ -378,7 +369,7 @@ std::vector<std::string> sink_impl::get_gain_names( size_t chan )
osmosdr::gain_range_t sink_impl::get_gain_range( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain_range( dev_chan );
@@ -389,7 +380,7 @@ osmosdr::gain_range_t sink_impl::get_gain_range( size_t chan )
osmosdr::gain_range_t sink_impl::get_gain_range( const std::string & name, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain_range( name, dev_chan );
@@ -400,7 +391,7 @@ osmosdr::gain_range_t sink_impl::get_gain_range( const std::string & name, size_
bool sink_impl::set_gain_mode( bool automatic, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _gain_mode[ chan ] != automatic ) {
@@ -418,7 +409,7 @@ bool sink_impl::set_gain_mode( bool automatic, size_t chan )
bool sink_impl::get_gain_mode( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain_mode( dev_chan );
@@ -429,7 +420,7 @@ bool sink_impl::get_gain_mode( size_t chan )
double sink_impl::set_gain( double gain, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _gain[ chan ] != gain ) {
@@ -444,7 +435,7 @@ double sink_impl::set_gain( double gain, size_t chan )
double sink_impl::set_gain( double gain, const std::string & name, size_t chan)
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->set_gain( gain, name, dev_chan );
@@ -455,7 +446,7 @@ double sink_impl::set_gain( double gain, const std::string & name, size_t chan)
double sink_impl::get_gain( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain( dev_chan );
@@ -466,7 +457,7 @@ double sink_impl::get_gain( size_t chan )
double sink_impl::get_gain( const std::string & name, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain( name, dev_chan );
@@ -477,7 +468,7 @@ double sink_impl::get_gain( const std::string & name, size_t chan )
double sink_impl::set_if_gain( double gain, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _if_gain[ chan ] != gain ) {
@@ -492,7 +483,7 @@ double sink_impl::set_if_gain( double gain, size_t chan )
double sink_impl::set_bb_gain( double gain, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _bb_gain[ chan ] != gain ) {
@@ -507,7 +498,7 @@ double sink_impl::set_bb_gain( double gain, size_t chan )
std::vector< std::string > sink_impl::get_antennas( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_antennas( dev_chan );
@@ -518,7 +509,7 @@ std::vector< std::string > sink_impl::get_antennas( size_t chan )
std::string sink_impl::set_antenna( const std::string & antenna, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _antenna[ chan ] != antenna ) {
@@ -533,7 +524,7 @@ std::string sink_impl::set_antenna( const std::string & antenna, size_t chan )
std::string sink_impl::get_antenna( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_antenna( dev_chan );
@@ -544,7 +535,7 @@ std::string sink_impl::get_antenna( size_t chan )
void sink_impl::set_dc_offset( const std::complex<double> &offset, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
dev->set_dc_offset( offset, dev_chan );
@@ -553,7 +544,7 @@ void sink_impl::set_dc_offset( const std::complex<double> &offset, size_t chan )
void sink_impl::set_iq_balance( const std::complex<double> &balance, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
dev->set_iq_balance( balance, dev_chan );
@@ -562,7 +553,7 @@ void sink_impl::set_iq_balance( const std::complex<double> &balance, size_t chan
double sink_impl::set_bandwidth( double bandwidth, size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _bandwidth[ chan ] != bandwidth || 0.0f == bandwidth ) {
@@ -577,7 +568,7 @@ double sink_impl::set_bandwidth( double bandwidth, size_t chan )
double sink_impl::get_bandwidth( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_bandwidth( dev_chan );
@@ -588,7 +579,7 @@ double sink_impl::get_bandwidth( size_t chan )
osmosdr::freq_range_t sink_impl::get_bandwidth_range( size_t chan )
{
size_t channel = 0;
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_bandwidth_range( dev_chan );
@@ -681,7 +672,7 @@ void sink_impl::set_time_now(const osmosdr::time_spec_t &time_spec, size_t mboar
void sink_impl::set_time_next_pps(const osmosdr::time_spec_t &time_spec)
{
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
{
dev->set_time_next_pps( time_spec );
}
@@ -689,7 +680,7 @@ void sink_impl::set_time_next_pps(const osmosdr::time_spec_t &time_spec)
void sink_impl::set_time_unknown_pps(const osmosdr::time_spec_t &time_spec)
{
- for (sink_iface *dev : _devs)
+ BOOST_FOREACH( sink_iface *dev, _devs )
{
dev->set_time_unknown_pps( time_spec );
}
diff --git a/lib/soapy/CMakeLists.txt b/lib/soapy/CMakeLists.txt
index 7ac4d69..338bcaf 100644
--- a/lib/soapy/CMakeLists.txt
+++ b/lib/soapy/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2015 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,18 +21,19 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${SoapySDR_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- ${SoapySDR_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(soapy_srcs
${CMAKE_CURRENT_SOURCE_DIR}/soapy_common.cc
${CMAKE_CURRENT_SOURCE_DIR}/soapy_source_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/soapy_sink_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${soapy_srcs})
+list(APPEND gr_osmosdr_libs ${SoapySDR_LIBRARIES})
diff --git a/lib/soapy/soapy_common.cc b/lib/soapy/soapy_common.cc
index e241967..0e277e4 100644
--- a/lib/soapy/soapy_common.cc
+++ b/lib/soapy/soapy_common.cc
@@ -36,8 +36,8 @@ osmosdr::gain_range_t soapy_range_to_gain_range(const SoapySDR::Range &r)
return osmosdr::gain_range_t(r.minimum(), r.maximum(), step);
}
-std::mutex &get_soapy_maker_mutex(void)
+boost::mutex &get_soapy_maker_mutex(void)
{
- static std::mutex m;
+ static boost::mutex m;
return m;
}
diff --git a/lib/soapy/soapy_common.h b/lib/soapy/soapy_common.h
index 8adb0db..87e46a5 100644
--- a/lib/soapy/soapy_common.h
+++ b/lib/soapy/soapy_common.h
@@ -23,8 +23,7 @@
#include <osmosdr/ranges.h>
#include <SoapySDR/Types.hpp>
-
-#include <mutex>
+#include <boost/thread/mutex.hpp>
/*!
* Convert a soapy range to a gain range.
@@ -36,6 +35,6 @@ osmosdr::gain_range_t soapy_range_to_gain_range(const SoapySDR::Range &r);
* Global mutex to protect factory routines.
* (optional under 0.5 release above)
*/
-std::mutex &get_soapy_maker_mutex(void);
+boost::mutex &get_soapy_maker_mutex(void);
#endif /* INCLUDED_SOAPY_COMMON_H */
diff --git a/lib/soapy/soapy_sink_c.cc b/lib/soapy/soapy_sink_c.cc
index 4aafc47..b12b8da 100644
--- a/lib/soapy/soapy_sink_c.cc
+++ b/lib/soapy/soapy_sink_c.cc
@@ -63,7 +63,7 @@ soapy_sink_c::soapy_sink_c (const std::string &args)
gr::io_signature::make (0, 0, 0))
{
{
- std::lock_guard<std::mutex> l(get_soapy_maker_mutex());
+ boost::mutex::scoped_lock l(get_soapy_maker_mutex());
_device = SoapySDR::Device::make(params_to_dict(args));
}
_nchan = std::max(1, args_to_io_signature(args)->max_streams());
@@ -75,7 +75,7 @@ soapy_sink_c::soapy_sink_c (const std::string &args)
soapy_sink_c::~soapy_sink_c(void)
{
_device->closeStream(_stream);
- std::lock_guard<std::mutex> l(get_soapy_maker_mutex());
+ boost::mutex::scoped_lock l(get_soapy_maker_mutex());
SoapySDR::Device::unmake(_device);
}
@@ -107,7 +107,7 @@ std::vector<std::string> soapy_sink_c::get_devices()
{
std::vector<std::string> result;
int i = 0;
- for (SoapySDR::Kwargs kw : SoapySDR::Device::enumerate())
+ BOOST_FOREACH(SoapySDR::Kwargs kw, SoapySDR::Device::enumerate())
{
kw["soapy"] = boost::lexical_cast<std::string>(i++);
result.push_back(dict_to_args_string(kw));
@@ -124,12 +124,12 @@ osmosdr::meta_range_t soapy_sink_c::get_sample_rates( void )
{
osmosdr::meta_range_t result;
#ifdef SOAPY_SDR_API_HAS_GET_SAMPLE_RATE_RANGE
- for (const SoapySDR::Range &r : _device->getSampleRateRange(SOAPY_SDR_TX, 0))
+ BOOST_FOREACH(const SoapySDR::Range &r, _device->getSampleRateRange(SOAPY_SDR_TX, 0))
{
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
}
#else
- for (const double rate : _device->listSampleRates(SOAPY_SDR_TX, 0))
+ BOOST_FOREACH(const double rate, _device->listSampleRates(SOAPY_SDR_TX, 0))
{
result.push_back(osmosdr::range_t(rate));
}
@@ -151,7 +151,7 @@ double soapy_sink_c::get_sample_rate( void )
osmosdr::freq_range_t soapy_sink_c::get_freq_range( size_t chan)
{
osmosdr::meta_range_t result;
- for (const SoapySDR::Range r : _device->getFrequencyRange(SOAPY_SDR_TX, 0))
+ BOOST_FOREACH(const SoapySDR::Range r, _device->getFrequencyRange(SOAPY_SDR_TX, 0))
{
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
}
@@ -309,12 +309,12 @@ osmosdr::freq_range_t soapy_sink_c::get_bandwidth_range( size_t chan)
{
osmosdr::meta_range_t result;
#ifdef SOAPY_SDR_API_HAS_GET_BANDWIDTH_RANGE
- for (const SoapySDR::Range &r : _device->getBandwidthRange(SOAPY_SDR_TX, 0))
+ BOOST_FOREACH(const SoapySDR::Range &r, _device->getBandwidthRange(SOAPY_SDR_TX, 0))
{
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
}
#else
- for (const double bw : _device->listBandwidths(SOAPY_SDR_TX, 0))
+ BOOST_FOREACH(const double bw, _device->listBandwidths(SOAPY_SDR_TX, 0))
{
result.push_back(osmosdr::range_t(bw));
}
diff --git a/lib/soapy/soapy_source_c.cc b/lib/soapy/soapy_source_c.cc
index 4dc9efc..a645361 100644
--- a/lib/soapy/soapy_source_c.cc
+++ b/lib/soapy/soapy_source_c.cc
@@ -64,7 +64,7 @@ soapy_source_c::soapy_source_c (const std::string &args)
args_to_io_signature(args))
{
{
- std::lock_guard<std::mutex> l(get_soapy_maker_mutex());
+ boost::mutex::scoped_lock l(get_soapy_maker_mutex());
_device = SoapySDR::Device::make(params_to_dict(args));
}
_nchan = std::max(1, args_to_io_signature(args)->max_streams());
@@ -76,7 +76,7 @@ soapy_source_c::soapy_source_c (const std::string &args)
soapy_source_c::~soapy_source_c(void)
{
_device->closeStream(_stream);
- std::lock_guard<std::mutex> l(get_soapy_maker_mutex());
+ boost::mutex::scoped_lock l(get_soapy_maker_mutex());
SoapySDR::Device::unmake(_device);
}
@@ -96,14 +96,9 @@ int soapy_source_c::work( int noutput_items,
{
int flags = 0;
long long timeNs = 0;
- int ret;
- int retries = 1;
-
- do {
- ret = _device->readStream(
- _stream, &output_items[0],
- noutput_items, flags, timeNs);
- } while (retries-- && (ret == SOAPY_SDR_OVERFLOW));
+ int ret = _device->readStream(
+ _stream, &output_items[0],
+ noutput_items, flags, timeNs);
if (ret < 0) return 0; //call again
return ret;
@@ -113,7 +108,7 @@ std::vector<std::string> soapy_source_c::get_devices()
{
std::vector<std::string> result;
int i = 0;
- for (SoapySDR::Kwargs kw : SoapySDR::Device::enumerate())
+ BOOST_FOREACH(SoapySDR::Kwargs kw, SoapySDR::Device::enumerate())
{
kw["soapy"] = boost::lexical_cast<std::string>(i++);
result.push_back(dict_to_args_string(kw));
@@ -130,12 +125,12 @@ osmosdr::meta_range_t soapy_source_c::get_sample_rates( void )
{
osmosdr::meta_range_t result;
#ifdef SOAPY_SDR_API_HAS_GET_SAMPLE_RATE_RANGE
- for (const SoapySDR::Range &r : _device->getSampleRateRange(SOAPY_SDR_RX, 0))
+ BOOST_FOREACH(const SoapySDR::Range &r, _device->getSampleRateRange(SOAPY_SDR_RX, 0))
{
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
}
#else
- for (const double rate : _device->listSampleRates(SOAPY_SDR_RX, 0))
+ BOOST_FOREACH(const double rate, _device->listSampleRates(SOAPY_SDR_RX, 0))
{
result.push_back(osmosdr::range_t(rate));
}
@@ -157,7 +152,7 @@ double soapy_source_c::get_sample_rate( void )
osmosdr::freq_range_t soapy_source_c::get_freq_range( size_t chan )
{
osmosdr::meta_range_t result;
- for (const SoapySDR::Range r : _device->getFrequencyRange(SOAPY_SDR_RX, 0))
+ BOOST_FOREACH(const SoapySDR::Range r, _device->getFrequencyRange(SOAPY_SDR_RX, 0))
{
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
}
@@ -338,12 +333,12 @@ osmosdr::freq_range_t soapy_source_c::get_bandwidth_range( size_t chan )
{
osmosdr::meta_range_t result;
#ifdef SOAPY_SDR_API_HAS_GET_BANDWIDTH_RANGE
- for (const SoapySDR::Range &r : _device->getBandwidthRange(SOAPY_SDR_RX, 0))
+ BOOST_FOREACH(const SoapySDR::Range &r, _device->getBandwidthRange(SOAPY_SDR_RX, 0))
{
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
}
#else
- for (const double bw : _device->listBandwidths(SOAPY_SDR_RX, 0))
+ BOOST_FOREACH(const double bw, _device->listBandwidths(SOAPY_SDR_RX, 0))
{
result.push_back(osmosdr::range_t(bw));
}
diff --git a/lib/source_impl.cc b/lib/source_impl.cc
index 8f2028b..f9a7e64 100644
--- a/lib/source_impl.cc
+++ b/lib/source_impl.cc
@@ -32,6 +32,10 @@
#include <gnuradio/blocks/throttle.h>
#include <gnuradio/constants.h>
+#ifdef ENABLE_OSMOSDR
+#include <osmosdr_src_c.h>
+#endif
+
#ifdef ENABLE_FCD
#include <fcd_source_c.h>
#endif
@@ -52,6 +56,10 @@
#include <uhd_source_c.h>
#endif
+#ifdef ENABLE_MIRI
+#include <miri_source_c.h>
+#endif
+
#ifdef ENABLE_SDRPLAY
#include <sdrplay_source_c.h>
#endif
@@ -72,10 +80,6 @@
#include <airspy_source_c.h>
#endif
-#ifdef ENABLE_AIRSPYHF
-#include <airspyhf_source_c.h>
-#endif
-
#ifdef ENABLE_SOAPY
#include <soapy_source_c.h>
#endif
@@ -88,10 +92,6 @@
#include <freesrp_source_c.h>
#endif
-#ifdef ENABLE_XTRX
-#include <xtrx_source_c.h>
-#endif
-
#include "arg_helpers.h"
#include "source_impl.h"
@@ -124,6 +124,9 @@ source_impl::source_impl( const std::string &args )
#ifdef ENABLE_FILE
dev_types.push_back("file");
#endif
+#ifdef ENABLE_OSMOSDR
+ dev_types.push_back("osmosdr");
+#endif
#ifdef ENABLE_FCD
dev_types.push_back("fcd");
#endif
@@ -136,6 +139,9 @@ source_impl::source_impl( const std::string &args )
#ifdef ENABLE_UHD
dev_types.push_back("uhd");
#endif
+#ifdef ENABLE_MIRI
+ dev_types.push_back("miri");
+#endif
#ifdef ENABLE_SDRPLAY
dev_types.push_back("sdrplay");
#endif
@@ -151,9 +157,6 @@ source_impl::source_impl( const std::string &args )
#ifdef ENABLE_AIRSPY
dev_types.push_back("airspy");
#endif
-#ifdef ENABLE_AIRSPYHF
- dev_types.push_back("airspyhf");
-#endif
#ifdef ENABLE_SOAPY
dev_types.push_back("soapy");
#endif
@@ -163,14 +166,11 @@ source_impl::source_impl( const std::string &args )
#ifdef ENABLE_FREESRP
dev_types.push_back("freesrp");
#endif
-#ifdef ENABLE_XTRX
- dev_types.push_back("xtrx");
-#endif
std::cerr << "gr-osmosdr "
<< GR_OSMOSDR_VERSION << " (" << GR_OSMOSDR_LIBVER << ") "
<< "gnuradio " << gr::version() << std::endl;
std::cerr << "built-in source types: ";
- for (std::string dev_type : dev_types)
+ BOOST_FOREACH(std::string dev_type, dev_types)
std::cerr << dev_type << " ";
std::cerr << std::endl;
@@ -181,9 +181,9 @@ source_impl::source_impl( const std::string &args )
dev_types.push_back("cloudiq");
#endif
- for (std::string arg : arg_list) {
+ BOOST_FOREACH(std::string arg, arg_list) {
dict_t dict = params_to_dict(arg);
- for (std::string dev_type : dev_types) {
+ BOOST_FOREACH(std::string dev_type, dev_types) {
if ( dict.count( dev_type ) ) {
device_specified = true;
break;
@@ -191,63 +191,76 @@ source_impl::source_impl( const std::string &args )
}
}
+ bool force_arg = false;
+ int force_val = 0;
+
+ if (arg_list.size() <= 2) {
+ BOOST_FOREACH(std::string arg, arg_list) {
+ if ( arg.find( "numchan=" ) == 0 ) {
+ pair_t pair = param_to_pair( arg );
+ force_arg = true;
+ force_val = boost::lexical_cast<size_t>( pair.second );
+ }
+ }
+ }
+
if ( ! device_specified ) {
std::vector< std::string > dev_list;
+#ifdef ENABLE_OSMOSDR
+ BOOST_FOREACH( std::string dev, osmosdr_src_c::get_devices() )
+ dev_list.push_back( dev );
+#endif
#ifdef ENABLE_FCD
- for (std::string dev : fcd_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, fcd_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_RTL
- for (std::string dev : rtl_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, rtl_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_UHD
- for (std::string dev : uhd_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
+ dev_list.push_back( dev );
+#endif
+#ifdef ENABLE_MIRI
+ BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_SDRPLAY
- for (std::string dev : sdrplay_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, sdrplay_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_BLADERF
- for (std::string dev : bladerf_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, bladerf_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_RFSPACE
- for (std::string dev : rfspace_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_HACKRF
- for (std::string dev : hackrf_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, hackrf_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_AIRSPY
- for (std::string dev : airspy_source_c::get_devices())
- dev_list.push_back( dev );
-#endif
-#ifdef ENABLE_AIRSPYHF
- for (std::string dev : airspyhf_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, airspy_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_SOAPY
- for (std::string dev : soapy_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, soapy_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_REDPITAYA
- for (std::string dev : redpitaya_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, redpitaya_source_c::get_devices() )
dev_list.push_back( dev );
#endif
#ifdef ENABLE_FREESRP
- for (std::string dev : freesrp_source_c::get_devices())
- dev_list.push_back( dev );
-#endif
-#ifdef ENABLE_XTRX
- for (std::string dev : xtrx_source_c::get_devices())
+ BOOST_FOREACH( std::string dev, freesrp_source_c::get_devices() )
dev_list.push_back( dev );
#endif
// std::cerr << std::endl;
-// for (std::string dev : dev_list)
+// BOOST_FOREACH( std::string dev, dev_list )
// std::cerr << "'" << dev << "'" << std::endl;
if ( dev_list.size() )
@@ -256,17 +269,27 @@ source_impl::source_impl( const std::string &args )
throw std::runtime_error("No supported devices found (check the connection and/or udev rules).");
}
- for (std::string arg : arg_list) {
+ BOOST_FOREACH(std::string arg, arg_list) {
+
+ if(force_arg)
+ arg += ",nchan=" + std::to_string(force_val);
dict_t dict = params_to_dict(arg);
// std::cerr << std::endl;
-// for (dict_t::value_type &entry : dict)
+// BOOST_FOREACH( dict_t::value_type &entry, dict )
// std::cerr << "'" << entry.first << "' = '" << entry.second << "'" << std::endl;
source_iface *iface = NULL;
gr::basic_block_sptr block;
+#ifdef ENABLE_OSMOSDR
+ if ( dict.count("osmosdr") ) {
+ osmosdr_src_c_sptr src = osmosdr_make_src_c( arg );
+ block = src; iface = src.get();
+ }
+#endif
+
#ifdef ENABLE_FCD
if ( dict.count("fcd") ) {
fcd_source_c_sptr src = make_fcd_source_c( arg );
@@ -302,6 +325,13 @@ source_impl::source_impl( const std::string &args )
}
#endif
+#ifdef ENABLE_MIRI
+ if ( dict.count("miri") ) {
+ miri_source_c_sptr src = make_miri_source_c( arg );
+ block = src; iface = src.get();
+ }
+#endif
+
#ifdef ENABLE_SDRPLAY
if ( dict.count("sdrplay") ) {
sdrplay_source_c_sptr src = make_sdrplay_source_c( arg );
@@ -341,13 +371,6 @@ source_impl::source_impl( const std::string &args )
}
#endif
-#ifdef ENABLE_AIRSPYHF
- if ( dict.count("airspyhf") ) {
- airspyhf_source_c_sptr src = make_airspyhf_source_c( arg );
- block = src; iface = src.get();
- }
-#endif
-
#ifdef ENABLE_SOAPY
if ( dict.count("soapy") ) {
soapy_source_c_sptr src = make_soapy_source_c( arg );
@@ -369,13 +392,6 @@ source_impl::source_impl( const std::string &args )
}
#endif
-#ifdef ENABLE_XTRX
- if ( dict.count("xtrx") ) {
- xtrx_source_c_sptr src = make_xtrx_source_c( arg );
- block = src; iface = src.get();
- }
-#endif
-
if ( iface != NULL && long(block.get()) != 0 ) {
_devs.push_back( iface );
@@ -403,13 +419,20 @@ source_impl::source_impl( const std::string &args )
if (!_devs.size())
throw std::runtime_error("No devices specified via device arguments.");
+
+ /* Populate the _gain and _gain_mode arrays with the hardware state */
+ BOOST_FOREACH( source_iface *dev, _devs )
+ for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
+ _gain_mode[dev_chan] = dev->get_gain_mode(dev_chan);
+ _gain[dev_chan] = dev->get_gain(dev_chan);
+ }
}
size_t source_impl::get_num_channels()
{
size_t channels = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
channels += dev->get_num_channels();
return channels;
@@ -418,7 +441,7 @@ size_t source_impl::get_num_channels()
bool source_impl::seek( long seek_point, int whence, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->seek( seek_point, whence, dev_chan );
@@ -448,12 +471,12 @@ double source_impl::set_sample_rate(double rate)
if (_devs.empty())
throw std::runtime_error(NO_DEVICES_MSG);
#endif
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
sample_rate = dev->set_sample_rate(rate);
#ifdef HAVE_IQBALANCE
size_t channel = 0;
- for (source_iface *dev : _devs) {
+ BOOST_FOREACH( source_iface *dev, _devs ) {
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
if ( channel < _iq_opt.size() ) {
gr::iqbalance::optimize_c *opt = _iq_opt[channel];
@@ -472,7 +495,7 @@ double source_impl::set_sample_rate(double rate)
_sample_rate = sample_rate;
}
- return _sample_rate;
+ return sample_rate;
}
double source_impl::get_sample_rate()
@@ -491,7 +514,7 @@ double source_impl::get_sample_rate()
osmosdr::freq_range_t source_impl::get_freq_range( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_freq_range( dev_chan );
@@ -502,7 +525,7 @@ osmosdr::freq_range_t source_impl::get_freq_range( size_t chan )
double source_impl::set_center_freq( double freq, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _center_freq[ chan ] != freq ) {
@@ -517,7 +540,7 @@ double source_impl::set_center_freq( double freq, size_t chan )
double source_impl::get_center_freq( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_center_freq( dev_chan );
@@ -528,7 +551,7 @@ double source_impl::get_center_freq( size_t chan )
double source_impl::set_freq_corr( double ppm, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _freq_corr[ chan ] != ppm ) {
@@ -543,7 +566,7 @@ double source_impl::set_freq_corr( double ppm, size_t chan )
double source_impl::get_freq_corr( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_freq_corr( dev_chan );
@@ -554,7 +577,7 @@ double source_impl::get_freq_corr( size_t chan )
std::vector<std::string> source_impl::get_gain_names( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain_names( dev_chan );
@@ -565,7 +588,7 @@ std::vector<std::string> source_impl::get_gain_names( size_t chan )
osmosdr::gain_range_t source_impl::get_gain_range( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain_range( dev_chan );
@@ -576,7 +599,7 @@ osmosdr::gain_range_t source_impl::get_gain_range( size_t chan )
osmosdr::gain_range_t source_impl::get_gain_range( const std::string & name, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain_range( name, dev_chan );
@@ -587,7 +610,7 @@ osmosdr::gain_range_t source_impl::get_gain_range( const std::string & name, siz
bool source_impl::set_gain_mode( bool automatic, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _gain_mode[ chan ] != automatic ) {
@@ -605,7 +628,7 @@ bool source_impl::set_gain_mode( bool automatic, size_t chan )
bool source_impl::get_gain_mode( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain_mode( dev_chan );
@@ -616,7 +639,7 @@ bool source_impl::get_gain_mode( size_t chan )
double source_impl::set_gain( double gain, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _gain[ chan ] != gain ) {
@@ -631,7 +654,7 @@ double source_impl::set_gain( double gain, size_t chan )
double source_impl::set_gain( double gain, const std::string & name, size_t chan)
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->set_gain( gain, name, dev_chan );
@@ -642,7 +665,7 @@ double source_impl::set_gain( double gain, const std::string & name, size_t chan
double source_impl::get_gain( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain( dev_chan );
@@ -653,7 +676,7 @@ double source_impl::get_gain( size_t chan )
double source_impl::get_gain( const std::string & name, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_gain( name, dev_chan );
@@ -664,7 +687,7 @@ double source_impl::get_gain( const std::string & name, size_t chan )
double source_impl::set_if_gain( double gain, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _if_gain[ chan ] != gain ) {
@@ -679,7 +702,7 @@ double source_impl::set_if_gain( double gain, size_t chan )
double source_impl::set_bb_gain( double gain, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _bb_gain[ chan ] != gain ) {
@@ -694,7 +717,7 @@ double source_impl::set_bb_gain( double gain, size_t chan )
std::vector< std::string > source_impl::get_antennas( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_antennas( dev_chan );
@@ -705,7 +728,7 @@ std::vector< std::string > source_impl::get_antennas( size_t chan )
std::string source_impl::set_antenna( const std::string & antenna, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _antenna[ chan ] != antenna ) {
@@ -720,7 +743,7 @@ std::string source_impl::set_antenna( const std::string & antenna, size_t chan )
std::string source_impl::get_antenna( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_antenna( dev_chan );
@@ -731,7 +754,7 @@ std::string source_impl::get_antenna( size_t chan )
void source_impl::set_dc_offset_mode( int mode, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
dev->set_dc_offset_mode( mode, dev_chan );
@@ -740,7 +763,7 @@ void source_impl::set_dc_offset_mode( int mode, size_t chan )
void source_impl::set_dc_offset( const std::complex<double> &offset, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
dev->set_dc_offset( offset, dev_chan );
@@ -750,7 +773,7 @@ void source_impl::set_iq_balance_mode( int mode, size_t chan )
{
size_t channel = 0;
#ifdef HAVE_IQBALANCE
- for (source_iface *dev : _devs) {
+ BOOST_FOREACH( source_iface *dev, _devs ) {
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
if ( chan == channel++ ) {
if ( chan < _iq_opt.size() && chan < _iq_fix.size() ) {
@@ -780,7 +803,7 @@ void source_impl::set_iq_balance_mode( int mode, size_t chan )
}
}
#else
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->set_iq_balance_mode( mode, dev_chan );
@@ -791,7 +814,7 @@ void source_impl::set_iq_balance( const std::complex<double> &balance, size_t ch
{
size_t channel = 0;
#ifdef HAVE_IQBALANCE
- for (source_iface *dev : _devs) {
+ BOOST_FOREACH( source_iface *dev, _devs ) {
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
if ( chan == channel++ ) {
if ( chan < _iq_opt.size() && chan < _iq_fix.size() ) {
@@ -807,7 +830,7 @@ void source_impl::set_iq_balance( const std::complex<double> &balance, size_t ch
}
}
#else
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->set_iq_balance( balance, dev_chan );
@@ -817,7 +840,7 @@ void source_impl::set_iq_balance( const std::complex<double> &balance, size_t ch
double source_impl::set_bandwidth( double bandwidth, size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ ) {
if ( _bandwidth[ chan ] != bandwidth || 0.0f == bandwidth ) {
@@ -832,7 +855,7 @@ double source_impl::set_bandwidth( double bandwidth, size_t chan )
double source_impl::get_bandwidth( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_bandwidth( dev_chan );
@@ -843,7 +866,7 @@ double source_impl::get_bandwidth( size_t chan )
osmosdr::freq_range_t source_impl::get_bandwidth_range( size_t chan )
{
size_t channel = 0;
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
if ( chan == channel++ )
return dev->get_bandwidth_range( dev_chan );
@@ -936,7 +959,7 @@ void source_impl::set_time_now(const osmosdr::time_spec_t &time_spec, size_t mbo
void source_impl::set_time_next_pps(const osmosdr::time_spec_t &time_spec)
{
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
{
dev->set_time_next_pps( time_spec );
}
@@ -944,7 +967,7 @@ void source_impl::set_time_next_pps(const osmosdr::time_spec_t &time_spec)
void source_impl::set_time_unknown_pps(const osmosdr::time_spec_t &time_spec)
{
- for (source_iface *dev : _devs)
+ BOOST_FOREACH( source_iface *dev, _devs )
{
dev->set_time_unknown_pps( time_spec );
}
diff --git a/lib/uhd/CMakeLists.txt b/lib/uhd/CMakeLists.txt
index 0ab6508..aba5c77 100644
--- a/lib/uhd/CMakeLists.txt
+++ b/lib/uhd/CMakeLists.txt
@@ -1,19 +1,19 @@
# Copyright 2012 Free Software Foundation, Inc.
#
-# This file is part of gr-osmosdr
+# This file is part of GNU Radio
#
-# gr-osmosdr is free software; you can redistribute it and/or modify
+# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
-# gr-osmosdr is distributed in the hope that it will be useful,
+# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with gr-osmosdr; see the file COPYING. If not, write to
+# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
@@ -21,19 +21,19 @@
# This file included, use CMake directory variables
########################################################################
-target_include_directories(gnuradio-osmosdr PRIVATE
+include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
- ${gnuradio-uhd_INCLUDE_DIRS}
+ ${GNURADIO_UHD_INCLUDE_DIRS}
${UHD_INCLUDE_DIRS}
)
-APPEND_LIB_LIST(
- gnuradio::gnuradio-uhd
- ${UHD_LIBRARIES}
-)
-
-list(APPEND gr_osmosdr_srcs
+set(uhd_srcs
${CMAKE_CURRENT_SOURCE_DIR}/uhd_sink_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/uhd_source_c.cc
)
-set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
+
+########################################################################
+# Append gnuradio-osmosdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${uhd_srcs})
+list(APPEND gr_osmosdr_libs ${GNURADIO_UHD_LIBRARIES} ${UHD_LIBRARIES})
diff --git a/lib/uhd/uhd_sink_c.cc b/lib/uhd/uhd_sink_c.cc
index 8698f4c..a154556 100644
--- a/lib/uhd/uhd_sink_c.cc
+++ b/lib/uhd/uhd_sink_c.cc
@@ -18,6 +18,7 @@
* Boston, MA 02110-1301, USA.
*/
+#include <boost/foreach.hpp>
#include <boost/assign.hpp>
#include <boost/algorithm/string.hpp>
@@ -70,7 +71,7 @@ uhd_sink_c::uhd_sink_c(const std::string &args) :
_lo_offset = boost::lexical_cast< double >( dict["lo_offset"] );
std::string arguments; // rebuild argument string without internal arguments
- for (dict_t::value_type &entry : dict)
+ BOOST_FOREACH( dict_t::value_type &entry, dict )
{
if ( "cpu_format" == entry.first ||
"otw_format" == entry.first ||
@@ -134,7 +135,7 @@ std::vector< std::string > uhd_sink_c::get_devices()
std::vector< std::string > devices;
uhd::device_addr_t hint;
- for (const uhd::device_addr_t &dev : uhd::device::find(hint))
+ BOOST_FOREACH(const uhd::device_addr_t &dev, uhd::device::find(hint))
{
std::string args = "uhd," + dev.to_string();
@@ -189,7 +190,7 @@ osmosdr::meta_range_t uhd_sink_c::get_sample_rates( void )
{
osmosdr::meta_range_t rates;
- for (uhd::range_t rate : _snk->get_samp_rates())
+ BOOST_FOREACH( uhd::range_t rate, _snk->get_samp_rates() )
rates += osmosdr::range_t( rate.start(), rate.stop(), rate.step() );
return rates;
@@ -210,7 +211,7 @@ osmosdr::freq_range_t uhd_sink_c::get_freq_range( size_t chan )
{
osmosdr::freq_range_t range;
- for (uhd::range_t freq : _snk->get_freq_range(chan))
+ BOOST_FOREACH( uhd::range_t freq, _snk->get_freq_range(chan) )
range += osmosdr::range_t( freq.start(), freq.stop(), freq.step() );
return range;
@@ -259,7 +260,7 @@ osmosdr::gain_range_t uhd_sink_c::get_gain_range( size_t chan )
{
osmosdr::gain_range_t range;
- for (uhd::range_t gain : _snk->get_gain_range(chan))
+ BOOST_FOREACH( uhd::range_t gain, _snk->get_gain_range(chan) )
range += osmosdr::range_t( gain.start(), gain.stop(), gain.step() );
return range;
@@ -269,7 +270,7 @@ osmosdr::gain_range_t uhd_sink_c::get_gain_range( const std::string & name, size
{
osmosdr::gain_range_t range;
- for (uhd::range_t gain : _snk->get_gain_range(name, chan))
+ BOOST_FOREACH( uhd::range_t gain, _snk->get_gain_range(name, chan) )
range += osmosdr::range_t( gain.start(), gain.stop(), gain.step() );
return range;
@@ -350,7 +351,7 @@ osmosdr::freq_range_t uhd_sink_c::get_bandwidth_range( size_t chan )
{
osmosdr::freq_range_t bandwidths;
- for (uhd::range_t bw : _snk->get_bandwidth_range(chan))
+ BOOST_FOREACH( uhd::range_t bw, _snk->get_bandwidth_range(chan) )
bandwidths += osmosdr::range_t( bw.start(), bw.stop(), bw.step() );
return bandwidths;
diff --git a/lib/uhd/uhd_source_c.cc b/lib/uhd/uhd_source_c.cc
index f9f9fdd..fc13017 100644
--- a/lib/uhd/uhd_source_c.cc
+++ b/lib/uhd/uhd_source_c.cc
@@ -18,6 +18,7 @@
* Boston, MA 02110-1301, USA.
*/
+#include <boost/foreach.hpp>
#include <boost/assign.hpp>
#include <boost/algorithm/string.hpp>
@@ -71,7 +72,7 @@ uhd_source_c::uhd_source_c(const std::string &args) :
_lo_offset = boost::lexical_cast< double >( dict["lo_offset"] );
std::string arguments; // rebuild argument string without internal arguments
- for (dict_t::value_type &entry : dict)
+ BOOST_FOREACH( dict_t::value_type &entry, dict )
{
if ( "cpu_format" == entry.first ||
"otw_format" == entry.first ||
@@ -135,7 +136,7 @@ std::vector< std::string > uhd_source_c::get_devices()
std::vector< std::string > devices;
uhd::device_addr_t hint;
- for (const uhd::device_addr_t &dev : uhd::device::find(hint))
+ BOOST_FOREACH(const uhd::device_addr_t &dev, uhd::device::find(hint))
{
std::string args = "uhd," + dev.to_string();
@@ -190,7 +191,7 @@ osmosdr::meta_range_t uhd_source_c::get_sample_rates( void )
{
osmosdr::meta_range_t rates;
- for (uhd::range_t rate : _src->get_samp_rates())
+ BOOST_FOREACH( uhd::range_t rate, _src->get_samp_rates() )
rates += osmosdr::range_t( rate.start(), rate.stop(), rate.step() );
return rates;
@@ -211,7 +212,7 @@ osmosdr::freq_range_t uhd_source_c::get_freq_range( size_t chan )
{
osmosdr::freq_range_t range;
- for (uhd::range_t freq : _src->get_freq_range(chan))
+ BOOST_FOREACH( uhd::range_t freq, _src->get_freq_range(chan) )
range += osmosdr::range_t( freq.start(), freq.stop(), freq.step() );
return range;
@@ -260,7 +261,7 @@ osmosdr::gain_range_t uhd_source_c::get_gain_range( size_t chan )
{
osmosdr::gain_range_t range;
- for (uhd::range_t gain : _src->get_gain_range(chan))
+ BOOST_FOREACH( uhd::range_t gain, _src->get_gain_range(chan) )
range += osmosdr::range_t( gain.start(), gain.stop(), gain.step() );
return range;
@@ -270,7 +271,7 @@ osmosdr::gain_range_t uhd_source_c::get_gain_range( const std::string & name, si
{
osmosdr::gain_range_t range;
- for (uhd::range_t gain : _src->get_gain_range(name, chan))
+ BOOST_FOREACH( uhd::range_t gain, _src->get_gain_range(name, chan) )
range += osmosdr::range_t( gain.start(), gain.stop(), gain.step() );
return range;
@@ -382,7 +383,7 @@ osmosdr::freq_range_t uhd_source_c::get_bandwidth_range( size_t chan )
{
osmosdr::freq_range_t bandwidths;
- for (uhd::range_t bw : _src->get_bandwidth_range(chan))
+ BOOST_FOREACH( uhd::range_t bw, _src->get_bandwidth_range(chan) )
bandwidths += osmosdr::range_t( bw.start(), bw.stop(), bw.step() );
return bandwidths;
diff --git a/lib/xtrx/xtrx_obj.cc b/lib/xtrx/xtrx_obj.cc
deleted file mode 100644
index 016b420..0000000
--- a/lib/xtrx/xtrx_obj.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#include "xtrx_obj.h"
-#include <iostream>
-#include <sstream>
-#include <boost/thread.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-
-static std::map<std::string, xtrx_obj_sptr> s_objects;
-
-xtrx_obj_sptr xtrx_obj::get(const char* xtrx_dev,
- unsigned loglevel,
- bool lmsreset)
-{
- std::map<std::string, xtrx_obj_sptr>::iterator i;
- std::string name(xtrx_dev);
-
- i = s_objects.find(name);
- if (i == s_objects.end()) {
- // No such object
- s_objects[name].reset(new xtrx_obj(name, loglevel, lmsreset));
- }
-
- return s_objects[name];
-}
-
-void xtrx_obj::clear_all()
-{
- s_objects.clear();
-}
-
-std::vector<std::string> xtrx_obj::get_devices()
-{
- std::vector<std::string> devices;
- // TODO
- devices.push_back("/dev/xtrx0");
- return devices;
-}
-
-
-xtrx_obj::xtrx_obj(const std::string &path, unsigned loglevel, bool lmsreset)
- : _run(false)
- , _vio(0)
- , _sink_rate(0)
- , _sink_master(0)
- , _source_rate(0)
- , _source_master(0)
- , _flags(0)
-{
- unsigned xtrxflag = (loglevel & XTRX_O_LOGLVL_MASK) | ((lmsreset) ? XTRX_O_RESET : 0);
- std::cerr << "xtrx_obj::xtrx_obj = " << xtrxflag << std::endl;
-
- int res = xtrx_open_string(path.c_str(), &_obj);
- if (res < 0) {
- std::stringstream message;
- message << "Couldn't open " ": Error: " << -res;
-
- throw std::runtime_error( message.str() );
- }
-
- _devices = res;
-}
-
-double xtrx_obj::set_smaplerate(double rate, double master, bool sink, unsigned flags)
-{
- boost::mutex::scoped_lock lock(mtx);
-
- if (sink) {
- _sink_rate = rate;
- _sink_master = master;
- } else {
- _source_rate = rate;
- _source_master = master;
- }
- _flags |= flags | XTRX_SAMPLERATE_FORCE_UPDATE;
-
- if (_sink_master != 0 && _source_master != 0 && _sink_master != _source_master) {
- std::stringstream message;
- message << "Can't operate on diferrent master settings for XTRX sink and source"
- " sink_master " << _sink_master << " source_master" << _source_master;
-
- throw std::runtime_error( message.str() );
- }
-
- double rxrate = 0, txrate = 0;
- double actmaster = (_source_master > 0) ? _source_master : _sink_master;
- int res = xtrx_set_samplerate(_obj,
- actmaster,
- _source_rate,
- _sink_rate,
- _flags,
- NULL,
- &rxrate,
- &txrate);
- if (res) {
- std::cerr << "Unable to set samplerate, error=" << res << std::endl;
- if (sink)
- return _sink_rate;
- return _source_rate;
- }
-
- if (_vio) {
- xtrx_val_set(_obj, XTRX_TRX, XTRX_CH_AB, XTRX_LMS7_VIO, _vio);
- }
-
- if (sink)
- return txrate;
- return rxrate;
-}
-
-xtrx_obj::~xtrx_obj()
-{
- if (_obj) {
- if (_run) {
- //boost::mutex::scoped_lock lock(mtx);
- xtrx_stop(_obj, XTRX_TRX);
- }
- xtrx_close(_obj);
- }
-}
diff --git a/lib/xtrx/xtrx_obj.h b/lib/xtrx/xtrx_obj.h
deleted file mode 100644
index e26947d..0000000
--- a/lib/xtrx/xtrx_obj.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef XTRX_OBJ_H
-#define XTRX_OBJ_H
-
-#include <boost/shared_ptr.hpp>
-#include <xtrx_api.h>
-#include <map>
-#include <vector>
-#include <boost/thread/mutex.hpp>
-
-class xtrx_obj;
-
-typedef boost::shared_ptr<xtrx_obj> xtrx_obj_sptr;
-
-class xtrx_obj
-{
-public:
- xtrx_obj(const std::string& path, unsigned loglevel, bool lmsreset);
- ~xtrx_obj();
-
- static std::vector<std::string> get_devices();
-
- static xtrx_obj_sptr get(const char* xtrx_dev,
- unsigned loglevel,
- bool lmsreset);
- static void clear_all();
-
- xtrx_dev* dev() { return _obj; }
- unsigned dev_count() { return _devices; }
-
- double set_smaplerate(double rate, double master, bool sink, unsigned flags);
-
- void set_vio(unsigned vio) { _vio = vio; }
-
- boost::mutex mtx;
-protected:
- xtrx_dev* _obj;
- bool _run;
- unsigned _vio;
-
- double _sink_rate;
- double _sink_master;
- double _source_rate;
- double _source_master;
-
- unsigned _flags;
- unsigned _devices;
-};
-
-#endif // XTRX_OBJ_H
diff --git a/lib/xtrx/xtrx_sink_c.cc b/lib/xtrx/xtrx_sink_c.cc
deleted file mode 100644
index 5253311..0000000
--- a/lib/xtrx/xtrx_sink_c.cc
+++ /dev/null
@@ -1,505 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2016,2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#include <fstream>
-#include <string>
-#include <sstream>
-#include <map>
-
-#include <boost/assign.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/thread.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-
-#include <gnuradio/io_signature.h>
-#include <gnuradio/blocks/deinterleave.h>
-#include <gnuradio/blocks/float_to_complex.h>
-
-#include "xtrx_sink_c.h"
-
-#include "arg_helpers.h"
-
-static const int max_burstsz = 4096;
-using namespace boost::assign;
-
-xtrx_sink_c_sptr make_xtrx_sink_c(const std::string &args)
-{
- return gnuradio::get_initial_sptr(new xtrx_sink_c(args));
-}
-
-static size_t parse_nchan(const std::string &args)
-{
- size_t nchan = 1;
-
- dict_t dict = params_to_dict(args);
-
- if (dict.count("nchan"))
- nchan = boost::lexical_cast< size_t >( dict["nchan"] );
-
- if (nchan < 1)
- nchan = 1;
-
- return nchan;
-}
-
-xtrx_sink_c::xtrx_sink_c(const std::string &args) :
- gr::sync_block("xtrx_sink_c",
- gr::io_signature::make(parse_nchan(args),
- parse_nchan(args),
- sizeof(gr_complex)),
- gr::io_signature::make(0, 0, 0)),
- _sample_flags(0),
- _rate(0),
- _master(0),
- _freq(0),
- _corr(0),
- _bandwidth(0),
- _dsp(0),
- _auto_gain(false),
- _otw(XTRX_WF_16),
- _mimo_mode(false),
- _gain_tx(0),
- _channels(parse_nchan(args)),
- _ts(8192),
- _swap_ab(false),
- _swap_iq(false),
- _tdd(false),
- _allow_dis(false),
- _dev("")
-{
-
- dict_t dict = params_to_dict(args);
-
- if (dict.count("master")) {
- _master = boost::lexical_cast< double >( dict["master"]);
- }
-
- std::cerr << args.c_str() << std::endl;
-
- int loglevel = 4;
- if (dict.count("loglevel")) {
- loglevel = boost::lexical_cast< int >( dict["loglevel"] );
- }
-
- bool lmsreset = 0;
- if (dict.count("lmsreset")) {
- lmsreset = boost::lexical_cast< bool >( dict["lmsreset"] );
- }
-
- if (dict.count("txdelay")) {
- _ts += 8192 * boost::lexical_cast< int >( dict["txdelay"] );
- }
-
- if (dict.count("allowdis")) {
- _allow_dis = boost::lexical_cast< bool >( dict["allowdis"] );
- }
-
- if (dict.count("swap_ab")) {
- _swap_ab = true;
- std::cerr << "xtrx_sink_c: swap AB channels";
- }
-
- if (dict.count("swap_iq")) {
- _swap_iq = true;
- std::cerr << "xtrx_sink_c: swap IQ";
- }
-
- if (dict.count("sfl")) {
- _sample_flags = boost::lexical_cast< unsigned >( dict["sfl"] );
- }
-
- if (dict.count("tdd")) {
- _tdd = true;
- std::cerr << "xtrx_sink_c: TDD mode";
- }
-
- if (dict.count("dsp")) {
- _dsp = boost::lexical_cast< double >( dict["dsp"] );
- std::cerr << "xtrx_sink_c: DSP:" << _dsp;
- }
-
- if (dict.count("dev")) {
- _dev = dict["dev"];
- std::cerr << "xtrx_sink_c: XTRX device: %s" << _dev.c_str();
- }
-
- _xtrx = xtrx_obj::get(_dev.c_str(), loglevel, lmsreset);
- if (_xtrx->dev_count() * 2 == _channels) {
- _mimo_mode = true;
- } else if (_xtrx->dev_count() != _channels) {
- throw std::runtime_error("Number of requested channels != number of devices");
- }
- if (dict.count("refclk")) {
- xtrx_set_ref_clk(_xtrx->dev(), boost::lexical_cast< unsigned >( dict["refclk"] ), XTRX_CLKSRC_INT);
- }
- if (dict.count("extclk")) {
- xtrx_set_ref_clk(_xtrx->dev(), boost::lexical_cast< unsigned >( dict["extclk"] ), XTRX_CLKSRC_EXT);
- }
-
- std::cerr << "xtrx_sink_c::xtrx_sink_c()" << std::endl;
- set_alignment(32);
- set_output_multiple(max_burstsz);
-}
-
-xtrx_sink_c::~xtrx_sink_c()
-{
- std::cerr << "xtrx_sink_c::~xtrx_sink_c()" << std::endl;
-}
-
-std::string xtrx_sink_c::name()
-{
- return "GrLibXTRX";
-}
-
-size_t xtrx_sink_c::get_num_channels( void )
-{
- return input_signature()->max_streams();
-}
-
-osmosdr::meta_range_t xtrx_sink_c::get_sample_rates( void )
-{
- osmosdr::meta_range_t range;
- range += osmosdr::range_t( 1000000, 160000000, 1 );
- return range;
-}
-
-double xtrx_sink_c::set_sample_rate( double rate )
-{
- std::cerr << "Set sample rate " << rate << std::endl;
- _rate = _xtrx->set_smaplerate(rate, _master, true, _sample_flags);
- return get_sample_rate();
-}
-
-double xtrx_sink_c::get_sample_rate( void )
-{
- return _rate;
-}
-
-osmosdr::freq_range_t xtrx_sink_c::get_freq_range( size_t chan )
-{
- osmosdr::freq_range_t range;
- range += osmosdr::range_t( double(0.03e9), double(3.8e9), 1); // as far as we know
- return range;
-}
-
-double xtrx_sink_c::set_center_freq( double freq, size_t chan )
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
-
- _freq = freq;
- double corr_freq = (freq)*(1.0 + (_corr) * 0.000001);
-
- std::cerr << "TX Set freq " << freq << std::endl;
- xtrx_channel_t xchan = (xtrx_channel_t)(XTRX_CH_A << chan);
-
- int res = xtrx_tune_ex(_xtrx->dev(), (_tdd) ? XTRX_TUNE_TX_AND_RX_TDD : XTRX_TUNE_TX_FDD, xchan, corr_freq - _dsp, &_freq);
- if (res) {
- std::cerr << "Unable to deliver frequency " << corr_freq << std::endl;
- }
-
- res = xtrx_tune_ex(_xtrx->dev(), XTRX_TUNE_BB_TX, xchan, _dsp, NULL);
- return get_center_freq(chan);
-}
-
-double xtrx_sink_c::get_center_freq( size_t chan )
-{
- return _freq + _dsp;
-}
-
-double xtrx_sink_c::set_freq_corr( double ppm, size_t chan )
-{
- _corr = ppm;
-
- set_center_freq(_freq, chan);
-
- return get_freq_corr( chan );
-}
-
-double xtrx_sink_c::get_freq_corr( size_t chan )
-{
- return _corr;
-}
-
-
-static const std::vector<std::string> s_lna_list = boost::assign::list_of("TX");
-
-std::vector<std::string> xtrx_sink_c::get_gain_names( size_t chan )
-{
- return s_lna_list;
-}
-
-osmosdr::gain_range_t xtrx_sink_c::get_gain_range( size_t chan )
-{
- return get_gain_range("TX", chan);
-}
-
-osmosdr::gain_range_t xtrx_sink_c::get_gain_range( const std::string & name, size_t chan )
-{
- osmosdr::gain_range_t range;
- range += osmosdr::range_t( -31, 0, 1 );
- return range;
-}
-
-bool xtrx_sink_c::set_gain_mode( bool automatic, size_t chan )
-{
- _auto_gain = automatic;
- return get_gain_mode(chan);
-}
-
-bool xtrx_sink_c::get_gain_mode( size_t chan )
-{
- return _auto_gain;
-}
-
-double xtrx_sink_c::set_gain( double gain, size_t chan )
-{
- return set_gain(gain, "TX", chan);
-}
-
-double xtrx_sink_c::set_gain( double igain, const std::string & name, size_t chan )
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
-
- osmosdr::gain_range_t gains = xtrx_sink_c::get_gain_range( name, chan );
- double gain = gains.clip(igain);
- double actual_gain;
-
- std::cerr << "Set TX gain: " << igain << std::endl;
-
- int res = xtrx_set_gain(_xtrx->dev(), (xtrx_channel_t)(XTRX_CH_A << chan),
- XTRX_TX_PAD_GAIN, gain, &actual_gain);
- if (res) {
- std::cerr << "Unable to set gain `" << name.c_str() << "`; err=" << res << std::endl;
- }
-
- _gain_tx = actual_gain;
- return actual_gain;
-}
-
-double xtrx_sink_c::get_gain( size_t chan )
-{
- return get_gain("TX");
-}
-
-double xtrx_sink_c::get_gain( const std::string & name, size_t chan )
-{
- return _gain_tx;
-}
-
-double xtrx_sink_c::set_bandwidth( double bandwidth, size_t chan )
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
- std::cerr << "Set bandwidth " << bandwidth << " chan " << chan << std::endl;
-
- if (bandwidth <= 0.0) {
- bandwidth = get_sample_rate() * 0.75;
- if (bandwidth < 0.5e6) {
- bandwidth = 0.5e6;
- }
- }
-
- int res = xtrx_tune_tx_bandwidth(_xtrx->dev(),
- (xtrx_channel_t)(XTRX_CH_A << chan),
- bandwidth, &_bandwidth);
- if (res) {
- std::cerr << "Can't set bandwidth: " << res << std::endl;
- }
- return get_bandwidth(chan);
-}
-
-double xtrx_sink_c::get_bandwidth( size_t chan )
-{
- return _bandwidth;
-}
-
-
-static const std::map<std::string, xtrx_antenna_t> s_ant_map = boost::assign::map_list_of
- ("AUTO", XTRX_TX_AUTO)
- ("B1", XTRX_TX_H)
- ("B2", XTRX_TX_W)
- ("TXH", XTRX_TX_H)
- ("TXW", XTRX_TX_W)
- ;
-static const std::map<xtrx_antenna_t, std::string> s_ant_map_r = boost::assign::map_list_of
- (XTRX_TX_H, "TXH")
- (XTRX_TX_W, "TXW")
- (XTRX_TX_AUTO, "AUTO")
- ;
-
-static xtrx_antenna_t get_ant_type(const std::string& name)
-{
- std::map<std::string, xtrx_antenna_t>::const_iterator it;
-
- it = s_ant_map.find(name);
- if (it != s_ant_map.end()) {
- return it->second;
- }
-
- return XTRX_TX_AUTO;
-}
-
-static const std::vector<std::string> s_ant_list = boost::assign::list_of
- ("AUTO")("TXH")("TXW")
- ;
-
-
-std::vector< std::string > xtrx_sink_c::get_antennas( size_t chan )
-{
- return s_ant_list;
-}
-
-std::string xtrx_sink_c::set_antenna( const std::string & antenna, size_t chan )
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
- _ant = get_ant_type(antenna);
-
- std::cerr << "Set antenna " << antenna << std::endl;
-
- int res = xtrx_set_antenna_ex(_xtrx->dev(),
- (xtrx_channel_t)(XTRX_CH_A << chan),
- _ant);
- if (res) {
- std::cerr << "Can't set antenna: " << antenna << std::endl;
- }
- return get_antenna( chan );
-}
-
-std::string xtrx_sink_c::get_antenna( size_t chan )
-{
- return s_ant_map_r.find(_ant)->second;
-}
-
-void xtrx_sink_c::tag_process(int ninput_items)
-{
- std::sort(_tags.begin(), _tags.end(), gr::tag_t::offset_compare);
-
- const uint64_t samp0_count = this->nitems_read(0);
- uint64_t max_count = samp0_count + ninput_items;
-
- bool found_time_tag = false;
- for (const gr::tag_t &my_tag : _tags) {
- const uint64_t my_tag_count = my_tag.offset;
- const pmt::pmt_t &key = my_tag.key;
- const pmt::pmt_t &value = my_tag.value;
-
- if (my_tag_count >= max_count) {
- break;
- } else if(pmt::equal(key, TIME_KEY)) {
- //if (my_tag_count != samp0_count) {
- // max_count = my_tag_count;
- // break;
- //}
- found_time_tag = true;
- //_metadata.has_time_spec = true;
- //_metadata.time_spec = ::uhd::time_spec_t
- // (pmt::to_uint64(pmt::tuple_ref(value, 0)),
- // pmt::to_double(pmt::tuple_ref(value, 1)));
- uint64_t seconds = pmt::to_uint64(pmt::tuple_ref(value, 0));
- double fractional = pmt::to_double(pmt::tuple_ref(value, 1));
-
- std::cerr << "TX_TIME: " << seconds << ":" << fractional << std::endl;
- }
- } // end for
-
- if (found_time_tag) {
- //_metadata.has_time_spec = true;
- }
-}
-
-int xtrx_sink_c::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- int ninput_items = noutput_items;
- const uint64_t samp0_count = nitems_read(0);
- get_tags_in_range(_tags, 0, samp0_count, samp0_count + ninput_items);
- if (!_tags.empty())
- tag_process(ninput_items);
-
- xtrx_send_ex_info_t nfo;
- nfo.samples = noutput_items;
- nfo.buffer_count = input_items.size();
- nfo.buffers = &input_items[0];
- nfo.flags = XTRX_TX_DONT_BUFFER;
- if (!_allow_dis)
- nfo.flags |= XTRX_TX_NO_DISCARD;
- nfo.ts = _ts;
- nfo.timeout = 0;
-
- int res = xtrx_send_sync_ex(_xtrx->dev(), &nfo);
- if (res) {
- std::cerr << "Err: " << res << std::endl;
-
- std::stringstream message;
- message << "xtrx_send_burst_sync error: " << -res;
- throw std::runtime_error( message.str() );
- }
-
- _ts += noutput_items;
- for (unsigned i = 0; i < input_items.size(); i++) {
- consume(i, noutput_items);
- }
- return 0;
-}
-
-bool xtrx_sink_c::start()
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
-
- xtrx_run_params_t params;
- xtrx_run_params_init(&params);
-
- params.dir = XTRX_TX;
- if (!_mimo_mode)
- params.tx.flags |= XTRX_RSP_SISO_MODE;
-
- if (_swap_ab)
- params.tx.flags |= XTRX_RSP_SWAP_AB;
-
- if (_swap_iq)
- params.tx.flags |= XTRX_RSP_SWAP_IQ;
-
- params.tx.hfmt = XTRX_IQ_FLOAT32;
- params.tx.wfmt = _otw;
- params.tx.chs = XTRX_CH_AB;
- params.tx.paketsize = 0;
- params.rx_stream_start = 256*1024;
-
- int res = xtrx_run_ex(_xtrx->dev(), &params);
- if (res) {
- std::cerr << "Got error: " << res << std::endl;
- }
-
- return res == 0;
-}
-
-bool xtrx_sink_c::stop()
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
-
- //TODO:
- std::cerr << "xtrx_sink_c::stop()" << std::endl;
- int res = xtrx_stop(_xtrx->dev(), XTRX_TX);
- if (res) {
- std::cerr << "Got error: " << res << std::endl;
- }
-
- return res == 0;
-}
diff --git a/lib/xtrx/xtrx_sink_c.h b/lib/xtrx/xtrx_sink_c.h
deleted file mode 100644
index 1263858..0000000
--- a/lib/xtrx/xtrx_sink_c.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2016 Sergey Kostanabev <sergey.kostanbaev@fairwaves.co>
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef XTRX_SINK_C_H
-#define XTRX_SINK_C_H
-
-#include <gnuradio/block.h>
-#include <gnuradio/sync_block.h>
-
-#include "sink_iface.h"
-#include "xtrx_obj.h"
-
-
-static const pmt::pmt_t SOB_KEY = pmt::string_to_symbol("tx_sob");
-static const pmt::pmt_t EOB_KEY = pmt::string_to_symbol("tx_eob");
-static const pmt::pmt_t TIME_KEY = pmt::string_to_symbol("tx_time");
-static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("tx_freq");
-static const pmt::pmt_t COMMAND_KEY = pmt::string_to_symbol("tx_command");
-
-class xtrx_sink_c;
-
-typedef boost::shared_ptr< xtrx_sink_c > xtrx_sink_c_sptr;
-
-xtrx_sink_c_sptr make_xtrx_sink_c( const std::string & args = "" );
-
-class xtrx_sink_c :
- public gr::sync_block,
- public sink_iface
-{
-private:
- friend xtrx_sink_c_sptr make_xtrx_sink_c(const std::string &args);
-
- xtrx_sink_c(const std::string &args);
-
-public:
- ~xtrx_sink_c();
-
- std::string name();
-
- static std::vector< std::string > get_devices( bool fake = false ) { return xtrx_obj::get_devices(); }
-
- size_t get_num_channels( void );
-
- osmosdr::meta_range_t get_sample_rates( void );
- double set_sample_rate( double rate );
- double get_sample_rate( void );
-
- osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
- double set_center_freq( double freq, size_t chan = 0 );
- double get_center_freq( size_t chan = 0 );
- double set_freq_corr( double ppm, size_t chan = 0 );
- double get_freq_corr( size_t chan = 0 );
-
- std::vector<std::string> get_gain_names( size_t chan = 0 );
- osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
- osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
- bool set_gain_mode( bool automatic, size_t chan = 0 );
- bool get_gain_mode( size_t chan = 0 );
- double set_gain( double gain, size_t chan = 0 );
- double set_gain( double gain, const std::string & name, size_t chan = 0 );
- double get_gain( size_t chan = 0 );
- double get_gain( const std::string & name, size_t chan = 0 );
-
- std::vector< std::string > get_antennas( size_t chan = 0 );
- std::string set_antenna( const std::string & antenna, size_t chan = 0 );
- std::string get_antenna( size_t chan = 0 );
-
- double set_bandwidth( double bandwidth, size_t chan = 0 );
- double get_bandwidth( size_t chan = 0 );
-
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
- bool start();
- bool stop();
-
- void tag_process(int ninput_items);
-
-private:
- xtrx_obj_sptr _xtrx;
- std::vector<gr::tag_t> _tags;
-
- unsigned _sample_flags;
- double _rate;
- double _master;
- double _freq;
- double _corr;
- double _bandwidth;
- double _dsp;
- bool _auto_gain;
-
- xtrx_wire_format_t _otw;
- bool _mimo_mode;
-
- int _gain_tx;
-
- unsigned _channels;
- xtrx_antenna_t _ant;
-
- uint64_t _ts;
-
- bool _swap_ab;
- bool _swap_iq;
-
- bool _tdd;
- bool _allow_dis;
-
- std::string _dev;
-};
-
-#endif // xtrx_sink_c_H
diff --git a/lib/xtrx/xtrx_source_c.cc b/lib/xtrx/xtrx_source_c.cc
deleted file mode 100644
index 4fdc877..0000000
--- a/lib/xtrx/xtrx_source_c.cc
+++ /dev/null
@@ -1,583 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2016,2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#include <fstream>
-#include <string>
-#include <sstream>
-#include <map>
-
-#include <boost/assign.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/thread.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/mutex.hpp>
-
-#include <gnuradio/io_signature.h>
-#include <gnuradio/blocks/deinterleave.h>
-#include <gnuradio/blocks/float_to_complex.h>
-
-#include "xtrx_source_c.h"
-
-#include "arg_helpers.h"
-
-using namespace boost::assign;
-
-
-xtrx_source_c_sptr make_xtrx_source_c(const std::string &args)
-{
- return gnuradio::get_initial_sptr(new xtrx_source_c(args));
-}
-
-static size_t parse_nchan(const std::string &args)
-{
- size_t nchan = 1;
-
- dict_t dict = params_to_dict(args);
-
- if (dict.count("nchan"))
- nchan = boost::lexical_cast< size_t >( dict["nchan"] );
-
- if (nchan < 1)
- nchan = 1;
-
- return nchan;
-}
-
-xtrx_source_c::xtrx_source_c(const std::string &args) :
- gr::sync_block("xtrx_source_c",
- gr::io_signature::make(0, 0, 0),
- gr::io_signature::make(parse_nchan(args),
- parse_nchan(args),
- sizeof(gr_complex))),
- _sample_flags(0),
- _rate(0),
- _master(0),
- _freq(0),
- _corr(0),
- _bandwidth(0),
- _auto_gain(false),
- _otw(XTRX_WF_16),
- _mimo_mode(false),
- _gain_lna(0),
- _gain_tia(0),
- _gain_pga(0),
- _channels(parse_nchan(args)),
- _swap_ab(false),
- _swap_iq(false),
- _loopback(false),
- _tdd(false),
- _fbctrl(false),
- _timekey(false),
- _dsp(0)
-{
- _id = pmt::string_to_symbol(args);
-
- dict_t dict = params_to_dict(args);
-
- if (dict.count("otw_format")) {
- const std::string& otw = dict["otw_format"];
- if (otw == "sc16" || otw == "16") {
- _otw = XTRX_WF_16;
- } else if (otw == "sc12" || otw == "12") {
- _otw = XTRX_WF_12;
- } else if (otw == "sc8" || otw == "8") {
- _otw = XTRX_WF_8;
- } else {
- throw std::runtime_error("Parameter `otw_format` should be {sc16,sc12,sc8}");
- }
- }
-
- if (dict.count("master")) {
- _master = boost::lexical_cast< double >( dict["master"]);
- }
-
- std::cerr << args.c_str() << std::endl;
-
- int loglevel = 4;
- if (dict.count("loglevel")) {
- loglevel = boost::lexical_cast< int >( dict["loglevel"] );
- }
-
- bool lmsreset = 0;
- if (dict.count("lmsreset")) {
- lmsreset = boost::lexical_cast< bool >( dict["lmsreset"] );
- }
-
- if (dict.count("fbctrl")) {
- _fbctrl = boost::lexical_cast< bool >( dict["fbctrl"] );
- }
-
- if (dict.count("swap_ab")) {
- _swap_ab = true;
- std::cerr << "xtrx_source_c: swap AB channels";
- }
-
- if (dict.count("swap_iq")) {
- _swap_iq = true;
- std::cerr << "xtrx_source_c: swap IQ";
- }
-
- if (dict.count("sfl")) {
- _sample_flags = boost::lexical_cast< unsigned >( dict["sfl"] );
- }
-
- if (dict.count("loopback")) {
- _loopback = true;
- std::cerr << "xtrx_source_c: loopback";
- }
-
- if (dict.count("tdd")) {
- _tdd = true;
- std::cerr << "xtrx_source_c: TDD mode";
- }
-
- if (dict.count("dsp")) {
- _dsp = boost::lexical_cast< double >( dict["dsp"] );
- std::cerr << "xtrx_source_c: DSP:" << _dsp;
- }
-
- if (dict.count("dev")) {
- _dev = dict["dev"];
- std::cerr << "xtrx_source_c: XTRX device: %s" << _dev.c_str();
- }
-
- _xtrx = xtrx_obj::get(_dev.c_str(), loglevel, lmsreset);
- if (_xtrx->dev_count() * 2 == _channels) {
- _mimo_mode = true;
- } else if (_xtrx->dev_count() != _channels) {
- throw std::runtime_error("Number of requested channels != number of devices");
- }
-
- if (dict.count("refclk")) {
- xtrx_set_ref_clk(_xtrx->dev(), boost::lexical_cast< unsigned >( dict["refclk"] ), XTRX_CLKSRC_INT);
- }
- if (dict.count("extclk")) {
- xtrx_set_ref_clk(_xtrx->dev(), boost::lexical_cast< unsigned >( dict["extclk"] ), XTRX_CLKSRC_EXT);
- }
-
- if (dict.count("vio")) {
- unsigned vio = boost::lexical_cast< unsigned >( dict["vio"] );
- _xtrx->set_vio(vio);
- }
-
- if (dict.count("dac")) {
- unsigned dac = boost::lexical_cast< unsigned >( dict["dac"] );
- xtrx_val_set(_xtrx->dev(), XTRX_TRX, XTRX_CH_ALL, XTRX_VCTCXO_DAC_VAL, dac);
- }
-
- if (dict.count("pmode")) {
- unsigned pmode = boost::lexical_cast< unsigned >( dict["pmode"] );
- xtrx_val_set(_xtrx->dev(), XTRX_TRX, XTRX_CH_ALL, XTRX_LMS7_PWR_MODE, pmode);
- }
-
- if (dict.count("timekey")) {
- _timekey = boost::lexical_cast< bool >( dict["timekey"] );
- }
-
- std::cerr << "xtrx_source_c::xtrx_source_c()" << std::endl;
- set_alignment(32);
- if (_otw == XTRX_WF_16) {
- if (_mimo_mode)
- set_output_multiple(4096);
- else
- set_output_multiple(8192);
- } else if (_otw == XTRX_WF_8) {
- if (_mimo_mode)
- set_output_multiple(8192);
- else
- set_output_multiple(16384);
- }
-}
-
-xtrx_source_c::~xtrx_source_c()
-{
- std::cerr << "xtrx_source_c::~xtrx_source_c()" << std::endl;
-}
-
-std::string xtrx_source_c::name()
-{
- return "GrLibXTRX";
-}
-
-size_t xtrx_source_c::get_num_channels( void )
-{
- return output_signature()->max_streams();
-}
-
-osmosdr::meta_range_t xtrx_source_c::get_sample_rates( void )
-{
- osmosdr::meta_range_t range;
- range += osmosdr::range_t( 200000, 160000000, 1 );
- return range;
-}
-
-double xtrx_source_c::set_sample_rate( double rate )
-{
- std::cerr << "Set sample rate " << rate << std::endl;
- _rate = _xtrx->set_smaplerate(rate, _master, false, _sample_flags);
- return get_sample_rate();
-}
-
-double xtrx_source_c::get_sample_rate( void )
-{
- return _rate;
-}
-
-osmosdr::freq_range_t xtrx_source_c::get_freq_range( size_t chan )
-{
- osmosdr::freq_range_t range;
- range += osmosdr::range_t( double(0.03e9), double(3.8e9), 1); // as far as we know
- return range;
-}
-
-double xtrx_source_c::set_center_freq( double freq, size_t chan )
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
-
- _freq = freq;
- double corr_freq = (freq)*(1.0 + (_corr) * 0.000001);
-
- if (_tdd)
- return get_center_freq(chan);
-
- xtrx_channel_t xchan = (xtrx_channel_t)(XTRX_CH_A << chan);
-
- std::cerr << "Set freq " << freq << std::endl;
-
- int res = xtrx_tune_ex(_xtrx->dev(), XTRX_TUNE_RX_FDD, xchan, corr_freq - _dsp, &_freq);
- if (res) {
- std::cerr << "Unable to deliver frequency " << corr_freq << std::endl;
- }
-
- res = xtrx_tune_ex(_xtrx->dev(), XTRX_TUNE_BB_RX, xchan, _dsp, NULL);
-
- return get_center_freq(chan);
-}
-
-double xtrx_source_c::get_center_freq( size_t chan )
-{
- return _freq;
-}
-
-double xtrx_source_c::set_freq_corr( double ppm, size_t chan )
-{
- _corr = ppm;
-
- set_center_freq(_freq, chan);
-
- return get_freq_corr( chan );
-}
-
-double xtrx_source_c::get_freq_corr( size_t chan )
-{
- return _corr;
-}
-
-static const std::map<std::string, xtrx_gain_type_t> s_lna_map = boost::assign::map_list_of
- ("LNA", XTRX_RX_LNA_GAIN)
- ("TIA", XTRX_RX_TIA_GAIN)
- ("PGA", XTRX_RX_PGA_GAIN)
- ("LB", XTRX_RX_LB_GAIN)
- ;
-
-static xtrx_gain_type_t get_gain_type(const std::string& name)
-{
- std::map<std::string, xtrx_gain_type_t>::const_iterator it;
-
- it = s_lna_map.find(name);
- if (it != s_lna_map.end()) {
- return it->second;
- }
-
- return XTRX_RX_LNA_GAIN;
-}
-
-static const std::vector<std::string> s_lna_list = boost::assign::list_of
- ("LNA")("TIA")("PGA")("LB")
- ;
-
-std::vector<std::string> xtrx_source_c::get_gain_names( size_t chan )
-{
- return s_lna_list;
-}
-
-osmosdr::gain_range_t xtrx_source_c::get_gain_range( size_t chan )
-{
- return get_gain_range("LNA", chan);
-}
-
-osmosdr::gain_range_t xtrx_source_c::get_gain_range( const std::string & name, size_t chan )
-{
- osmosdr::gain_range_t range;
-
- if (name == "LNA") {
- range += osmosdr::range_t( 0, 24, 3 );
- range += osmosdr::range_t( 25, 30, 1 );
- } else if (name == "TIA") {
- range += osmosdr::range_t( 0 );
- range += osmosdr::range_t( 9 );
- range += osmosdr::range_t( 12 );
- } else if (name == "PGA") {
- range += osmosdr::range_t( -12.5, 12.5, 1 );
- } else if (name == "LB") {
- range += osmosdr::range_t( -40, 0, 1 );
- }
-
- return range;
-}
-
-bool xtrx_source_c::set_gain_mode( bool automatic, size_t chan )
-{
- _auto_gain = automatic;
- return get_gain_mode(chan);
-}
-
-bool xtrx_source_c::get_gain_mode( size_t chan )
-{
- return _auto_gain;
-}
-
-double xtrx_source_c::set_gain( double gain, size_t chan )
-{
- return set_gain(gain, "LNA", chan);
-}
-
-double xtrx_source_c::set_gain( double igain, const std::string & name, size_t chan )
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
-
- osmosdr::gain_range_t gains = xtrx_source_c::get_gain_range( name, chan );
- double gain = gains.clip(igain);
- double actual_gain;
- xtrx_gain_type_t gt = get_gain_type(name);
-
- std::cerr << "Set gain " << name << " (" << gt << "): " << igain << std::endl;
-
- int res = xtrx_set_gain(_xtrx->dev(), (xtrx_channel_t)(XTRX_CH_A << chan),
- gt, gain, &actual_gain);
- if (res) {
- std::cerr << "Unable to set gain `" << name.c_str() << "`; err=" << res << std::endl;
- }
-
- switch (gt) {
- case XTRX_RX_LNA_GAIN: _gain_lna = actual_gain; break;
- case XTRX_RX_TIA_GAIN: _gain_tia = actual_gain; break;
- case XTRX_RX_PGA_GAIN: _gain_pga = actual_gain; break;
- default: break;
- }
-
- return actual_gain;
-}
-
-double xtrx_source_c::get_gain( size_t chan )
-{
- return get_gain("LNA");
-}
-
-double xtrx_source_c::get_gain( const std::string & name, size_t chan )
-{
- xtrx_gain_type_t gt = get_gain_type(name);
- switch (gt) {
- case XTRX_RX_LNA_GAIN: return _gain_lna;
- case XTRX_RX_TIA_GAIN: return _gain_tia;
- case XTRX_RX_PGA_GAIN: return _gain_pga;
- default: return 0;
- }
-}
-
-double xtrx_source_c::set_if_gain(double gain, size_t chan)
-{
- return set_gain(gain, "PGA", chan);
-}
-
-double xtrx_source_c::set_bandwidth( double bandwidth, size_t chan )
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
- std::cerr << "Set bandwidth " << bandwidth << " chan " << chan << std::endl;
-
- if (bandwidth <= 0.0) {
- bandwidth = get_sample_rate() * 0.75;
- if (bandwidth < 0.5e6) {
- bandwidth = 0.5e6;
- }
- }
-
- int res = xtrx_tune_rx_bandwidth(_xtrx->dev(), (xtrx_channel_t)(XTRX_CH_A << chan),
- bandwidth, &_bandwidth);
- if (res) {
- std::cerr << "Can't set bandwidth: " << res << std::endl;
- }
- return get_bandwidth(chan);
-}
-
-double xtrx_source_c::get_bandwidth( size_t chan )
-{
- return _bandwidth;
-}
-
-osmosdr::freq_range_t xtrx_source_c::get_bandwidth_range( size_t chan )
-{
- return osmosdr::freq_range_t(500e3, 140e6, 0);
-}
-
-
-static const std::map<std::string, xtrx_antenna_t> s_ant_map = boost::assign::map_list_of
- ("AUTO", XTRX_RX_AUTO)
- ("RXL", XTRX_RX_L)
- ("RXH", XTRX_RX_H)
- ("RXW", XTRX_RX_W)
- ("RXL_LB", XTRX_RX_L_LB)
- ("RXW_LB", XTRX_RX_W_LB)
- ;
-static const std::map<xtrx_antenna_t, std::string> s_ant_map_r = boost::assign::map_list_of
- (XTRX_RX_AUTO, "AUTO")
- (XTRX_RX_L, "RXL")
- (XTRX_RX_H, "RXH")
- (XTRX_RX_W, "RXW")
- (XTRX_RX_L_LB, "RXL_LB")
- (XTRX_RX_W_LB, "RXW_LB")
- ;
-
-static xtrx_antenna_t get_ant_type(const std::string& name)
-{
- std::map<std::string, xtrx_antenna_t>::const_iterator it;
-
- it = s_ant_map.find(name);
- if (it != s_ant_map.end()) {
- return it->second;
- }
-
- return XTRX_RX_AUTO;
-}
-
-static const std::vector<std::string> s_ant_list = boost::assign::list_of
- ("AUTO")("RXL")("RXH")("RXW")
- ;
-
-
-std::vector< std::string > xtrx_source_c::get_antennas( size_t chan )
-{
- return s_ant_list;
-}
-
-std::string xtrx_source_c::set_antenna( const std::string & antenna, size_t chan )
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
- _ant = get_ant_type(antenna);
-
- std::cerr << "Set antenna " << antenna << " type:" << _ant << std::endl;
-
- int res = xtrx_set_antenna_ex(_xtrx->dev(), (xtrx_channel_t)(XTRX_CH_A << chan),
- _ant);
- if (res) {
- std::cerr << "Can't set antenna: " << antenna << std::endl;
- }
- return get_antenna( chan );
-}
-
-std::string xtrx_source_c::get_antenna( size_t chan )
-{
- return s_ant_map_r.find(_ant)->second;
-}
-
-int xtrx_source_c::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- xtrx_recv_ex_info_t ri;
- ri.samples = noutput_items;
- ri.buffer_count = output_items.size();
- ri.buffers = &output_items[0];
- ri.flags = RCVEX_DONT_INSER_ZEROS | RCVEX_DROP_OLD_ON_OVERFLOW;
- ri.timeout = 1000;
-
- int res = xtrx_recv_sync_ex(_xtrx->dev(), &ri);
- if (res) {
- std::stringstream message;
- message << "xtrx_recv_sync error: " << -res;
- throw std::runtime_error( message.str() );
- }
-
- if (_timekey) {
- uint64_t seconds = (ri.out_first_sample / _rate);
- double fractional = (ri.out_first_sample - (uint64_t)(_rate * seconds)) / _rate;
-
- //std::cerr << "Time " << seconds << ":" << fractional << std::endl;
- const pmt::pmt_t val = pmt::make_tuple
- (pmt::from_uint64(seconds),
- pmt::from_double(fractional));
- for(size_t i = 0; i < output_items.size(); i++) {
- this->add_item_tag(i, nitems_written(0), TIME_KEY,
- val, _id);
- this->add_item_tag(i, nitems_written(0), RATE_KEY,
- pmt::from_double(_rate), _id);
- this->add_item_tag(i, nitems_written(0), FREQ_KEY,
- pmt::from_double(this->get_center_freq(i)), _id);
- }
- }
- return ri.out_samples;
-}
-
-bool xtrx_source_c::start()
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
-
- xtrx_run_params_t params;
- xtrx_run_params_init(&params);
-
- params.dir = XTRX_RX;
- if (!_mimo_mode)
- params.rx.flags |= XTRX_RSP_SISO_MODE;
-
- if (_swap_ab)
- params.rx.flags |= XTRX_RSP_SWAP_AB;
-
- if (_swap_iq)
- params.rx.flags |= XTRX_RSP_SWAP_IQ;
-
- params.rx.hfmt = XTRX_IQ_FLOAT32;
- params.rx.wfmt = _otw;
- params.rx.chs = XTRX_CH_AB;
- params.rx.paketsize = 0;
- params.rx_stream_start = 256*1024;
-
- params.nflags = (_loopback) ? XTRX_RUN_DIGLOOPBACK : 0;
-
- int res = xtrx_run_ex(_xtrx->dev(), &params);
- if (res) {
- std::cerr << "Got error: " << res << std::endl;
- }
-
- res = xtrx_tune_ex(_xtrx->dev(), XTRX_TUNE_BB_RX, XTRX_CH_ALL, _dsp, NULL);
-
- return res == 0;
-}
-
-bool xtrx_source_c::stop()
-{
- boost::mutex::scoped_lock lock(_xtrx->mtx);
- //TODO:
- std::cerr << "xtrx_source_c::stop()" << std::endl;
- int res = xtrx_stop(_xtrx->dev(), XTRX_RX);
- if (res) {
- std::cerr << "Got error: " << res << std::endl;
- }
-
- return res == 0;
-}
diff --git a/lib/xtrx/xtrx_source_c.h b/lib/xtrx/xtrx_source_c.h
deleted file mode 100644
index fda9d77..0000000
--- a/lib/xtrx/xtrx_source_c.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2016,2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-#ifndef XTRX_SOURCE_C_H
-#define XTRX_SOURCE_C_H
-
-#include <gnuradio/block.h>
-#include <gnuradio/sync_block.h>
-
-#include "source_iface.h"
-#include "xtrx_obj.h"
-
-static const pmt::pmt_t TIME_KEY = pmt::string_to_symbol("rx_time");
-static const pmt::pmt_t RATE_KEY = pmt::string_to_symbol("rx_rate");
-static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("rx_freq");
-
-class xtrx_source_c;
-
-typedef boost::shared_ptr< xtrx_source_c > xtrx_source_c_sptr;
-
-xtrx_source_c_sptr make_xtrx_source_c( const std::string & args = "" );
-
-class xtrx_source_c :
- public gr::sync_block,
- public source_iface
-{
-private:
- friend xtrx_source_c_sptr make_xtrx_source_c(const std::string &args);
-
- xtrx_source_c(const std::string &args);
-
-public:
- ~xtrx_source_c();
-
- std::string name();
-
- static std::vector< std::string > get_devices( bool fake = false ) { return xtrx_obj::get_devices(); }
-
- size_t get_num_channels( void );
-
- osmosdr::meta_range_t get_sample_rates( void );
- double set_sample_rate( double rate );
- double get_sample_rate( void );
-
- osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
- double set_center_freq( double freq, size_t chan = 0 );
- double get_center_freq( size_t chan = 0 );
- double set_freq_corr( double ppm, size_t chan = 0 );
- double get_freq_corr( size_t chan = 0 );
-
- std::vector<std::string> get_gain_names( size_t chan = 0 );
- osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
- osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
- bool set_gain_mode( bool automatic, size_t chan = 0 );
- bool get_gain_mode( size_t chan = 0 );
- double set_gain( double gain, size_t chan = 0 );
- double set_gain( double gain, const std::string & name, size_t chan = 0 );
- double get_gain( size_t chan = 0 );
- double get_gain( const std::string & name, size_t chan = 0 );
-
- double set_if_gain( double gain, size_t chan = 0 );
-
- std::vector< std::string > get_antennas( size_t chan = 0 );
- std::string set_antenna( const std::string & antenna, size_t chan = 0 );
- std::string get_antenna( size_t chan = 0 );
-
- double set_bandwidth( double bandwidth, size_t chan = 0 );
- double get_bandwidth( size_t chan = 0 );
- osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0);
-
- int work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
- bool start();
- bool stop();
-
-private:
- xtrx_obj_sptr _xtrx;
- pmt::pmt_t _id;
-
- unsigned _sample_flags;
- double _rate;
- double _master;
- double _freq;
- double _corr;
- double _bandwidth;
- bool _auto_gain;
-
- xtrx_wire_format_t _otw;
- bool _mimo_mode;
-
- int _gain_lna;
- int _gain_tia;
- int _gain_pga;
-
- unsigned _channels;
- xtrx_antenna_t _ant;
-
- bool _swap_ab;
- bool _swap_iq;
- bool _loopback;
- bool _tdd;
- bool _fbctrl;
- bool _timekey;
-
- double _dsp;
- std::string _dev;
-};
-
-#endif // XTRX_SOURCE_C_H