introduce device discovery api

This API allows to acquire a list of devices connected to the host and
creates an argument string ready to be passed to a source object for
cunstruction.

Each device_t entry contains a "label" entry, which holds the generic
device name which may be shown to the user for device selection.

For certain radio hardware extended entries ("name", "serial", "type")
may be available to make bijective device addressing possible.

The argument string for target types "rtl_tcp" and "file" might be
constructed using the osmosdr::device_t class facilities.

Example:

 #include <osmosdr_device.h>
 #include <osmosdr_source_c.h>

osmosdr::devices_t devs = osmosdr::device::find();

BOOST_FOREACH(osmosdr::device_t &dev, devs) // try to create each dev
  osmosdr_source_c_sptr src = osmosdr_make_source_c(dev.to_string());
This commit is contained in:
Dimitri Stolnikov 2012-05-20 12:30:28 +02:00
parent e256bf332e
commit 3ea0b38810
14 changed files with 571 additions and 29 deletions

View File

@ -116,8 +116,8 @@ Examples (some arguments may be optional):
fcd=0 fcd=0
rtl=0,rtl_xtal=28.80001e6,tuner_xtal=26e6,buffers=64 ... rtl=0,rtl_xtal=28.80001e6,tuner_xtal=26e6,buffers=64 ...
rtl_tcp=127.0.0.1:1234,psize=16384 rtl_tcp=127.0.0.1:1234,psize=16384
uhd=0|name,mcr=52e6,nchan=2,subdev='\\\\'B:0 A:0'\\\\' ... uhd=,serial=...,type=usrp1,mcr=52e6,nchan=2,subdev='\\\\'B:0 A:0'\\\\' ...
osmosdr=0|name,mcr=64e6,nchan=5,port=/dev/ttyUSB0 ... osmosdr=0,mcr=64e6,nchan=5 ...
file=/path/to/file.ext,freq=428e6,rate=1e6,repeat=true,throttle=true ... file=/path/to/file.ext,freq=428e6,rate=1e6,repeat=true,throttle=true ...
Num Channels: Num Channels:

View File

@ -24,6 +24,7 @@ install(FILES
osmosdr_api.h osmosdr_api.h
osmosdr_pimpl.h osmosdr_pimpl.h
osmosdr_ranges.h osmosdr_ranges.h
osmosdr_device.h
osmosdr_source_c.h osmosdr_source_c.h
# osmosdr_sink_c.h # osmosdr_sink_c.h
DESTINATION include/osmosdr DESTINATION include/osmosdr

View File

@ -0,0 +1,112 @@
/* -*- 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_DEVICE_H
#define INCLUDED_OSMOSDR_DEVICE_H
#include <osmosdr_api.h>
#include <osmosdr_pimpl.h>
#include <boost/noncopyable.hpp>
#include <boost/lexical_cast.hpp>
#include <stdexcept>
#include <string>
#include <vector>
#include <map>
typedef std::map<std::string, std::string> string_string_dict_t;
namespace osmosdr {
/*!
* Mapping of key/value pairs for locating devices on the system.
* When left empty, the device discovery routines will search
* all available transports on the system (ethernet, usb...).
*
* The logical device can also be used to pass arguments into
* the transport layer control to set (for example) buffer sizes.
*
* An arguments string, is a way to represent a device address
* using a single string with delimiter characters.
*/
class OSMOSDR_API device_t : public string_string_dict_t
{
public:
/*!
* Create a logical device from an args string.
* \param args the arguments string
*/
device_t(const std::string &args = "");
/*!
* Convert a logical device into a pretty print string.
* \return a printable string representing the device
*/
std::string to_pp_string(void) const;
/*!
* Convert the logical device into an args string.
* The args string contains delimiter symbols.
* \return a string with delimiter markup
*/
std::string to_string(void) const;
/*!
* Lexically cast a parameter to the specified type,
* or use the default value if the key is not found.
* \param key the key as one of the parameters
* \param def the value to use when key is not present
* \return the casted value as type T or the default
* \throw error when the parameter cannot be casted
*/
template <typename T> T cast(const std::string &key, const T &def) const
{
if (!this->count(key)) return def;
try { return boost::lexical_cast<T>((*this)[key]); }
catch(const boost::bad_lexical_cast &) {
throw std::runtime_error("cannot cast " + key + " = " + (*this)[key]);
}
}
};
//! A typedef for a vector of logical devices
typedef std::vector<device_t> devices_t;
/*!
* The device interface represents the underyling hardware.
* The api allows for discovery, configuration, and streaming.
*/
class OSMOSDR_API device : boost::noncopyable
{
public:
/*!
* \brief Find logical radio devices attached to the host.
*
* The device hint should be used to narrow down the search
* to particular transport types and/or transport arguments.
*
* \param hint a partially (or fully) filled in logical device
* \return a vector of logical devices for all radios on the system
*/
static devices_t find(const device_t &hint = osmosdr::device_t());
};
} //namespace osmosdr
#endif /* INCLUDED_OSMOSDR_DEVICE_H */

