aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/include/uhd/gain_handler.hpp68
-rw-r--r--host/include/uhd/utils.hpp7
-rw-r--r--host/lib/device.cpp15
-rw-r--r--host/lib/gain_handler.cpp264
-rw-r--r--host/lib/usrp/dboard/basic.cpp4
-rw-r--r--host/lib/usrp/dboard_manager.cpp83
-rw-r--r--host/lib/wax.cpp10
-rw-r--r--host/test/gain_handler_test.cpp18
8 files changed, 271 insertions, 198 deletions
diff --git a/host/include/uhd/gain_handler.hpp b/host/include/uhd/gain_handler.hpp
index 06800315a..fade86f53 100644
--- a/host/include/uhd/gain_handler.hpp
+++ b/host/include/uhd/gain_handler.hpp
@@ -15,11 +15,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-#include <boost/shared_ptr.hpp>
#include <uhd/wax.hpp>
-#include <uhd/props.hpp>
+#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
-#include <boost/bind.hpp>
#ifndef INCLUDED_UHD_GAIN_HANDLER_HPP
#define INCLUDED_UHD_GAIN_HANDLER_HPP
@@ -29,29 +27,41 @@ namespace uhd{
class gain_handler{
public:
typedef boost::shared_ptr<gain_handler> sptr;
+ typedef boost::function<bool(const wax::obj &, const wax::obj &)> is_equal_t;
- template <class T> gain_handler(
- wax::obj *wax_obj_ptr, const T &gain_prop,
- const T &gain_min_prop, const T &gain_max_prop,
- const T &gain_step_prop, const T &gain_names_prop
- ){
- _wax_obj_ptr = wax_obj_ptr;
- _gain_prop = gain_prop;
- _gain_min_prop = gain_min_prop;
- _gain_max_prop = gain_max_prop;
- _gain_step_prop = gain_step_prop;
- _gain_names_prop = gain_names_prop;
- _is_equal = boost::bind(&gain_handler::is_equal<T>, _1, _2);
- }
+ /*!
+ * A set of properties for dealing with gains.
+ */
+ struct gain_props_t{
+ wax::obj gain_val_prop;
+ wax::obj gain_min_prop;
+ wax::obj gain_max_prop;
+ wax::obj gain_step_prop;
+ wax::obj gain_names_prop;
+ gain_props_t(void); //default constructor
+ };
- ~gain_handler(void);
+ /*!
+ * Make a new gain handler.
+ * The construction arguments are agnostic to the property type.
+ * It is up to the caller to provide an "is_equal" function that
+ * can tell weather two properties (in a wax obj) are equal.
+ * \param link a link to the wax obj with properties
+ * \param gain_props a struct of properties keys
+ * \param is_equal the function that tests for equal properties
+ */
+ static sptr make(
+ const wax::obj &link,
+ const gain_props_t &gain_props,
+ is_equal_t is_equal
+ );
/*!
* Intercept gets for overall gain, min, max, step.
* Ensures that the gain name is valid.
* \return true for handled, false to pass on
*/
- bool intercept_get(const wax::obj &key, wax::obj &val);
+ virtual bool intercept_get(const wax::obj &key, wax::obj &val) = 0;
/*!
* Intercept sets for overall gain.
@@ -59,27 +69,10 @@ public:
* Ensures that the new gain is within range.
* \return true for handled, false to pass on
*/
- bool intercept_set(const wax::obj &key, const wax::obj &val);
-
-private:
-
- wax::obj *_wax_obj_ptr;
- wax::obj _gain_prop;
- wax::obj _gain_min_prop;
- wax::obj _gain_max_prop;
- wax::obj _gain_step_prop;
- wax::obj _gain_names_prop;
+ virtual bool intercept_set(const wax::obj &key, const wax::obj &val) = 0;
/*!
- * Verify that the key is valid:
- * If its a named prop for gain, ensure that name is valid.
- * If the name if not valid, throw a std::invalid_argument.
- * The name can only be valid if its in the list of gain names.
- */
- void _check_key(const wax::obj &key);
-
- /*
- * Private interface to test if two wax types are equal:
+ * Function template to test if two wax types are equal:
* The constructor will bind an instance of this for a specific type.
* This bound equals functions allows the intercept methods to be non-templated.
*/
@@ -91,7 +84,6 @@ private:
return false;
}
}
- boost::function<bool(const wax::obj &, const wax::obj &)> _is_equal;
};
diff --git a/host/include/uhd/utils.hpp b/host/include/uhd/utils.hpp
index e4cfd098b..5d6a18b3a 100644
--- a/host/include/uhd/utils.hpp
+++ b/host/include/uhd/utils.hpp
@@ -26,7 +26,7 @@
/*!
* Defines a static code block that will be called before main()
*/
-#define STATIC_BLOCK(_name, _code) struct _name{_name(void){_code}} _name
+#define STATIC_BLOCK(_x) struct _x{_x();}_x;_x::_x()
/*!
* Useful templated functions and classes that I like to pretend are part of stl
@@ -55,6 +55,11 @@ namespace std{
return tmp;
}
+ template<class T, class Iterable, class Function>
+ T reduce(Iterable iterable, Function fcn, T init = 0){
+ return reduce(iterable.begin(), iterable.end(), fcn, init);
+ }
+
template<class T, class InputIterator>
bool has(InputIterator first, InputIterator last, const T &elem){
return last != std::find(first, last, elem);
diff --git a/host/lib/device.cpp b/host/lib/device.cpp
index 82052708a..4b64e4a15 100644
--- a/host/lib/device.cpp
+++ b/host/lib/device.cpp
@@ -32,9 +32,16 @@ using namespace uhd;
* Create a new device from a device address.
* Based on the address, call the appropriate make functions.
* \param dev_addr the device address
+ * \param hint the device address that was used to find the device
* \return a smart pointer to a device
*/
-static device::sptr make_device(const device_addr_t &dev_addr){
+static device::sptr make_device(const device_addr_t &dev_addr_, const device_addr_t &hint){
+ //copy keys that were in hint but not in dev_addr
+ //this way, we can pass additional transport arguments
+ device_addr_t dev_addr = dev_addr_;
+ BOOST_FOREACH(std::string key, hint.get_keys()){
+ if (not dev_addr.has_key(key)) dev_addr[key] = hint[key];
+ }
//create a usrp1e
if (dev_addr["type"] == "usrp1e"){
@@ -46,7 +53,9 @@ static device::sptr make_device(const device_addr_t &dev_addr){
return usrp::usrp2::make(dev_addr);
}
- throw std::runtime_error("cant make a device");
+ throw std::runtime_error(str(
+ boost::format("Cant make a device for %s") % device_addr::to_string(dev_addr)
+ ));
}
/*!
@@ -126,7 +135,7 @@ device::sptr device::make(const device_addr_t &hint, size_t which){
}
//create and register a new device
catch(const std::assert_error &e){
- device::sptr dev = make_device(dev_addr);
+ device::sptr dev = make_device(dev_addr, hint);
hash_to_device[dev_hash] = dev;
return dev;
}
diff --git a/host/lib/gain_handler.cpp b/host/lib/gain_handler.cpp
index b03d5bda2..8f840ae7f 100644
--- a/host/lib/gain_handler.cpp
+++ b/host/lib/gain_handler.cpp
@@ -17,6 +17,7 @@
#include <uhd/gain_handler.hpp>
#include <uhd/utils.hpp>
+#include <uhd/props.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
@@ -25,143 +26,178 @@
using namespace uhd;
/***********************************************************************
- * Helper functions and macros
+ * helper functions
**********************************************************************/
-#define GET_PROP_NAMES() \
- wax::cast<prop_names_t>((*_wax_obj_ptr)[_gain_names_prop])
-
-/*!
- * Helper function to simplify getting a named gain (also min, max, step).
- */
-static gain_t get_named_gain(wax::obj *wax_obj_ptr, wax::obj prop, std::string name){
- return wax::cast<gain_t>((*wax_obj_ptr)[named_prop_t(prop, name)]);
+static gain_t gain_max(gain_t a, gain_t b){
+ return std::max(a, b);
+}
+static gain_t gain_sum(gain_t a, gain_t b){
+ return std::sum(a, b);
+}
+
+/***********************************************************************
+ * gain handler implementation interface
+ **********************************************************************/
+class gain_handler_impl : public gain_handler{
+public:
+ gain_handler_impl(
+ const wax::obj &link,
+ const gain_props_t &gain_props,
+ is_equal_t is_equal
+ );
+ ~gain_handler_impl(void);
+ bool intercept_get(const wax::obj &key, wax::obj &val);
+ bool intercept_set(const wax::obj &key, const wax::obj &val);
+
+private:
+ wax::obj _link;
+ gain_props_t _gain_props;
+ is_equal_t _is_equal;
+
+ prop_names_t get_gain_names(void);
+ std::vector<gain_t> get_gains(const wax::obj &prop_key);
+ gain_t get_overall_gain_val(void);
+ gain_t get_overall_gain_min(void);
+ gain_t get_overall_gain_max(void);
+ gain_t get_overall_gain_step(void);
+};
+
+/***********************************************************************
+ * the make function
+ **********************************************************************/
+gain_handler::sptr gain_handler::make(
+ const wax::obj &link,
+ const gain_props_t &gain_props,
+ is_equal_t is_equal
+){
+ return sptr(new gain_handler_impl(link, gain_props, is_equal));
}
/***********************************************************************
- * Class methods of gain handler
+ * gain handler implementation methods
**********************************************************************/
-gain_handler::~gain_handler(void){
+gain_handler::gain_props_t::gain_props_t(void){
/* NOP */
}
-void gain_handler::_check_key(const wax::obj &key_){
- wax::obj key; std::string name;
- boost::tie(key, name) = extract_named_prop(key_);
-
- try{
- //only handle non wildcard names
- ASSERT_THROW(name != "");
-
- //only handle these gain props
- ASSERT_THROW(
- _is_equal(key, _gain_prop) or
- _is_equal(key, _gain_min_prop) or
- _is_equal(key, _gain_max_prop) or
- _is_equal(key, _gain_step_prop)
- );
-
- //check that the name is allowed
- prop_names_t prop_names = GET_PROP_NAMES();
- ASSERT_THROW(not std::has(prop_names.begin(), prop_names.end(), name));
-
- //if we get here, throw an exception
- throw std::invalid_argument(str(
- boost::format("Unknown gain name %s") % name
- ));
- }
- catch(const std::assert_error &){}
+gain_handler_impl::gain_handler_impl(
+ const wax::obj &link,
+ const gain_props_t &gain_props,
+ is_equal_t is_equal
+){
+ _link = link;
+ _gain_props = gain_props;
+ _is_equal = is_equal;
}
-static gain_t gain_max(gain_t a, gain_t b){
- return std::max(a, b);
+gain_handler_impl::~gain_handler_impl(void){
+ /* NOP */
}
-static gain_t gain_sum(gain_t a, gain_t b){
- return std::sum(a, b);
+
+prop_names_t gain_handler_impl::get_gain_names(void){
+ return wax::cast<prop_names_t>(_link[_gain_props.gain_names_prop]);
}
-bool gain_handler::intercept_get(const wax::obj &key, wax::obj &val){
- _check_key(key); //verify the key
-
- std::vector<wax::obj> gain_props = boost::assign::list_of
- (_gain_prop)(_gain_min_prop)(_gain_max_prop)(_gain_step_prop);
-
- /*!
- * Handle getting overall gains when a name is not specified.
- * For the gain props below, set the overall value and return true.
- */
- BOOST_FOREACH(wax::obj prop_key, gain_props){
- if (_is_equal(key, prop_key)){
- //form the gains vector from the props vector
- prop_names_t prop_names = GET_PROP_NAMES();
- std::vector<gain_t> gains(prop_names.size());
- std::transform(
- prop_names.begin(), prop_names.end(), gains.begin(),
- boost::bind(get_named_gain, _wax_obj_ptr, key, _1)
- );
-
- //reduce across the gain vector
- if (_is_equal(key, _gain_step_prop)){
- val = std::reduce<gain_t>(gains.begin(), gains.end(), gain_max);
- }
- else{
- val = std::reduce<gain_t>(gains.begin(), gains.end(), gain_sum);
- }
- return true;
- }
+std::vector<gain_t> gain_handler_impl::get_gains(const wax::obj &prop_key){
+ std::vector<gain_t> gains;
+ BOOST_FOREACH(std::string name, get_gain_names()){
+ gains.push_back(wax::cast<gain_t>(_link[named_prop_t(prop_key, name)]));
}
+ return gains;
+}
+
+gain_t gain_handler_impl::get_overall_gain_val(void){
+ return std::reduce<gain_t>(get_gains(_gain_props.gain_val_prop), gain_sum);
+}
- return false;
+gain_t gain_handler_impl::get_overall_gain_min(void){
+ return std::reduce<gain_t>(get_gains(_gain_props.gain_min_prop), gain_sum);
}
-bool gain_handler::intercept_set(const wax::obj &key_, const wax::obj &val){
- _check_key(key_); //verify the key
+gain_t gain_handler_impl::get_overall_gain_max(void){
+ return std::reduce<gain_t>(get_gains(_gain_props.gain_max_prop), gain_sum);
+}
+
+gain_t gain_handler_impl::get_overall_gain_step(void){
+ return std::reduce<gain_t>(get_gains(_gain_props.gain_step_prop), gain_max);
+}
+/***********************************************************************
+ * gain handler implementation get method
+ **********************************************************************/
+bool gain_handler_impl::intercept_get(const wax::obj &key_, wax::obj &val){
wax::obj key; std::string name;
boost::tie(key, name) = extract_named_prop(key_);
- /*!
- * Verify that a named gain component is in range.
- */
- try{
- //only handle the gain props
- ASSERT_THROW(_is_equal(key, _gain_prop));
-
- //check that the gain is in range
- gain_t gain = wax::cast<gain_t>(val);
- gain_t gain_min = get_named_gain(_wax_obj_ptr, _gain_min_prop, name);
- gain_t gain_max = get_named_gain(_wax_obj_ptr, _gain_max_prop, name);
- ASSERT_THROW(gain > gain_max or gain < gain_min);
-
- //if we get here, throw an exception
- throw std::range_error(str(
- boost::format("gain %s is out of range of (%f, %f)") % name % gain_min % gain_max
- ));
+ //not a wildcard... dont handle (but check name)
+ if (name != ""){
+ assert_has(get_gain_names(), name, "gain name");
+ return false;
+ }
+
+ if (_is_equal(key, _gain_props.gain_val_prop)){
+ val = get_overall_gain_val();
+ return true;
+ }
+
+ if (_is_equal(key, _gain_props.gain_min_prop)){
+ val = get_overall_gain_min();
+ return true;
}
- catch(const std::assert_error &){}
-
- /*!
- * Handle setting the overall gain.
- */
- if (_is_equal(key, _gain_prop) and name == ""){
- gain_t gain = wax::cast<gain_t>(val);
- prop_names_t prop_names = GET_PROP_NAMES();
- BOOST_FOREACH(std::string name, prop_names){
- //get the min, max, step for this gain name
- gain_t gain_min = get_named_gain(_wax_obj_ptr, _gain_min_prop, name);
- gain_t gain_max = get_named_gain(_wax_obj_ptr, _gain_max_prop, name);
- gain_t gain_step = get_named_gain(_wax_obj_ptr, _gain_step_prop, name);
-
- //clip g to be within the allowed range
- gain_t g = std::min(std::max(gain, gain_min), gain_max);
- //set g to be a multiple of the step size
- g -= fmod(g, gain_step);
- //set g to be the new gain
- (*_wax_obj_ptr)[named_prop_t(_gain_prop, name)] = g;
- //subtract g out of the total gain left to apply
- gain -= g;
- }
+
+ if (_is_equal(key, _gain_props.gain_max_prop)){
+ val = get_overall_gain_max();
return true;
}
- return false;
+ if (_is_equal(key, _gain_props.gain_step_prop)){
+ val = get_overall_gain_step();
+ return true;
+ }
+
+ return false; //not handled
+}
+
+/***********************************************************************
+ * gain handler implementation set method
+ **********************************************************************/
+bool gain_handler_impl::intercept_set(const wax::obj &key_, const wax::obj &val){
+ wax::obj key; std::string name;
+ boost::tie(key, name) = extract_named_prop(key_);
+
+ //not a gain value key... dont handle
+ if (not _is_equal(key, _gain_props.gain_val_prop)) return false;
+
+ gain_t gain_val = wax::cast<gain_t>(val);
+
+ //not a wildcard... dont handle (but check name and range)
+ if (name != ""){
+ assert_has(get_gain_names(), name, "gain name");
+ gain_t gain_min = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_min_prop, name)]);
+ gain_t gain_max = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_max_prop, name)]);
+ if (gain_val > gain_max or gain_val < gain_min) throw std::range_error(str(
+ boost::format("A value of %f for gain %s is out of range of (%f, %f)")
+ % gain_val % name % gain_min % gain_max
+ ));
+ return false;
+ }
+
+ //set the overall gain
+ BOOST_FOREACH(std::string name, get_gain_names()){
+ //get the min, max, step for this gain name
+ gain_t gain_min = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_min_prop, name)]);
+ gain_t gain_max = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_max_prop, name)]);
+ gain_t gain_step = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_step_prop, name)]);
+
+ //clip g to be within the allowed range
+ gain_t g = std::min(std::max(gain_val, gain_min), gain_max);
+ //set g to be a multiple of the step size
+ g -= fmod(g, gain_step);
+ //set g to be the new gain
+ _link[named_prop_t(_gain_props.gain_val_prop, name)] = g;
+ //subtract g out of the total gain left to apply
+ gain_val -= g;
+ }
+
+ return true;
}
diff --git a/host/lib/usrp/dboard/basic.cpp b/host/lib/usrp/dboard/basic.cpp
index 5e245a8cf..4b74e4a47 100644
--- a/host/lib/usrp/dboard/basic.cpp
+++ b/host/lib/usrp/dboard/basic.cpp
@@ -73,12 +73,12 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){
return dboard_base::sptr(new basic_tx(args, 32e6));
}
-STATIC_BLOCK(reg_dboards, {
+STATIC_BLOCK(reg_dboards){
dboard_manager::register_subdevs(0x0000, &make_basic_tx, "Basic TX", list_of(""));
dboard_manager::register_subdevs(0x0001, &make_basic_rx, "Basic RX", list_of("a")("b")("ab"));
dboard_manager::register_subdevs(0x000e, &make_lf_tx, "LF TX", list_of(""));
dboard_manager::register_subdevs(0x000f, &make_lf_rx, "LF RX", list_of("a")("b")("ab"));
-});
+}
/***********************************************************************
* Basic and LF RX dboard
diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp
index 57b449175..08b92e62a 100644
--- a/host/lib/usrp/dboard_manager.cpp
+++ b/host/lib/usrp/dboard_manager.cpp
@@ -16,10 +16,12 @@
//
#include <uhd/usrp/dboard_manager.hpp>
+#include <uhd/gain_handler.hpp>
#include <uhd/utils.hpp>
#include <uhd/dict.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/format.hpp>
+#include <boost/bind.hpp>
#include <boost/foreach.hpp>
using namespace uhd;
@@ -42,6 +44,7 @@ void dboard_manager::register_subdevs(
const std::string &name,
const prop_names_t &subdev_names
){
+ //std::cout << "registering: " << name << std::endl;
id_to_str[dboard_id] = name;
id_to_args_map[dboard_id] = args_t(dboard_ctor, subdev_names);
}
@@ -52,36 +55,7 @@ std::string dboard_id::to_string(const dboard_id_t &id){
}
/***********************************************************************
- * dboard manager implementation class
- **********************************************************************/
-class dboard_manager_impl : public dboard_manager{
-
-public:
- dboard_manager_impl(
- dboard_id_t rx_dboard_id,
- dboard_id_t tx_dboard_id,
- dboard_interface::sptr interface
- );
- ~dboard_manager_impl(void);
-
- //dboard_interface
- prop_names_t get_rx_subdev_names(void);
- prop_names_t get_tx_subdev_names(void);
- wax::obj get_rx_subdev(const std::string &subdev_name);
- wax::obj get_tx_subdev(const std::string &subdev_name);
-
-private:
- //list of rx and tx dboards in this dboard_manager
- //each dboard here is actually a subdevice proxy
- //the subdevice proxy is internal to the cpp file
- uhd::dict<std::string, wax::obj> _rx_dboards;
- uhd::dict<std::string, wax::obj> _tx_dboards;
- dboard_interface::sptr _interface;
- void set_nice_gpio_pins(void);
-};
-
-/***********************************************************************
- * internal helper classes
+ * internal helper classe
**********************************************************************/
/*!
* A special wax proxy object that forwards calls to a subdev.
@@ -95,7 +69,18 @@ public:
//structors
subdev_proxy(dboard_base::sptr subdev, type_t type)
: _subdev(subdev), _type(type){
- /* NOP */
+ //initialize gain props struct
+ gain_handler::gain_props_t gain_props;
+ gain_props.gain_val_prop = SUBDEV_PROP_GAIN;
+ gain_props.gain_min_prop = SUBDEV_PROP_GAIN_MIN;
+ gain_props.gain_max_prop = SUBDEV_PROP_GAIN_MAX;
+ gain_props.gain_step_prop = SUBDEV_PROP_GAIN_STEP;
+ gain_props.gain_names_prop = SUBDEV_PROP_GAIN_NAMES;
+
+ //make a new gain handler
+ _gain_handler = gain_handler::make(
+ this->get_link(), gain_props, boost::bind(&gain_handler::is_equal<subdev_prop_t>, _1, _2)
+ );
}
~subdev_proxy(void){
@@ -103,11 +88,13 @@ public:
}
private:
+ gain_handler::sptr _gain_handler;
dboard_base::sptr _subdev;
type_t _type;
//forward the get calls to the rx or tx
void get(const wax::obj &key, wax::obj &val){
+ if (_gain_handler->intercept_get(key, val)) return;
switch(_type){
case RX_TYPE: return _subdev->rx_get(key, val);
case TX_TYPE: return _subdev->tx_get(key, val);
@@ -116,6 +103,7 @@ private:
//forward the set calls to the rx or tx
void set(const wax::obj &key, const wax::obj &val){
+ if (_gain_handler->intercept_set(key, val)) return;
switch(_type){
case RX_TYPE: return _subdev->rx_set(key, val);
case TX_TYPE: return _subdev->tx_set(key, val);
@@ -124,6 +112,35 @@ private:
};
/***********************************************************************
+ * dboard manager implementation class
+ **********************************************************************/
+class dboard_manager_impl : public dboard_manager{
+
+public:
+ dboard_manager_impl(
+ dboard_id_t rx_dboard_id,
+ dboard_id_t tx_dboard_id,
+ dboard_interface::sptr interface
+ );
+ ~dboard_manager_impl(void);
+
+ //dboard_interface
+ prop_names_t get_rx_subdev_names(void);
+ prop_names_t get_tx_subdev_names(void);
+ wax::obj get_rx_subdev(const std::string &subdev_name);
+ wax::obj get_tx_subdev(const std::string &subdev_name);
+
+private:
+ //list of rx and tx dboards in this dboard_manager
+ //each dboard here is actually a subdevice proxy
+ //the subdevice proxy is internal to the cpp file
+ uhd::dict<std::string, subdev_proxy::sptr> _rx_dboards;
+ uhd::dict<std::string, subdev_proxy::sptr> _tx_dboards;
+ dboard_interface::sptr _interface;
+ void set_nice_gpio_pins(void);
+};
+
+/***********************************************************************
* make routine for dboard manager
**********************************************************************/
dboard_manager::sptr dboard_manager::make(
@@ -241,7 +258,7 @@ wax::obj dboard_manager_impl::get_rx_subdev(const std::string &subdev_name){
str(boost::format("Unknown rx subdev name %s") % subdev_name)
);
//get a link to the rx subdev proxy
- return wax::cast<subdev_proxy::sptr>(_rx_dboards[subdev_name])->get_link();
+ return _rx_dboards[subdev_name]->get_link();
}
wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){
@@ -249,7 +266,7 @@ wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){
str(boost::format("Unknown tx subdev name %s") % subdev_name)
);
//get a link to the tx subdev proxy
- return wax::cast<subdev_proxy::sptr>(_tx_dboards[subdev_name])->get_link();
+ return _tx_dboards[subdev_name]->get_link();
}
void dboard_manager_impl::set_nice_gpio_pins(void){
diff --git a/host/lib/wax.cpp b/host/lib/wax.cpp
index c08398c50..0348d9a66 100644
--- a/host/lib/wax.cpp
+++ b/host/lib/wax.cpp
@@ -36,7 +36,11 @@ public:
link_args_t(const wax::obj *obj_ptr) : _obj_ptr(obj_ptr){
/* NOP */
}
- wax::obj & operator()(void){
+ wax::obj & operator()(void) const{
+ //recursively resolve link args to get at original pointer
+ if (_obj_ptr->type() == typeid(link_args_t)){
+ return wax::cast<link_args_t>(*_obj_ptr)();
+ }
return *const_cast<wax::obj *>(_obj_ptr);
}
private:
@@ -56,10 +60,10 @@ public:
proxy_args_t(const wax::obj *obj_ptr, const wax::obj &key) : _key(key){
_obj_link = obj_ptr->get_link();
}
- wax::obj & operator()(void){
+ wax::obj & operator()(void) const{
return wax::cast<link_args_t>(_obj_link)();
}
- const wax::obj & key(void){
+ const wax::obj & key(void) const{
return _key;
}
private:
diff --git a/host/test/gain_handler_test.cpp b/host/test/gain_handler_test.cpp
index c81221aac..9a6a50dab 100644
--- a/host/test/gain_handler_test.cpp
+++ b/host/test/gain_handler_test.cpp
@@ -17,7 +17,9 @@
#include <boost/test/unit_test.hpp>
#include <uhd/gain_handler.hpp>
+#include <uhd/props.hpp>
#include <uhd/dict.hpp>
+#include <boost/bind.hpp>
#include <iostream>
using namespace uhd;
@@ -33,9 +35,17 @@ enum prop_t{
class gainful_obj : public wax::obj{
public:
gainful_obj(void){
- _gain_handler = gain_handler::sptr(new gain_handler(
- this, PROP_GAIN, PROP_GAIN_MIN, PROP_GAIN_MAX, PROP_GAIN_STEP, PROP_GAIN_NAMES
- ));
+ //initialize gain props struct
+ gain_handler::gain_props_t gain_props;
+ gain_props.gain_val_prop = PROP_GAIN;
+ gain_props.gain_min_prop = PROP_GAIN_MIN;
+ gain_props.gain_max_prop = PROP_GAIN_MAX;
+ gain_props.gain_step_prop = PROP_GAIN_STEP;
+ gain_props.gain_names_prop = PROP_GAIN_NAMES;
+ //make a new gain handler
+ _gain_handler = gain_handler::make(
+ this->get_link(), gain_props, boost::bind(&gain_handler::is_equal<prop_t>, _1, _2)
+ );
_gains["g0"] = 0;
_gains["g1"] = 0;
_gains_min["g0"] = -10;
@@ -113,7 +123,7 @@ BOOST_AUTO_TEST_CASE(test_gain_handler){
BOOST_CHECK_THROW(
wax::cast<gain_t>(go0[named_prop_t(PROP_GAIN, "fail")]),
- std::invalid_argument
+ std::exception
);
std::cout << "verifying the overall min, max, step" << std::endl;