osmocom-sdr
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- 921 discussions
09 Feb '20
From: Clayton Smith <argilo(a)gmail.com>
Currently, rtl_tcp_source_c repeatedly calls ::connect until it
succeeds. This can result in 100% CPU utilization and/or a lot of
network traffic. In addition, GUI applications like Gqrx freeze up.
To solve these problems, I've changed the code to report an error
if ::connect fails.
Also, I removed rtl_tcp_source_f since it is no longer used, and
corrected a few error messages in rtl_tcp_source_c so they print the
correct class name.
---
lib/rtl_tcp/rtl_tcp_source_c.cc | 10 +-
lib/rtl_tcp/rtl_tcp_source_f.cc | 327 --------------------------------
lib/rtl_tcp/rtl_tcp_source_f.h | 125 ------------
3 files changed, 5 insertions(+), 457 deletions(-)
delete mode 100644 lib/rtl_tcp/rtl_tcp_source_f.cc
delete mode 100644 lib/rtl_tcp/rtl_tcp_source_f.h
diff --git a/lib/rtl_tcp/rtl_tcp_source_c.cc b/lib/rtl_tcp/rtl_tcp_source_c.cc
index ecdeee0216..af8e30006b 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_f: unknown error %d WS err %d \n", perr, werr );
+ fprintf(stderr,"rtl_tcp_source_c: 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_f WSAStartup", "can't open socket" );
+ report_error( "rtl_tcp_source_c 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_f/getaddrinfo",
+ report_error("rtl_tcp_source_c/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
- while (::connect(d_socket, ip_src->ai_addr, ip_src->ai_addrlen) != 0)
- ; // FIXME handle errors?
+ 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");
freeaddrinfo(ip_src);
int flag = 1;
diff --git a/lib/rtl_tcp/rtl_tcp_source_f.cc b/lib/rtl_tcp/rtl_tcp_source_f.cc
deleted file mode 100644
index a17594c916..0000000000
--- a/lib/rtl_tcp/rtl_tcp_source_f.cc
+++ /dev/null
@@ -1,327 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2012 Hoernchen <la(a)tfc-server.de>
- * Copyright 2012 Dimitri Stolnikov <horiz0n(a)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.
- */
-//#define HAVE_WINDOWS_H
-
-
-#include <rtl_tcp_source_f.h>
-#include <gnuradio/io_signature.h>
-#include <stdexcept>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifndef _WIN32
-#include <netinet/in.h>
-#else
-#include <WinSock2.h>
-#endif
-
-/* copied from rtl sdr code */
-typedef struct { /* structure size must be multiple of 2 bytes */
- char magic[4];
- uint32_t tuner_type;
- uint32_t tuner_gain_count;
-} dongle_info_t;
-
-#define USE_SELECT 1 // non-blocking receive on all platforms
-#define USE_RCV_TIMEO 0 // non-blocking receive on all but Cygwin
-#define SRC_VERBOSE 0
-#define SNK_VERBOSE 0
-
-static int is_error( int perr )
-{
- // Compare error to posix error code; return nonzero if match.
-#if defined(USING_WINSOCK)
-#define ENOPROTOOPT 109
- // All codes to be checked for must be defined below
- int werr = WSAGetLastError();
- switch( werr ) {
- case WSAETIMEDOUT:
- return( perr == EAGAIN );
- case WSAENOPROTOOPT:
- return( perr == ENOPROTOOPT );
- default:
- fprintf(stderr,"rtl_tcp_source_f: unknown error %d WS err %d \n", perr, werr );
- throw std::runtime_error("internal error");
- }
- return 0;
-#else
- return( perr == errno );
-#endif
-}
-
-static void report_error( const char *msg1, const char *msg2 )
-{
- // Deal with errors, both posix and winsock
-#if defined(USING_WINSOCK)
- int werr = WSAGetLastError();
- fprintf(stderr, "%s: winsock error %d\n", msg1, werr );
-#else
- perror(msg1);
-#endif
- if( msg2 != NULL )
- throw std::runtime_error(msg2);
- return;
-}
-
-rtl_tcp_source_f::rtl_tcp_source_f(size_t itemsize,
- const char *host,
- unsigned short port,
- int payload_size,
- bool eof,
- bool wait)
- : gr::sync_block ("rtl_tcp_source_f",
- gr::io_signature::make(0, 0, 0),
- gr::io_signature::make(1, 1, sizeof(float))),
- d_itemsize(itemsize),
- d_payload_size(payload_size),
- d_eof(eof),
- d_wait(wait),
- d_socket(-1),
- d_temp_offset(0)
-{
- int ret = 0;
-#if defined(USING_WINSOCK) // for Windows (with MinGW)
- // initialize winsock DLL
- WSADATA wsaData;
- int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
- if( iResult != NO_ERROR ) {
- report_error( "rtl_tcp_source_f WSAStartup", "can't open socket" );
- }
-#endif
-
- // Set up the address stucture for the source address and port numbers
- // Get the source IP address from the host name
- struct addrinfo *ip_src; // store the source IP address to use
- struct addrinfo hints;
- memset( (void*)&hints, 0, sizeof(hints) );
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_flags = AI_PASSIVE;
- char port_str[12];
- sprintf( port_str, "%d", port );
-
- // FIXME leaks if report_error throws below
- ret = getaddrinfo( host, port_str, &hints, &ip_src );
- if( ret != 0 )
- report_error("rtl_tcp_source_f/getaddrinfo",
- "can't initialize source socket" );
-
- // FIXME leaks if report_error throws below
- d_temp_buff = new unsigned char[d_payload_size]; // allow it to hold up to payload_size bytes
- d_LUT= new float[0xff+1];
- for(int i=0; i <=(0xff);++i){
- d_LUT[i] = (((float)(i&0xff))-127.4f)*(1.0f/128.0f);
- }
- // create socket
- d_socket = socket(ip_src->ai_family, ip_src->ai_socktype,
- ip_src->ai_protocol);
- if(d_socket == -1) {
- report_error("socket open","can't open socket");
- }
-
- // Turn on reuse address
- int opt_val = 1;
- if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, sizeof(int)) == -1) {
- report_error("SO_REUSEADDR","can't set socket option SO_REUSEADDR");
- }
-
- // Don't wait when shutting down
- linger lngr;
- lngr.l_onoff = 1;
- lngr.l_linger = 0;
- if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) {
- if( !is_error(ENOPROTOOPT) ) { // no SO_LINGER for SOCK_DGRAM on Windows
- report_error("SO_LINGER","can't set socket option SO_LINGER");
- }
- }
-
-#if USE_RCV_TIMEO
- // Set a timeout on the receive function to not block indefinitely
- // This value can (and probably should) be changed
- // Ignored on Cygwin
-#if defined(USING_WINSOCK)
- DWORD timeout = 1000; // milliseconds
-#else
- timeval timeout;
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
-#endif
- if(setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (optval_t)&timeout, sizeof(timeout)) == -1) {
- report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO");
- }
-#endif // USE_RCV_TIMEO
-
- while(connect(d_socket, ip_src->ai_addr, ip_src->ai_addrlen) != 0);
- freeaddrinfo(ip_src);
-
- int flag = 1;
- setsockopt(d_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,sizeof(flag));
-
- dongle_info_t dongle_info;
- ret = recv(d_socket, (char*)&dongle_info, sizeof(dongle_info), 0);
- if (sizeof(dongle_info) != ret)
- fprintf(stderr,"failed to read dongle info\n");
-
- d_tuner_type = RTLSDR_TUNER_UNKNOWN;
- d_tuner_gain_count = 0;
- d_tuner_if_gain_count = 0;
-
- if (memcmp(dongle_info.magic, "RTL0", 4) == 0)
- {
- d_tuner_type = ntohl(dongle_info.tuner_type);
- d_tuner_gain_count = ntohl(dongle_info.tuner_gain_count);
- if ( RTLSDR_TUNER_E4000 == d_tuner_type )
- d_tuner_if_gain_count = 53;
- }
-}
-
-rtl_tcp_source_f_sptr make_rtl_tcp_source_f (size_t itemsize,
- const char *ipaddr,
- unsigned short port,
- int payload_size,
- bool eof,
- bool wait)
-{
- return gnuradio::get_initial_sptr(new rtl_tcp_source_f (
- itemsize,
- ipaddr,
- port,
- payload_size,
- eof,
- wait));
-}
-
-rtl_tcp_source_f::~rtl_tcp_source_f ()
-{
- delete [] d_temp_buff;
-
- if (d_socket != -1){
- shutdown(d_socket, SHUT_RDWR);
-#if defined(USING_WINSOCK)
- closesocket(d_socket);
-#else
- ::close(d_socket);
-#endif
- d_socket = -1;
- }
-
-#if defined(USING_WINSOCK) // for Windows (with MinGW)
- // free winsock resources
- WSACleanup();
-#endif
-}
-
-int rtl_tcp_source_f::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- float *out = (float *) output_items[0];
- ssize_t r = 0;
-
- int bytesleft = noutput_items;
- int index = 0;
- int receivedbytes = 0;
- while(bytesleft > 0) {
- receivedbytes = recv(d_socket, (char*)&d_temp_buff[index], bytesleft, 0);
-
- if(receivedbytes == -1 && !is_error(EAGAIN)){
- fprintf(stderr, "socket error\n");
- return -1;
- }
- bytesleft -= receivedbytes;
- index += receivedbytes;
- }
- r = noutput_items;
-
- for(int i=0; i<r; ++i)
- out[i]=d_LUT[*(d_temp_buff+d_temp_offset+i)];
-
- return r;
-}
-
-#ifdef _WIN32
-#define __attribute__(x)
-#pragma pack(push, 1)
-#endif
-struct command{
- unsigned char cmd;
- unsigned int param;
-}__attribute__((packed));
-#ifdef _WIN32
-#pragma pack(pop)
-#endif
-
-void rtl_tcp_source_f::set_freq(int freq)
-{
- struct command cmd = { 0x01, htonl(freq) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
-
-void rtl_tcp_source_f::set_sample_rate(int sample_rate)
-{
- struct command cmd = { 0x02, htonl(sample_rate) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
-
-void rtl_tcp_source_f::set_gain_mode(int manual)
-{
- struct command cmd = { 0x03, htonl(manual) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
-
-void rtl_tcp_source_f::set_gain(int gain)
-{
- struct command cmd = { 0x04, htonl(gain) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
-
-void rtl_tcp_source_f::set_freq_corr(int ppm)
-{
- struct command cmd = { 0x05, htonl(ppm) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
-
-void rtl_tcp_source_f::set_if_gain(int stage, int gain)
-{
- uint32_t params = stage << 16 | (gain & 0xffff);
- struct command cmd = { 0x06, htonl(params) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
-
-void rtl_tcp_source_f::set_agc_mode(int on)
-{
- struct command cmd = { 0x08, htonl(on) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
-
-void rtl_tcp_source_f::set_direct_sampling(int on)
-{
- struct command cmd = { 0x09, htonl(on) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
-
-void rtl_tcp_source_f::set_offset_tuning(int on)
-{
- struct command cmd = { 0x0a, htonl(on) };
- send(d_socket, (const char*)&cmd, sizeof(cmd), 0);
-}
diff --git a/lib/rtl_tcp/rtl_tcp_source_f.h b/lib/rtl_tcp/rtl_tcp_source_f.h
deleted file mode 100644
index 84ac57a2cd..0000000000
--- a/lib/rtl_tcp/rtl_tcp_source_f.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2012 Hoernchen <la(a)tfc-server.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.
- */
-
-#ifndef RTL_TCP_SOURCE_F_H
-#define RTL_TCP_SOURCE_F_H
-
-#include <gnuradio/sync_block.h>
-#include <gnuradio/thread/thread.h>
-
-#if defined(_WIN32)
-// if not posix, assume winsock
-#pragma comment(lib, "ws2_32.lib")
-#define USING_WINSOCK
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#define SHUT_RDWR 2
-typedef char* optval_t;
-#else
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-typedef void* optval_t;
-#endif
-
-#ifdef _MSC_VER
-#include <cstddef>
-typedef ptrdiff_t ssize_t;
-#endif //_MSC_VER
-
-/* copied from rtl sdr */
-enum rtlsdr_tuner {
- RTLSDR_TUNER_UNKNOWN = 0,
- RTLSDR_TUNER_E4000,
- RTLSDR_TUNER_FC0012,
- RTLSDR_TUNER_FC0013,
- RTLSDR_TUNER_FC2580,
- RTLSDR_TUNER_R820T,
- RTLSDR_TUNER_R828D
-};
-
-class rtl_tcp_source_f;
-typedef boost::shared_ptr<rtl_tcp_source_f> rtl_tcp_source_f_sptr;
-
-rtl_tcp_source_f_sptr make_rtl_tcp_source_f (
- size_t itemsize,
- const char *host,
- unsigned short port,
- int payload_size,
- bool eof = false,
- bool wait = false);
-
-class rtl_tcp_source_f : public gr::sync_block
-{
-private:
- size_t d_itemsize;
- int d_payload_size; // maximum transmission unit (packet length)
- bool d_eof; // zero-length packet is EOF
- bool d_wait; // wait if data if not immediately available
- int d_socket; // handle to socket
- unsigned char *d_temp_buff; // hold buffer between calls
- size_t d_temp_offset; // point to temp buffer location offset
- float *d_LUT;
-
- unsigned int d_tuner_type;
- unsigned int d_tuner_gain_count;
- unsigned int d_tuner_if_gain_count;
-
-private:
- rtl_tcp_source_f(size_t itemsize, const char *host,
- unsigned short port, int payload_size, bool eof, bool wait);
-
- // The friend declaration allows make_source_c to
- // access the private constructor.
- friend rtl_tcp_source_f_sptr make_rtl_tcp_source_f (
- size_t itemsize,
- const char *host,
- unsigned short port,
- int payload_size,
- bool eof,
- bool wait);
-
-public:
- ~rtl_tcp_source_f();
-
- enum rtlsdr_tuner get_tuner_type() { return (enum rtlsdr_tuner) d_tuner_type; }
- unsigned int get_tuner_gain_count() { return d_tuner_gain_count; }
- unsigned int get_tuner_if_gain_count() { return d_tuner_if_gain_count; }
-
- int work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
-
- void set_freq(int freq);
- void set_sample_rate(int sample_rate);
- void set_gain_mode(int manual);
- void set_gain(int gain);
- void set_freq_corr(int ppm);
- void set_if_gain(int stage, int gain);
- void set_agc_mode(int on);
- void set_direct_sampling(int on);
- void set_offset_tuning(int on);
-};
-
-
-#endif /* RTL_TCP_SOURCE_F_H */
--
2.17.1
1
0
From: Clayton Smith <argilo(a)gmail.com>
Currently gr-iqbal does not build with GNU Radio's master branch,
which declares itself to be version 3.9. This change allows both 3.8
and 3.9.
---
CMakeLists.txt | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1e8c0a5754..bc8a1aef0a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,7 +42,13 @@ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
# Find GNURadio
-find_package(Gnuradio "3.8" REQUIRED)
+find_package(Gnuradio "3.8")
+if(NOT Gnuradio_FOUND)
+ find_package(Gnuradio "3.9")
+ if(NOT Gnuradio_FOUND)
+ message(FATAL_ERROR "Unable to find GNURadio")
+ ENDIF(NOT Gnuradio_FOUND)
+ENDIF(NOT Gnuradio_FOUND)
# Set the version information here
set(VERSION_MAJOR 3)
--
2.17.1
1
0
From: Clayton Smith <argilo(a)gmail.com>
Since GNU Radio is gradually replacing Boost with C++11, it seemed worth
doing that for the HackRF blocks I was working on. This change removes
all usage of boost::assign.
---
lib/hackrf/hackrf_common.cc | 54 +++++++++++++++--------------------
lib/hackrf/hackrf_common.h | 1 +
lib/hackrf/hackrf_sink_c.cc | 11 +------
lib/hackrf/hackrf_source_c.cc | 11 +------
4 files changed, 26 insertions(+), 51 deletions(-)
diff --git a/lib/hackrf/hackrf_common.cc b/lib/hackrf/hackrf_common.cc
index 0a20f2ec9c..a6de22aab6 100644
--- a/lib/hackrf/hackrf_common.cc
+++ b/lib/hackrf/hackrf_common.cc
@@ -21,14 +21,10 @@
#include "config.h"
#endif
-#include <boost/assign.hpp>
-
#include "hackrf_common.h"
#include "arg_helpers.h"
-using namespace boost::assign;
-
int hackrf_common::_usage = 0;
std::mutex hackrf_common::_usage_mutex;
@@ -213,11 +209,11 @@ osmosdr::meta_range_t hackrf_common::get_sample_rates()
* 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 */
+ 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;
}
@@ -246,7 +242,7 @@ osmosdr::freq_range_t hackrf_common::get_freq_range( size_t chan )
{
osmosdr::freq_range_t range;
- range += osmosdr::range_t( _sample_rate / 2, 7250e6 - _sample_rate / 2 );
+ range.push_back(osmosdr::range_t( _sample_rate / 2, 7250e6 - _sample_rate / 2 ));
return range;
}
@@ -325,11 +321,7 @@ double hackrf_common::get_gain( size_t chan )
std::vector< std::string > hackrf_common::get_antennas( size_t chan )
{
- std::vector< std::string > antennas;
-
- antennas += get_antenna( chan );
-
- return antennas;
+ return { get_antenna( chan ) };
}
std::string hackrf_common::set_antenna( const std::string & antenna, size_t chan )
@@ -375,22 +367,22 @@ osmosdr::freq_range_t hackrf_common::get_bandwidth_range( size_t chan )
// 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 );
+ 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;
}
diff --git a/lib/hackrf/hackrf_common.h b/lib/hackrf/hackrf_common.h
index 02eabd2f0c..ea093b9680 100644
--- a/lib/hackrf/hackrf_common.h
+++ b/lib/hackrf/hackrf_common.h
@@ -20,6 +20,7 @@
#ifndef INCLUDED_HACKRF_COMMON_H
#define INCLUDED_HACKRF_COMMON_H
+#include <map>
#include <memory>
#include <mutex>
#include <string>
diff --git a/lib/hackrf/hackrf_sink_c.cc b/lib/hackrf/hackrf_sink_c.cc
index f003b89ce3..7271109b15 100644
--- a/lib/hackrf/hackrf_sink_c.cc
+++ b/lib/hackrf/hackrf_sink_c.cc
@@ -38,16 +38,12 @@
#include <emmintrin.h>
#endif
-#include <boost/assign.hpp>
-
#include <gnuradio/io_signature.h>
#include "hackrf_sink_c.h"
#include "arg_helpers.h"
-using namespace boost::assign;
-
static inline bool cb_init(circular_buffer_t *cb, size_t capacity, size_t sz)
{
cb->buffer = malloc(capacity * sz);
@@ -449,12 +445,7 @@ double hackrf_sink_c::get_freq_corr( size_t chan )
std::vector<std::string> hackrf_sink_c::get_gain_names( size_t chan )
{
- std::vector< std::string > names;
-
- names += "RF";
- names += "IF";
-
- return names;
+ return { "RF", "IF" };
}
osmosdr::gain_range_t hackrf_sink_c::get_gain_range( size_t chan )
diff --git a/lib/hackrf/hackrf_source_c.cc b/lib/hackrf/hackrf_source_c.cc
index 51a6580eca..eea5caafda 100644
--- a/lib/hackrf/hackrf_source_c.cc
+++ b/lib/hackrf/hackrf_source_c.cc
@@ -31,7 +31,6 @@
#include <stdexcept>
#include <iostream>
-#include <boost/assign.hpp>
#include <boost/detail/endian.hpp>
#include <gnuradio/io_signature.h>
@@ -40,8 +39,6 @@
#include "arg_helpers.h"
-using namespace boost::assign;
-
hackrf_source_c_sptr make_hackrf_source_c (const std::string & args)
{
return gnuradio::get_initial_sptr(new hackrf_source_c (args));
@@ -306,13 +303,7 @@ double hackrf_source_c::get_freq_corr( size_t chan )
std::vector<std::string> hackrf_source_c::get_gain_names( size_t chan )
{
- std::vector< std::string > names;
-
- names += "RF";
- names += "IF";
- names += "BB";
-
- return names;
+ return { "RF", "IF", "BB" };
}
osmosdr::gain_range_t hackrf_source_c::get_gain_range( size_t chan )
--
2.17.1
2
1
I can not transmit signal please help ? I am taking a low signal 165MHz after device is stopping to send signal. Why ? Please Help? İn this picture I take a very low signal after device stopped to send signal . Why I dont understand ?
1
0
I started application but dont transmit any signal ? Why ? I dont understand ?
I am listening in rtl sdr but dont transmit any signal . What is my error ? I dont contact any antenna to the device .
murat@murat-VivoBook-14-ASUS-Laptop-X407MA-X407MA:~$ pacat -r -d alsa_output.pci-0000_00_0e.0.analog-stereo.monitor | \
> pv -B 256k | \
> sox -t raw -r 44100 -e signed-integer -L -b 16 -c 2 - -c 1 -e signed-integer -b 16 -t raw - \
> biquad 4.76963 -2.98129 0 1 0.78833 0 sinc -15k loudness 5 | \
> fl2k_fm - -s 130e6 -c 30e6 -i 44100
Samplerate: 130.00 MHz
Carrier: 30.00 MHz
Frequencies: 100.00 MHz, 160.00 MHz
Failed to switch interface 0 to altsetting 1, trying to use interface 1
Allocating 6 zero-copy buffers
^C24,2MiB 0:18:45 [0,00 B/s] [ <=> ]
Signal caught, exiting!
^CSignal caught, exiting!
1
0
From: Clayton Smith <argilo(a)gmail.com>
To allow switching between transmit and receive mode within a single
flow graph, I've followed the model used by the BladeRF: I factored
common code into hackrf_common.cc and hackrf_common.h, and created a
"_devs" map there to keep track of which devices have been previously
opened. Shared pointers are used to track how many source & sink blocks
are using a particular device.
Because some properties (center frequency, sample rate, bandwidth, RF
amplifier state, bias tee) are shared between receive and transmit, the
blocks defer setting these until receiving or transmitting is started.
That way a source and sink can safely use different values for these
properties, and the correct values are set during T/R switching.
Because the HackRF driver and/or hardware does not seem to fully
transmit all samples sent to it, the code adds some silence to the end
of transmissions to ensure all samples are transmitted.
I've also replaced boost with C++11 code where possible.
---
lib/hackrf/CMakeLists.txt | 10 +-
lib/hackrf/hackrf_common.cc | 432 ++++++++++++++++++++++++++++++++++
lib/hackrf/hackrf_common.h | 111 +++++++++
lib/hackrf/hackrf_sink_c.cc | 414 +++++++-------------------------
lib/hackrf/hackrf_sink_c.h | 37 +--
lib/hackrf/hackrf_source_c.cc | 405 ++++---------------------------
lib/hackrf/hackrf_source_c.h | 36 +--
7 files changed, 693 insertions(+), 752 deletions(-)
create mode 100644 lib/hackrf/hackrf_common.cc
create mode 100644 lib/hackrf/hackrf_common.h
diff --git a/lib/hackrf/CMakeLists.txt b/lib/hackrf/CMakeLists.txt
index b817518f4c..d099b41c39 100644
--- a/lib/hackrf/CMakeLists.txt
+++ b/lib/hackrf/CMakeLists.txt
@@ -31,16 +31,8 @@ target_link_libraries(gnuradio-osmosdr
)
list(APPEND gr_osmosdr_srcs
+ ${CMAKE_CURRENT_SOURCE_DIR}/hackrf_common.cc
${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")
- target_compile_definitions(gnuradio-osmosdr PRIVATE -DLIBHACKRF_HAVE_DEVICE_LIST)
-endif(LIBHACKRF_HAVE_DEVICE_LIST)
diff --git a/lib/hackrf/hackrf_common.cc b/lib/hackrf/hackrf_common.cc
new file mode 100644
index 0000000000..0a20f2ec9c
--- /dev/null
+++ b/lib/hackrf/hackrf_common.cc
@@ -0,0 +1,432 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2020 Clayton Smith <argilo(a)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 <boost/assign.hpp>
+
+#include "hackrf_common.h"
+
+#include "arg_helpers.h"
+
+using namespace boost::assign;
+
+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),
+ _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 += 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_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 += 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 )
+{
+ std::vector< std::string > antennas;
+
+ antennas += get_antenna( chan );
+
+ return antennas;
+}
+
+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 );
+
+ 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 += 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;
+}
+
+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_bandwidth(get_bandwidth());
+ set_center_freq(get_center_freq());
+ set_sample_rate(get_sample_rate());
+ 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
new file mode 100644
index 0000000000..02eabd2f0c
--- /dev/null
+++ b/lib/hackrf/hackrf_common.h
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2020 Clayton Smith <argilo(a)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 <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 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"
+
+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 _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 ee089c642c..f003b89ce3 100644
--- a/lib/hackrf/hackrf_sink_c.cc
+++ b/lib/hackrf/hackrf_sink_c.cc
@@ -2,19 +2,20 @@
/*
* Copyright 2013 Dimitri Stolnikov <horiz0n(a)gmx.net>
* Copyright 2014 Hoernchen <la(a)tfc-server.de>
+ * Copyright 2020 Clayton Smith <argilo(a)gmail.com>
*
- * GNU Radio is free software; you can redistribute it and/or modify
+ * 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.
*
- * GNU Radio is distributed in the hope that it will be useful,
+ * 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 GNU Radio; see the file COPYING. If not, write to
+ * 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.
*/
@@ -38,10 +39,6 @@
#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>
@@ -51,24 +48,6 @@
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);
@@ -103,6 +82,11 @@ 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)
@@ -127,9 +111,6 @@ 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));
@@ -156,66 +137,21 @@ 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))),
- _dev(NULL),
+ hackrf_common::hackrf_common(args),
_buf(NULL),
- _sample_rate(0),
- _center_freq(0),
- _freq_corr(0),
- _auto_gain(false),
- _amp_gain(0),
- _vga_gain(0),
- _bandwidth(0)
+ _vga_gain(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 = boost::lexical_cast< unsigned int >( dict["buffers"] );
+ _buf_num = std::stoi(dict["buffers"]);
if (0 == _buf_num)
_buf_num = BUF_NUM;
- {
- 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;
+ _stopping = false;
if ( BUF_NUM != _buf_num ) {
std::cerr << "Using " << _buf_num << " buffers of size " << BUF_LEN << "."
@@ -232,26 +168,12 @@ 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") ) {
- 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;
- }
+ hackrf_common::set_bias(dict["bias_tx"] == "1");
}
_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")
}
/*
@@ -259,30 +181,6 @@ 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;
@@ -302,11 +200,16 @@ int hackrf_sink_c::hackrf_tx_callback(unsigned char *buffer, uint32_t length)
*buffer++ = rand() % 255;
#else
{
- boost::mutex::scoped_lock lock( _buf_mutex );
+ std::unique_lock<std::mutex> lock(_buf_mutex);
if ( ! cb_pop_front( &_cbuf, buffer ) ) {
memset(buffer, 0, length);
- std::cerr << "U" << std::flush;
+ if (_stopping) {
+ _buf_cond.notify_one();
+ return -1;
+ } else {
+ std::cerr << "U" << std::flush;
+ }
} else {
// std::cerr << "-" << std::flush;
_buf_cond.notify_one();
@@ -316,42 +219,61 @@ 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 )
+ if ( ! _dev.get() )
return false;
+ _stopping = false;
_buf_used = 0;
-#if 0
- int ret = hackrf_start_tx( _dev, _hackrf_tx_callback, (void *)this );
+ hackrf_common::start();
+ int ret = hackrf_start_tx( _dev.get(), _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()
{
- if ( ! _dev )
+ int i;
+
+ if ( ! _dev.get() )
return false;
-#if 0
- int ret = hackrf_stop_tx( _dev );
+
+ {
+ 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 ( ret != HACKRF_SUCCESS ) {
std::cerr << "Failed to stop TX streaming (" << ret << ")" << std::endl;
return false;
}
-#endif
return true;
}
@@ -424,7 +346,7 @@ int hackrf_sink_c::work( int noutput_items,
const gr_complex *in = (const gr_complex *) input_items[0];
{
- boost::mutex::scoped_lock lock( _buf_mutex );
+ std::unique_lock<std::mutex> lock(_buf_mutex);
while ( ! cb_has_room(&_cbuf) )
_buf_cond.wait( lock );
@@ -454,7 +376,7 @@ int hackrf_sink_c::work( int noutput_items,
if((unsigned int)noutput_items >= remaining) {
{
- boost::mutex::scoped_lock lock( _buf_mutex );
+ std::unique_lock<std::mutex> lock(_buf_mutex);
if ( ! cb_push_back( &_cbuf, _buf ) ) {
_buf_used = prev_buf_used;
@@ -477,78 +399,7 @@ int hackrf_sink_c::work( int noutput_items,
std::vector<std::string> hackrf_sink_c::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;
+ return hackrf_common::get_devices();
}
size_t hackrf_sink_c::get_num_channels()
@@ -558,88 +409,42 @@ size_t hackrf_sink_c::get_num_channels()
osmosdr::meta_range_t hackrf_sink_c::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;
+ return hackrf_common::get_sample_rates();
}
double hackrf_sink_c::set_sample_rate( double 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();
+ return hackrf_common::set_sample_rate(rate);
}
double hackrf_sink_c::get_sample_rate()
{
- return _sample_rate;
+ return hackrf_common::get_sample_rate();
}
osmosdr::freq_range_t hackrf_sink_c::get_freq_range( size_t chan )
{
- osmosdr::freq_range_t range;
-
- range += osmosdr::range_t( _sample_rate / 2, 7250e6 - _sample_rate / 2 );
-
- return range;
+ return hackrf_common::get_freq_range(chan);
}
double hackrf_sink_c::set_center_freq( double freq, size_t 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 );
+ return hackrf_common::set_center_freq(freq, chan);
}
double hackrf_sink_c::get_center_freq( size_t chan )
{
- return _center_freq;
+ return hackrf_common::get_center_freq(chan);
}
double hackrf_sink_c::set_freq_corr( double ppm, size_t chan )
{
- _freq_corr = ppm;
-
- set_center_freq( _center_freq );
-
- return get_freq_corr( chan );
+ return hackrf_common::set_freq_corr(ppm, chan);
}
double hackrf_sink_c::get_freq_corr( size_t chan )
{
- return _freq_corr;
+ return hackrf_common::get_freq_corr(chan);
}
std::vector<std::string> hackrf_sink_c::get_gain_names( size_t chan )
@@ -672,34 +477,17 @@ 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 )
{
- _auto_gain = automatic;
-
- return get_gain_mode(chan);
+ return hackrf_common::set_gain_mode(automatic, chan);
}
bool hackrf_sink_c::get_gain_mode( size_t chan )
{
- return _auto_gain;
+ return hackrf_common::get_gain_mode(chan);
}
double hackrf_sink_c::set_gain( double gain, size_t 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;
+ return hackrf_common::set_gain(gain, chan);
}
double hackrf_sink_c::set_gain( double gain, const std::string & name, size_t chan)
@@ -717,7 +505,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 _amp_gain;
+ return hackrf_common::get_gain(chan);
}
double hackrf_sink_c::get_gain( const std::string & name, size_t chan )
@@ -738,10 +526,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) {
+ if (_dev.get()) {
double clip_gain = if_gains.clip( gain, true );
- ret = hackrf_set_txvga_gain( _dev, uint32_t(clip_gain) );
+ ret = hackrf_set_txvga_gain( _dev.get(), uint32_t(clip_gain) );
if ( HACKRF_SUCCESS == ret ) {
_vga_gain = clip_gain;
} else {
@@ -759,72 +547,30 @@ double hackrf_sink_c::set_bb_gain( double gain, size_t chan )
std::vector< std::string > hackrf_sink_c::get_antennas( size_t chan )
{
- std::vector< std::string > antennas;
-
- antennas += get_antenna( chan );
-
- return antennas;
+ return hackrf_common::get_antennas(chan);
}
std::string hackrf_sink_c::set_antenna( const std::string & antenna, size_t chan )
{
- return get_antenna( chan );
+ return hackrf_common::set_antenna(antenna, chan);
}
std::string hackrf_sink_c::get_antenna( size_t chan )
{
- return "TX/RX";
+ return hackrf_common::get_antenna(chan);
}
double hackrf_sink_c::set_bandwidth( double bandwidth, size_t 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;
+ return hackrf_common::set_bandwidth(bandwidth, chan);
}
double hackrf_sink_c::get_bandwidth( size_t chan )
{
- return _bandwidth;
+ return hackrf_common::get_bandwidth(chan);
}
osmosdr::freq_range_t hackrf_sink_c::get_bandwidth_range( size_t 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;
+ return hackrf_common::get_bandwidth_range(chan);
}
diff --git a/lib/hackrf/hackrf_sink_c.h b/lib/hackrf/hackrf_sink_c.h
index a7e7ab86f5..08ff2ca8b3 100644
--- a/lib/hackrf/hackrf_sink_c.h
+++ b/lib/hackrf/hackrf_sink_c.h
@@ -1,34 +1,35 @@
/* -*- c++ -*- */
/*
* Copyright 2013 Dimitri Stolnikov <horiz0n(a)gmx.net>
+ * Copyright 2020 Clayton Smith <argilo(a)gmail.com>
*
- * GNU Radio is free software; you can redistribute it and/or modify
+ * 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.
*
- * GNU Radio is distributed in the hope that it will be useful,
+ * 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 GNU Radio; see the file COPYING. If not, write to
+ * 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_SINK_C_H
#define INCLUDED_HACKRF_SINK_C_H
-#include <gnuradio/thread/thread.h>
#include <gnuradio/sync_block.h>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition_variable.hpp>
+#include <condition_variable>
+#include <mutex>
#include <libhackrf/hackrf.h>
#include "sink_iface.h"
+#include "hackrf_common.h"
class hackrf_sink_c;
@@ -67,7 +68,8 @@ hackrf_sink_c_sptr make_hackrf_sink_c (const std::string & args = "");
class hackrf_sink_c :
public gr::sync_block,
- public sink_iface
+ public sink_iface,
+ protected hackrf_common
{
private:
// The friend declaration allows hackrf_make_sink_c to
@@ -124,29 +126,16 @@ 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;
- boost::mutex _buf_mutex;
- boost::condition_variable _buf_cond;
-
- double _sample_rate;
- double _center_freq;
- double _freq_corr;
- bool _auto_gain;
- double _amp_gain;
+ bool _stopping;
+ std::mutex _buf_mutex;
+ std::condition_variable _buf_cond;
+
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 30b63c780b..51a6580eca 100644
--- a/lib/hackrf/hackrf_source_c.cc
+++ b/lib/hackrf/hackrf_source_c.cc
@@ -1,19 +1,20 @@
/* -*- c++ -*- */
/*
* Copyright 2013 Dimitri Stolnikov <horiz0n(a)gmx.net>
+ * Copyright 2020 Clayton Smith <argilo(a)gmail.com>
*
- * GNU Radio is free software; you can redistribute it and/or modify
+ * 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.
*
- * GNU Radio is distributed in the hope that it will be useful,
+ * 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 GNU Radio; see the file COPYING. If not, write to
+ * 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.
*/
@@ -31,10 +32,7 @@
#include <iostream>
#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>
@@ -44,27 +42,6 @@
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));
@@ -91,29 +68,20 @@ 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))),
- _dev(NULL),
+ hackrf_common::hackrf_common(args),
_buf(NULL),
- _sample_rate(0),
- _center_freq(0),
- _freq_corr(0),
- _auto_gain(false),
- _amp_gain(0),
_lna_gain(0),
- _vga_gain(0),
- _bandwidth(0)
+ _vga_gain(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 = boost::lexical_cast< unsigned int >( dict["buffers"] );
+ _buf_num = std::stoi(dict["buffers"]);
// if (dict.count("buflen"))
-// _buf_len = boost::lexical_cast< unsigned int >( dict["buflen"] );
+// _buf_len = std::stoi(dict["buflen"]);
if (0 == _buf_num)
_buf_num = BUF_NUM;
@@ -134,66 +102,6 @@ hackrf_source_c::hackrf_source_c (const std::string &args)
#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;
@@ -211,16 +119,7 @@ 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") ) {
- 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;
- }
+ hackrf_common::set_bias(dict["bias"] == "1");
}
_buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
@@ -229,11 +128,6 @@ hackrf_source_c::hackrf_source_c (const std::string &args)
for(unsigned int i = 0; i < _buf_num; ++i)
_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")
}
/*
@@ -241,30 +135,6 @@ 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]);
@@ -284,7 +154,7 @@ int hackrf_source_c::_hackrf_rx_callback(hackrf_transfer *transfer)
int hackrf_source_c::hackrf_rx_callback(unsigned char *buf, uint32_t len)
{
{
- boost::mutex::scoped_lock lock( _buf_mutex );
+ std::unique_lock<std::mutex> lock(_buf_mutex);
int buf_tail = (_buf_head + _buf_used) % _buf_num;
memcpy(_buf[buf_tail], buf, len);
@@ -302,40 +172,31 @@ 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 )
+ if ( ! _dev.get() )
return false;
-#if 0
- int ret = hackrf_start_rx( _dev, _hackrf_rx_callback, (void *)this );
+
+ hackrf_common::start();
+ int ret = hackrf_start_rx( _dev.get(), _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 )
+ if ( ! _dev.get() )
return false;
-#if 0
- int ret = hackrf_stop_rx( _dev );
+
+ hackrf_common::stop();
+ int ret = hackrf_stop_rx( _dev.get() );
if ( ret != HACKRF_SUCCESS ) {
std::cerr << "Failed to stop RX streaming (" << ret << ")" << std::endl;
return false;
}
-#endif
return true;
}
@@ -347,11 +208,11 @@ int hackrf_source_c::work( int noutput_items,
bool running = false;
- if ( _dev )
- running = (hackrf_is_streaming( _dev ) == HACKRF_TRUE);
+ if ( _dev.get() )
+ running = (hackrf_is_streaming( _dev.get() ) == HACKRF_TRUE);
{
- boost::mutex::scoped_lock lock( _buf_mutex );
+ std::unique_lock<std::mutex> lock(_buf_mutex);
while (_buf_used < 3 && running) // collect at least 3 buffers
_buf_cond.wait( lock );
@@ -373,7 +234,7 @@ int hackrf_source_c::work( int noutput_items,
*out++ = _lut[ *(buf + i) ];
{
- boost::mutex::scoped_lock lock( _buf_mutex );
+ std::unique_lock<std::mutex> lock(_buf_mutex);
_buf_head = (_buf_head + 1) % _buf_num;
_buf_used--;
@@ -395,78 +256,7 @@ int hackrf_source_c::work( int noutput_items,
std::vector<std::string> hackrf_source_c::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;
+ return hackrf_common::get_devices();
}
size_t hackrf_source_c::get_num_channels()
@@ -476,88 +266,42 @@ size_t hackrf_source_c::get_num_channels()
osmosdr::meta_range_t hackrf_source_c::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;
+ return hackrf_common::get_sample_rates();
}
double hackrf_source_c::set_sample_rate( double 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();
+ return hackrf_common::set_sample_rate(rate);
}
double hackrf_source_c::get_sample_rate()
{
- return _sample_rate;
+ return hackrf_common::get_sample_rate();
}
osmosdr::freq_range_t hackrf_source_c::get_freq_range( size_t chan )
{
- osmosdr::freq_range_t range;
-
- range += osmosdr::range_t( _sample_rate / 2, 7250e6 - _sample_rate / 2 );
-
- return range;
+ return hackrf_common::get_freq_range(chan);
}
double hackrf_source_c::set_center_freq( double freq, size_t 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 );
+ return hackrf_common::set_center_freq(freq, chan);
}
double hackrf_source_c::get_center_freq( size_t chan )
{
- return _center_freq;
+ return hackrf_common::get_center_freq(chan);
}
double hackrf_source_c::set_freq_corr( double ppm, size_t chan )
{
- _freq_corr = ppm;
-
- set_center_freq( _center_freq );
-
- return get_freq_corr( chan );
+ return hackrf_common::set_freq_corr(ppm, chan);
}
double hackrf_source_c::get_freq_corr( size_t chan )
{
- return _freq_corr;
+ return hackrf_common::get_freq_corr(chan);
}
std::vector<std::string> hackrf_source_c::get_gain_names( size_t chan )
@@ -595,34 +339,17 @@ 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 )
{
- _auto_gain = automatic;
-
- return get_gain_mode(chan);
+ return hackrf_common::set_gain_mode(automatic, chan);
}
bool hackrf_source_c::get_gain_mode( size_t chan )
{
- return _auto_gain;
+ return hackrf_common::get_gain_mode(chan);
}
double hackrf_source_c::set_gain( double gain, size_t 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;
+ return hackrf_common::set_gain(gain, chan);
}
double hackrf_source_c::set_gain( double gain, const std::string & name, size_t chan)
@@ -644,7 +371,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 _amp_gain;
+ return hackrf_common::get_gain(chan);
}
double hackrf_source_c::get_gain( const std::string & name, size_t chan )
@@ -669,10 +396,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) {
+ if (_dev.get()) {
double clip_gain = rf_gains.clip( gain, true );
- ret = hackrf_set_lna_gain( _dev, uint32_t(clip_gain) );
+ ret = hackrf_set_lna_gain( _dev.get(), uint32_t(clip_gain) );
if ( HACKRF_SUCCESS == ret ) {
_lna_gain = clip_gain;
} else {
@@ -688,10 +415,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) {
+ if (_dev.get()) {
double clip_gain = if_gains.clip( gain, true );
- ret = hackrf_set_vga_gain( _dev, uint32_t(clip_gain) );
+ ret = hackrf_set_vga_gain( _dev.get(), uint32_t(clip_gain) );
if ( HACKRF_SUCCESS == ret ) {
_vga_gain = clip_gain;
} else {
@@ -704,72 +431,30 @@ double hackrf_source_c::set_bb_gain( double gain, size_t chan )
std::vector< std::string > hackrf_source_c::get_antennas( size_t chan )
{
- std::vector< std::string > antennas;
-
- antennas += get_antenna( chan );
-
- return antennas;
+ return hackrf_common::get_antennas(chan);
}
std::string hackrf_source_c::set_antenna( const std::string & antenna, size_t chan )
{
- return get_antenna( chan );
+ return hackrf_common::set_antenna(antenna, chan);
}
std::string hackrf_source_c::get_antenna( size_t chan )
{
- return "TX/RX";
+ return hackrf_common::get_antenna(chan);
}
double hackrf_source_c::set_bandwidth( double bandwidth, size_t 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;
+ return hackrf_common::set_bandwidth(bandwidth, chan);
}
double hackrf_source_c::get_bandwidth( size_t chan )
{
- return _bandwidth;
+ return hackrf_common::get_bandwidth(chan);
}
osmosdr::freq_range_t hackrf_source_c::get_bandwidth_range( size_t 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;
+ return hackrf_common::get_bandwidth_range(chan);
}
diff --git a/lib/hackrf/hackrf_source_c.h b/lib/hackrf/hackrf_source_c.h
index 6ae81d2511..e9aacb95b3 100644
--- a/lib/hackrf/hackrf_source_c.h
+++ b/lib/hackrf/hackrf_source_c.h
@@ -1,36 +1,35 @@
/* -*- c++ -*- */
/*
* Copyright 2013 Dimitri Stolnikov <horiz0n(a)gmx.net>
+ * Copyright 2020 Clayton Smith <argilo(a)gmail.com>
*
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
+ * 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.
*
- * GNU Radio is distributed in the hope that it will be useful,
+ * 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 GNU Radio; see the file COPYING. If not, write to
+ * 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_SOURCE_C_H
#define INCLUDED_HACKRF_SOURCE_C_H
-#include <gnuradio/thread/thread.h>
#include <gnuradio/sync_block.h>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition_variable.hpp>
+#include <condition_variable>
+#include <mutex>
#include <libhackrf/hackrf.h>
#include "source_iface.h"
+#include "hackrf_common.h"
class hackrf_source_c;
@@ -62,12 +61,12 @@ hackrf_source_c_sptr make_hackrf_source_c (const std::string & args = "");
*/
class hackrf_source_c :
public gr::sync_block,
- public source_iface
+ public source_iface,
+ protected hackrf_common
{
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);
/*!
@@ -123,35 +122,22 @@ 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<gr_complex> _lut;
- 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;
- boost::mutex _buf_mutex;
- boost::condition_variable _buf_cond;
+ std::mutex _buf_mutex;
+ std::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 */
--
2.17.1
2
1
Dear all,
I just subscribed to this list since I encountered an issue after
pulling the latest git commits.
> lib: use interface 0 altsetting 1 instead of interface 1 ...
> This makes osmo-fl2k work again with Linux 5.5.0-rc6 or later,
On my system (Debian stable, kernel 4.19) this change results in
"Error enabling IF 0 altsetting 1". Reverting to the
previous version (with Interface 1) solved the problem for me.
I will investigate a bit more whether it is related to kernel or
libusb versions. Or have I missed some other required configuration?
Best regards,
Carl-Fredrik SM2YHP
--
------------------
Carl-Fredrik Enell
Föraregatan 26B
SE-98139 Kiruna
+46705508256
-----------------
2
3
Hi all:
I'm trying to build the latest gr-osmosdr package from the gr3.8 branch, but I'm
seeing some unusual errors, and I'm not quite sure what the deal is.
I'll note the following:
- I had errors related to existing python2 packages, so I tried building with Python3.
I'd be less than surprised if someone says that this is the cause of the issues, but
personally, I'd like to roll with the Py3 products from now on, what with Py2 being EOL…
- OS is Arch.
My cmake command was:
```
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DPYTHON_EXECUTABLE=$(which python3) \
-DPYTHON_INCLUDE_DIR=$(echo /usr/include/python3*) \
-DPYTHON_LIBRARY=$(echo /usr/lib/libpython3.*.so) \
-DENABLE_DOXYGEN=1 \
-DCMAKE_INSTALL_PREFIX=/usr ../
```
Output from cmake:
```
-- ######################################################
-- # Gnuradio enabled components
-- ######################################################
-- * Python support
-- * sysmocom OsmoSDR
-- * IQ File Source & Sink
-- * Osmocom RTLSDR
-- * RTLSDR TCP Client
-- * Ettus USRP Devices
-- * Osmocom MiriSDR
-- * HackRF & rad1o Badge
-- * nuand bladeRF
-- * RFSPACE Receivers
-- * AIRSPY Receiver
-- * SoapySDR support
-- * Red Pitaya SDR
--
-- ######################################################
-- # Gnuradio disabled components
-- ######################################################
-- * Osmocom IQ Imbalance Correction
-- * AIRSPY HF+ Receiver
-- * FreeSRP support
--
-- Building for version: 0.2.0.0 / 0.2.0
-- Using install prefix: /usr
-- Configuring done
CMake Error at lib/CMakeLists.txt:43 (add_library):
Target "gnuradio-osmosdr" links to target "gnuradio::filter" but the target
was not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?
CMake Error at /usr/lib64/cmake/gnuradio/UseSWIG.cmake:573 (add_library):
Target "osmosdr_swig" links to target "gnuradio::filter" but the target was
not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?
Call Stack (most recent call first):
/usr/lib64/cmake/gnuradio/GrSwig.cmake:133 (swig_add_library)
swig/CMakeLists.txt:42 (GR_SWIG_MAKE)
CMake Error at lib/CMakeLists.txt:43 (add_library):
Target "gnuradio-osmosdr" links to target "gnuradio::filter" but the target
was not found. Perhaps a find_package() call is missing for an IMPORTED
target, or an ALIAS target is missing?
-- Generating done
CMake Generate step failed. Build files cannot be regenerated correctly.
```
Any feedback would be appreciated.
Thanks,
--
Tom Swartz
2
3
From: Clayton Smith <argilo(a)gmail.com>
---
lib/airspy/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/airspy/CMakeLists.txt b/lib/airspy/CMakeLists.txt
index 75770866db..4a601382c9 100644
--- a/lib/airspy/CMakeLists.txt
+++ b/lib/airspy/CMakeLists.txt
@@ -27,7 +27,7 @@ target_include_directories(gnuradio-osmosdr PRIVATE
)
target_link_libraries(gnuradio-osmosdr
- gnuradio::filter
+ gnuradio::gnuradio-filter
${Gnuradio-blocks_LIBRARIES}
${LIBAIRSPY_LIBRARIES}
)
--
2.17.1
1
0
I can not compile the block gr-osmosdr, obtained block of errors ,if you
can help me solve the problem ,please.Sincerely thebugslayers
The following are the errors
-- The CXX compiler identification is GNU 7.4.0
-- The C compiler identification is GNU 7.4.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Build type not specified: defaulting to release.
-- Found Git: /usr/bin/git (found version "2.17.1")
-- Extracting version information from git describe...
-- Configuring Boost C++ Libraries...
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Boost version: 1.65.1
-- Found the following Boost libraries:
-- thread
-- system
-- chrono
-- date_time
-- atomic
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1")
-- Checking for module 'gruel'
-- No package 'gruel' found
-- Could NOT find GRUEL (missing: GRUEL_LIBRARIES GRUEL_INCLUDE_DIRS)
-- Checking for module 'gnuradio-core'
-- No package 'gnuradio-core' found
-- Could NOT find GNURADIO_CORE (missing: GNURADIO_CORE_LIBRARIES
GNURADIO_CORE_INCLUDE_DIRS)
-- Checking for module 'gnuradio-iqbalance'
-- Found gnuradio-iqbalance, version 0
-- Could NOT find GNURADIO_IQBALANCE (missing:
GNURADIO_IQBALANCE_INCLUDE_DIRS)
-- Checking for module 'uhd'
-- No package 'uhd' found
-- Could NOT find UHD (missing: UHD_LIBRARIES UHD_INCLUDE_DIRS)
-- Checking for module 'gnuradio-uhd'
-- Found gnuradio-uhd, version 3.9.0
-- gnuradio-uhd not found.
-- Could NOT find GNURADIO_UHD (missing: GNURADIO_UHD_INCLUDE_DIRS)
-- Checking for module 'gnuradio-fcd'
-- No package 'gnuradio-fcd' found
-- gnuradio-fcd not found.
-- Could NOT find GNURADIO_FCD (missing: GNURADIO_FCD_LIBRARIES
GNURADIO_FCD_INCLUDE_DIRS)
-- Checking for module 'gnuradio-fcdproplus'
-- Found gnuradio-fcdproplus, version 3.7.11
-- Found gnuradio-fcdproplus: /usr/include,
/usr/lib/x86_64-linux-gnu/libgnuradio-fcdproplus.so
-- Found GNURADIO_FCDPP: /usr/lib/x86_64-linux-gnu/libgnuradio-fcdproplus.so
-- Checking for module 'libosmosdr'
-- No package 'libosmosdr' found
-- libosmosdr not found.
-- Checking for module 'librtlsdr'
-- No package 'librtlsdr' found
-- librtlsdr not found.
-- Checking for module 'libmirisdr'
-- No package 'libmirisdr' found
-- libmirisdr not found.
-- Checking for module 'libhackrf'
-- Found libhackrf, version 0.5
-- Found LIBHACKRF: /usr/local/lib/libhackrf.so
-- Checking for module 'libairspy'
-- No package 'libairspy' found
-- Could NOT find LIBAIRSPY (missing: LIBAIRSPY_LIBRARIES
LIBAIRSPY_INCLUDE_DIRS)
-- Checking for module 'libbladeRF'
-- No package 'libbladeRF' found
-- libbladeRF not found.
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
CMake Error at CMakeLists.txt:166 (message):
Gruel required to build gr-osmosdr
-- Configuring incomplete, errors occurred!
See also "/home/shan/gr-osmosdr/build/CMakeFiles/CMakeOutput.log".
See also "/home/shan/gr-osmosdr/build/CMakeFiles/CMakeError.log".
Thanks:)
2
2