View File

@ -38,6 +38,7 @@ GR_OSMOSDR_APPEND_SRCS(
osmosdr_source_c_impl.cc osmosdr_source_c_impl.cc
osmosdr_sink_c_impl.cc osmosdr_sink_c_impl.cc
osmosdr_ranges.cc osmosdr_ranges.cc
osmosdr_device.cc
) )
GR_OSMOSDR_APPEND_LIBS( GR_OSMOSDR_APPEND_LIBS(

View File

@ -38,6 +38,11 @@ fcd_source_sptr make_fcd_source(const std::string &args)
return gnuradio::get_initial_sptr(new fcd_source(args)); return gnuradio::get_initial_sptr(new fcd_source(args));
} }
/*
2 [V10 ]: USB-Audio - FUNcube Dongle V1.0
Hanlincrest Ltd. FUNcube Dongle V1.0 at usb-0000:00:1d.0-2, full speed
*/
static std::vector< std::string > _get_devices() static std::vector< std::string > _get_devices()
{ {
std::vector< std::string > devices; std::vector< std::string > devices;
@ -102,8 +107,11 @@ std::vector< std::string > fcd_source::get_devices()
int id = 0; int id = 0;
std::vector< std::string > devices; std::vector< std::string > devices;
BOOST_FOREACH( std::string dev, _get_devices() ) BOOST_FOREACH( std::string dev, _get_devices() ) {
devices.push_back( "fcd=" + boost::lexical_cast< std::string >( id++ ) ); std::string args = "fcd=" + boost::lexical_cast< std::string >( id++ );
args += ",label='FunCube Dongle'";
devices.push_back( args );
}
return devices; return devices;
} }

View File

