diff options
Diffstat (limited to 'host/lib/usrp/usrp2')
-rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 11 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 113 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 13 |
3 files changed, 134 insertions, 3 deletions
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 2e4a0715f..cc73b229c 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -23,6 +23,13 @@ using namespace uhd; /*********************************************************************** * Helper Methods **********************************************************************/ +void usrp2_impl::mboard_init(void){ + _mboards[""] = wax_obj_proxy( + boost::bind(&usrp2_impl::mboard_get, this, _1, _2), + boost::bind(&usrp2_impl::mboard_set, this, _1, _2) + ); +} + void usrp2_impl::init_clock_config(void){ //init the pps source clock config _pps_source_dict["sma"] = USRP2_PPS_SOURCE_SMA; @@ -60,7 +67,7 @@ void usrp2_impl::update_clock_config(void){ /*********************************************************************** * MBoard Get Properties **********************************************************************/ -void usrp2_impl::get(const wax::obj &key_, wax::obj &val){ +void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ wax::obj key; std::string name; boost::tie(key, name) = extract_named_prop(key_); @@ -146,7 +153,7 @@ void usrp2_impl::get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * MBoard Set Properties **********************************************************************/ -void usrp2_impl::set(const wax::obj &key, const wax::obj &val){ +void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ //handle the get request conditioned on the key switch(wax::cast<mboard_prop_t>(key)){ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index dbf740f2b..ac0c3c88a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -22,6 +22,78 @@ #include "usrp2_impl.hpp" using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Discovery over the udp transport + **********************************************************************/ +uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ + device_addrs_t usrp2_addrs; + + //create a udp transport to communicate + //TODO if an addr is not provided, search all interfaces? + std::string ctrl_port = boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT); + uhd::transport::udp udp_transport(hint["addr"], ctrl_port, true); + + //send a hello control packet + usrp2_ctrl_data_t ctrl_data_out; + ctrl_data_out.id = htonl(USRP2_CTRL_ID_GIVE_ME_YOUR_IP_ADDR_BRO); + udp_transport.send(boost::asio::buffer(&ctrl_data_out, sizeof(ctrl_data_out))); + + //loop and recieve until the time is up + size_t num_timeouts = 0; + while(true){ + uhd::shared_iovec iov = udp_transport.recv(); + //std::cout << boost::asio::buffer_size(buff) << "\n"; + if (iov.len < sizeof(usrp2_ctrl_data_t)){ + //sleep a little so we dont burn cpu + if (num_timeouts++ > 50) break; + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); + }else{ + //handle the received data + const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(iov.base); + switch(ntohl(ctrl_data_in->id)){ + case USRP2_CTRL_ID_THIS_IS_MY_IP_ADDR_DUDE: + //make a boost asio ipv4 with the raw addr in host byte order + boost::asio::ip::address_v4 ip_addr(ntohl(ctrl_data_in->data.ip_addr)); + device_addr_t new_addr; + new_addr["name"] = "USRP2"; + new_addr["type"] = "udp"; + new_addr["addr"] = ip_addr.to_string(); + usrp2_addrs.push_back(new_addr); + break; + } + } + } + + return usrp2_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +device::sptr usrp2::make(const device_addr_t &device_addr){ + //create a control transport + uhd::transport::udp::sptr ctrl_transport( + new uhd::transport::udp( + device_addr["addr"], + boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT) + ) + ); + + //create a data transport + uhd::transport::udp::sptr data_transport( + new uhd::transport::udp( + device_addr["addr"], + boost::lexical_cast<std::string>(USRP2_UDP_DATA_PORT) + ) + ); + + //create the usrp2 implementation guts + return device::sptr(dynamic_cast<device*>( + new usrp2_impl(ctrl_transport, data_transport) + )); +} /*********************************************************************** * Structors @@ -46,6 +118,9 @@ usrp2_impl::usrp2_impl( _allowed_decim_and_interp_rates.push_back(i); } + //init the mboard + mboard_init(); + //init the tx and rx dboards dboard_init(); @@ -100,3 +175,41 @@ usrp2_ctrl_data_t usrp2_impl::ctrl_send_and_recv(const usrp2_ctrl_data_t &out_da } throw std::runtime_error("usrp2 no control response"); } + +/*********************************************************************** + * Device Properties + **********************************************************************/ +void usrp2_impl::get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(wax::cast<device_prop_t>(key)){ + case DEVICE_PROP_NAME: + val = std::string("usrp2 device"); + return; + + case DEVICE_PROP_MBOARD: + val = _mboards[name].get_link(); + return; + + case DEVICE_PROP_MBOARD_NAMES: + val = prop_names_t(_mboards.get_keys()); + return; + } +} + +void usrp2_impl::set(const wax::obj &, const wax::obj &){ + throw std::runtime_error("Cannot set in usrp2 device"); +} + +/*********************************************************************** + * IO Interface + **********************************************************************/ +void usrp2_impl::send_raw(const std::vector<boost::asio::const_buffer> &){ + return; +} + +uhd::shared_iovec usrp2_impl::recv_raw(void){ + throw std::runtime_error("not implemented"); +} diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index be457a91c..2545efd58 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -15,6 +15,7 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // +#include <uhd/usrp/usrp2.hpp> #include <uhd/dict.hpp> #include <uhd/props.hpp> #include <uhd/time_spec.hpp> @@ -70,7 +71,7 @@ private: * The implementation details are encapsulated here. * Handles properties on the mboard, dboard, dsps... */ -class usrp2_impl : boost::noncopyable, public wax::obj{ +class usrp2_impl : public uhd::device{ public: typedef boost::shared_ptr<usrp2_impl> sptr; @@ -96,6 +97,10 @@ public: //misc access methods double get_master_clock_freq(void); + //the io interface + void send_raw(const std::vector<boost::asio::const_buffer> &); + uhd::shared_iovec recv_raw(void); + private: //udp transports for control and data uhd::transport::udp::sptr _ctrl_transport; @@ -119,6 +124,12 @@ private: uhd::usrp::dboard_manager::sptr _dboard_manager; void dboard_init(void); + //properties for the mboard + void mboard_init(void); + void mboard_get(const wax::obj &, wax::obj &); + void mboard_set(const wax::obj &, const wax::obj &); + uhd::dict<std::string, wax_obj_proxy> _mboards; + //properties interface for rx dboard void rx_dboard_get(const wax::obj &, wax::obj &); void rx_dboard_set(const wax::obj &, const wax::obj &); |