diff options
| -rw-r--r-- | host/include/uhd/gain_handler.hpp | 68 | ||||
| -rw-r--r-- | host/include/uhd/utils.hpp | 7 | ||||
| -rw-r--r-- | host/lib/device.cpp | 15 | ||||
| -rw-r--r-- | host/lib/gain_handler.cpp | 264 | ||||
| -rw-r--r-- | host/lib/usrp/dboard/basic.cpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/dboard_manager.cpp | 83 | ||||
| -rw-r--r-- | host/lib/wax.cpp | 10 | ||||
| -rw-r--r-- | host/test/gain_handler_test.cpp | 18 | 
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; | 