@ -45,7 +45,7 @@ osmosdr_control::~osmosdr_control()
/* /*
1 [OsmoSDR ]: USB-Audio - OsmoSDR 1 [OsmoSDR ]: USB-Audio - OsmoSDR
sysmocom OsmoSDR at usb-0000:00:06.1-2, high speed sysmocom OsmoSDR at usb-0000:00:06.1-2, high speed
*/ */
std::vector< std::string > osmosdr_control::find_devices() std::vector< std::string > osmosdr_control::find_devices()
{ {
std::vector< std::string > devices; std::vector< std::string > devices;

View File

@ -31,8 +31,12 @@
#include <gr_audio_source.h> #include <gr_audio_source.h>
#include <gr_float_to_complex.h> #include <gr_float_to_complex.h>
#include <boost/assign.hpp>
#include <osmosdr_arg_helpers.h> #include <osmosdr_arg_helpers.h>
using namespace boost::assign;
/* /*
* Create a new instance of osmosdr_src_c and return * Create a new instance of osmosdr_src_c and return
* a boost shared_ptr. This is effectively the public constructor. * a boost shared_ptr. This is effectively the public constructor.
@ -52,8 +56,30 @@ osmosdr_src_c::osmosdr_src_c (const std::string &args)
args_to_io_signature(args)), args_to_io_signature(args)),
osmosdr_rx_control(args) osmosdr_rx_control(args)
{ {
std::string dev_name;
unsigned int dev_index = 0, mcr = 0;
size_t nchan = 1;
dict_t dict = params_to_dict(args);
if (dict.count("osmosdr"))
dev_index = boost::lexical_cast< unsigned int >( dict["osmosdr"] );
if (dict.count("mcr"))
mcr = (unsigned int) boost::lexical_cast< double >( dict["mcr"] );
if (dict.count("nchan"))
nchan = boost::lexical_cast< size_t >( dict["nchan"] );
std::vector< std::string > devices = osmosdr_control::find_devices();
if ( devices.size() )
dev_name = devices[dev_index];
else
throw std::runtime_error("No OsmoSDR devices found.");
/* Audio source; sample rate is 500kHz by default */ /* Audio source; sample rate is 500kHz by default */
audio_source::sptr src = audio_make_source(500000, audio_dev_name(), true); audio_source::sptr src = audio_make_source(500000, dev_name, true);
/* block to convert stereo audio to a complex stream */ /* block to convert stereo audio to a complex stream */
gr_float_to_complex_sptr f2c = gr_make_float_to_complex(1); gr_float_to_complex_sptr f2c = gr_make_float_to_complex(1);
@ -61,6 +87,8 @@ osmosdr_src_c::osmosdr_src_c (const std::string &args)
connect(src, 0, f2c, 0); /* Left is I */ connect(src, 0, f2c, 0); /* Left is I */
connect(src, 1, f2c, 1); /* Right is Q */ connect(src, 1, f2c, 1); /* Right is Q */
connect(f2c, 0, self(), 0); connect(f2c, 0, self(), 0);
_auto_gain = false;
} }
/* /*
@ -70,3 +98,224 @@ osmosdr_src_c::~osmosdr_src_c ()
{ {
// nothing else required in this example // nothing else required in this example
} }
std::vector<std::string> osmosdr_src_c::get_devices()
{
int id = 0;
std::vector< std::string > devices;
BOOST_FOREACH( std::string dev, osmosdr_control::find_devices() ) {
std::string args = "osmosdr=" + boost::lexical_cast< std::string >( id++ );
args += ",label='sysmocom OsmoSDR'";
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;
range += osmosdr::range_t( 1024000 ); // known to work
range += osmosdr::range_t( 1800000 ); // known to work
range += osmosdr::range_t( 2048000 ); // known to work
range += osmosdr::range_t( 2400000 ); // may work
range += osmosdr::range_t( 2600000 ); // may work
range += osmosdr::range_t( 2800000 ); // may work
range += osmosdr::range_t( 3000000 ); // may work
range += osmosdr::range_t( 3200000 ); // max rate, may work
// TODO: read from the libosmosdr as soon as the api is available
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;
range += osmosdr::range_t( 50e6, 2.2e9, 100 );
// TODO: read from the libosmosdr as soon as the api is available
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 )
{
// if ( _dev )
// osmosdr_set_freq_correction( _dev, (int)ppm );
return get_freq_corr( chan );
}
double osmosdr_src_c::get_freq_corr( size_t chan )
{
// if ( _dev )
// return (double)osmosdr_get_freq_correction( _dev );
return 0;
}
std::vector<std::string> osmosdr_src_c::get_gain_names( size_t chan )
{
std::vector< std::string > antennas;
antennas += "LNA";
return antennas;
}
osmosdr::gain_range_t osmosdr_src_c::get_gain_range( size_t chan )
{
osmosdr::gain_range_t range;
range += osmosdr::range_t( -1.0 );
range += osmosdr::range_t( 1.5 );
range += osmosdr::range_t( 4.0 );
range += osmosdr::range_t( 6.5 );
range += osmosdr::range_t( 9.0 );
range += osmosdr::range_t( 11.5 );
range += osmosdr::range_t( 14.0 );
range += osmosdr::range_t( 16.5 );
range += osmosdr::range_t( 19.0 );
range += osmosdr::range_t( 21.5 );
range += osmosdr::range_t( 24.0 );
range += osmosdr::range_t( 29.0 );
range += osmosdr::range_t( 34.0 );
range += osmosdr::range_t( 42.0 );
range += osmosdr::range_t( 43.0 );
range += osmosdr::range_t( 45.0 );
range += osmosdr::range_t( 47.0 );
range += osmosdr::range_t( 49.0 );
// TODO: read from the libosmosdr as soon as the api is available
return range;
}
osmosdr::gain_range_t osmosdr_src_c::get_gain_range( const std::string & name, size_t chan )
{
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;
}
static double pick_closest_gain(osmosdr::gain_range_t &gains, double required)
{
double result = required;
double distance = 100;
BOOST_FOREACH(osmosdr::range_t gain, gains)
{
double diff = fabs(gain.start() - required);
if (diff < distance) {
distance = diff;
result = gain.start();
}
}
return result;
}
double osmosdr_src_c::set_gain( double gain, size_t chan )
{
osmosdr::gain_range_t gains = osmosdr_src_c::get_gain_range( chan );
double picked_gain = pick_closest_gain( gains, gain );
// if (_dev)
// osmosdr_set_tuner_gain( _dev, int(picked_gain * 10.0) );
return get_gain( chan );
}
double osmosdr_src_c::set_gain( double gain, const std::string & name, size_t 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 )
{
return get_gain( chan );
}
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 "ANT";
}

View File

@ -24,6 +24,8 @@
#include <osmosdr_control.h> #include <osmosdr_control.h>
#include <gr_hier_block2.h> #include <gr_hier_block2.h>
#include "osmosdr_src_iface.h"
class osmosdr_src_c; class osmosdr_src_c;
/* /*
@ -56,7 +58,8 @@ OSMOSDR_API osmosdr_src_c_sptr osmosdr_make_src_c (const std::string & args = ""
*/ */
class OSMOSDR_API osmosdr_src_c : class OSMOSDR_API osmosdr_src_c :
public gr_hier_block2, public gr_hier_block2,
public osmosdr_rx_control public osmosdr_rx_control,
public osmosdr_src_iface
{ {
private: private:
// The friend declaration allows osmosdr_make_src_c to // The friend declaration allows osmosdr_make_src_c to
@ -72,6 +75,36 @@ private:
public: public:
~osmosdr_src_c (); // public destructor ~osmosdr_src_c (); // public destructor
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 );
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:
bool _auto_gain;
}; };
#endif /* INCLUDED_OSMOSDR_SRC_C_H */ #endif /* INCLUDED_OSMOSDR_SRC_C_H */

View File

@ -32,7 +32,7 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
typedef std::map< std::string, std::string > dict_t; typedef std::map< std::string, std::string > dict_t;
typedef std::pair<std::string, std::string> pair_t; typedef std::pair< std::string, std::string > pair_t;
inline std::vector< std::string > args_to_vector( const std::string &args ) inline std::vector< std::string > args_to_vector( const std::string &args )
{ {
@ -88,11 +88,11 @@ inline dict_t params_to_dict( const std::string &params )
std::vector< std::string > param_list = params_to_vector( params ); std::vector< std::string > param_list = params_to_vector( params );
BOOST_FOREACH(std::string param, param_list) BOOST_FOREACH(std::string param, param_list)
{ {
pair_t nchan = param_to_pair( param ); pair_t pair = param_to_pair( param );
std::string value = nchan.second; std::string value = pair.second;
if (value.length() && value[0] == '\'' && value[ value.length() - 1 ] == '\'') if (value.length() && value[0] == '\'' && value[ value.length() - 1 ] == '\'')
value = value.substr(1, value.length() - 1); value = value.substr(1, value.length() - 1);
result[ nchan.first ] = nchan.second; result[ pair.first ] = value;
} }
return result; return result;

120
lib/osmosdr_device.cc Normal file
View File

@ -0,0 +1,120 @@
/* -*- 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.
*/
#include <osmosdr_device.h>
#include <stdexcept>
#include <boost/foreach.hpp>
#include <boost/thread/mutex.hpp>
#include <algorithm>
#include <sstream>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*
#define ENABLE_OSMOSDR
#define ENABLE_FCD
#define ENABLE_RTL
#define ENABLE_UHD
*/
#ifdef ENABLE_OSMOSDR
#include <osmosdr_src_c.h>
#endif
#ifdef ENABLE_FCD
#include <fcd_source.h>
#endif
#ifdef ENABLE_RTL
#include <rtl_source_c.h>
#endif
#ifdef ENABLE_UHD
#include <uhd_source_c.h>
#endif
#include "osmosdr_arg_helpers.h"
using namespace osmosdr;
static const std::string args_delim = " ";
static const std::string pairs_delim = ",";
static const std::string pair_delim = "=";
static boost::mutex _device_mutex;
device_t::device_t(const std::string &args)
{
dict_t dict = params_to_dict(args);
BOOST_FOREACH( dict_t::value_type &entry, dict )
(*this)[entry.first] = entry.second;
}
std::string device_t::to_pp_string(void) const
{
if (this->size() == 0) return "Empty Device Address";
std::stringstream ss;
ss << "Device Address:" << std::endl;
BOOST_FOREACH(const device_t::value_type &entry, *this) {
ss << boost::format(" %s: %s") % entry.first % entry.second << std::endl;
}
return ss.str();
}
std::string device_t::to_string(void) const
{
std::stringstream ss;
size_t count = 0;
BOOST_FOREACH(const device_t::value_type &entry, *this) {
std::string value = entry.second;
if (value.find(" ") != std::string::npos)
value = "'" + value + "'";
ss << ((count++) ? pairs_delim : "") + entry.first + pair_delim + value;
}
return ss.str();
}
devices_t device::find(const device_t &hint)
{
boost::mutex::scoped_lock lock(_device_mutex);
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
BOOST_FOREACH( std::string dev, fcd_source::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_RTL
BOOST_FOREACH( std::string dev, rtl_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_UHD
BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
return devices;
}

View File

@ -96,7 +96,8 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args)
std::vector< std::string > dev_list; std::vector< std::string > dev_list;
#ifdef ENABLE_OSMOSDR #ifdef ENABLE_OSMOSDR
// TODO: implement BOOST_FOREACH( std::string dev, osmosdr_src_c::get_devices() )
dev_list.push_back( dev );
#endif #endif
#ifdef ENABLE_FCD #ifdef ENABLE_FCD
BOOST_FOREACH( std::string dev, fcd_source::get_devices() ) BOOST_FOREACH( std::string dev, fcd_source::get_devices() )
@ -133,10 +134,10 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args)
if ( dict.count("osmosdr") ) { if ( dict.count("osmosdr") ) {
osmosdr_src_c_sptr src = osmosdr_make_src_c( arg ); osmosdr_src_c_sptr src = osmosdr_make_src_c( arg );
// for (size_t i = 0; i < src->get_num_channels(); i++) for (size_t i = 0; i < src->get_num_channels(); i++)
// connect(src, i, self(), channel++); connect(src, i, self(), channel++);
// _devs.push_back( src.get() ); // FIXME: implement interface _devs.push_back( src.get() );
} }
#endif #endif

View File

@ -125,8 +125,8 @@ rtl_source_c::rtl_source_c (const std::string &args)
if ( dev_index >= rtlsdr_get_device_count() ) if ( dev_index >= rtlsdr_get_device_count() )
throw std::runtime_error("Wrong rtlsdr device index given."); throw std::runtime_error("Wrong rtlsdr device index given.");
std::cerr << "Using device #" << dev_index << " " std::cerr << "Using device #" << dev_index << ": "
<< "(" << rtlsdr_get_device_name(dev_index) << ")" << rtlsdr_get_device_name(dev_index)
<< std::endl; << std::endl;
_dev = NULL; _dev = NULL;
@ -173,8 +173,9 @@ rtl_source_c::rtl_source_c (const std::string &args)
rtl_source_c::~rtl_source_c () rtl_source_c::~rtl_source_c ()
{ {
if (_dev) { if (_dev) {
_running = false;
rtlsdr_cancel_async( _dev ); rtlsdr_cancel_async( _dev );
_thread.join(); _thread.timed_join( boost::posix_time::milliseconds(200) );
rtlsdr_close( _dev ); rtlsdr_close( _dev );
_dev = NULL; _dev = NULL;
} }
@ -294,12 +295,15 @@ int rtl_source_c::work( int noutput_items,
std::vector<std::string> rtl_source_c::get_devices() std::vector<std::string> rtl_source_c::get_devices()
{ {
std::vector<std::string> result; std::vector<std::string> devices;
for (unsigned int i = 0; i < rtlsdr_get_device_count(); i++) for (unsigned int i = 0; i < rtlsdr_get_device_count(); i++) {
result.push_back( "rtl=" + boost::lexical_cast< std::string >( i ) ); std::string args = "rtl=" + boost::lexical_cast< std::string >( i );
args += ",label='" + std::string(rtlsdr_get_device_name( i )) + "'";
devices.push_back( args );
}
return result; return devices;
} }
size_t rtl_source_c::get_num_channels() size_t rtl_source_c::get_num_channels()

View File

@ -41,13 +41,16 @@ uhd_source_c::uhd_source_c(const std::string &args) :
gr_make_io_signature (0, 0, 0), gr_make_io_signature (0, 0, 0),
args_to_io_signature(args)) args_to_io_signature(args))
{ {
size_t num_channels = 1; size_t nchan = 1;
std::string arguments = args; std::string arguments = args;
dict_t dict = params_to_dict(args); dict_t dict = params_to_dict(args);
if (dict.count("nchan")) if (dict.count("nchan"))
num_channels = boost::lexical_cast< unsigned int >( dict["nchan"] ); nchan = boost::lexical_cast< size_t >( dict["nchan"] );
if (0 == nchan)
nchan = 1;
arguments.clear(); // rebuild argument string without uhd= prefix arguments.clear(); // rebuild argument string without uhd= prefix
BOOST_FOREACH( dict_t::value_type &entry, dict ) { BOOST_FOREACH( dict_t::value_type &entry, dict ) {
@ -59,12 +62,12 @@ uhd_source_c::uhd_source_c(const std::string &args) :
_src = uhd_make_usrp_source( arguments, _src = uhd_make_usrp_source( arguments,
uhd::io_type_t::COMPLEX_FLOAT32, uhd::io_type_t::COMPLEX_FLOAT32,
num_channels ); nchan );
if (dict.count("subdev")) if (dict.count("subdev"))
_src->set_subdev_spec( dict["subdev"] ); _src->set_subdev_spec( dict["subdev"] );
for ( size_t i = 0; i < num_channels; i++ ) for ( size_t i = 0; i < nchan; i++ )
connect( _src, i, self(), i ); connect( _src, i, self(), i );
} }
@ -77,8 +80,14 @@ std::vector< std::string > uhd_source_c::get_devices()
std::vector< std::string > devices; std::vector< std::string > devices;
uhd::device_addr_t hint; uhd::device_addr_t hint;
BOOST_FOREACH(uhd::device_addr_t device, uhd::device::find(hint)) BOOST_FOREACH(const uhd::device_addr_t &dev, uhd::device::find(hint)) {
devices += "uhd=" + device.to_string(); std::string args = "uhd=," + dev.to_string();
args += ",label='Ettus USRP'";
devices.push_back( args );
}
//devices.clear();
//devices.push_back( "uhd=,type=usrp1,label='Ettus USRP'" );
return devices; return devices;
} }
@ -94,7 +103,7 @@ std::string uhd_source_c::name()
// std::string dev_name = prop_tree->access<std::string>("/name").get(); // std::string dev_name = prop_tree->access<std::string>("/name").get();
std::string mboard_name = _src->get_device()->get_mboard_name(); std::string mboard_name = _src->get_device()->get_mboard_name();
// std::cout << "'" << dev_name << "' '" << mboard_name << "'" << std::endl; // std::cerr << "'" << dev_name << "' '" << mboard_name << "'" << std::endl;
// 'USRP1 Device' 'USRP1 (Classic)' // 'USRP1 Device' 'USRP1 (Classic)'
// 'B-Series Device' 'B100 (B-Hundo)' // 'B-Series Device' 'B100 (B-Hundo)'

View File

@ -2,12 +2,16 @@
#define OSMOSDR_API #define OSMOSDR_API
// suppress Warning 319: No access specifier given for base class 'boost::noncopyable' (ignored).
#pragma SWIG nowarn=319
%include "gnuradio.i" // the common stuff %include "gnuradio.i" // the common stuff
//load generated python docstrings //load generated python docstrings
%include "osmosdr_swig_doc.i" %include "osmosdr_swig_doc.i"
%{ %{
#include "osmosdr_device.h"
#include "osmosdr_source_c.h" #include "osmosdr_source_c.h"
//#include "osmosdr_sink_c.h" //#include "osmosdr_sink_c.h"
%} %}