summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/discover_usrps.cpp5
-rw-r--r--firmware/microblaze/apps/txrx.c25
-rw-r--r--include/uhd/Makefile.am2
-rw-r--r--include/uhd/device.hpp7
-rw-r--r--include/uhd/device_addr.hpp72
-rw-r--r--include/uhd/dict.hpp140
-rw-r--r--include/uhd/shared_iovec.hpp54
-rw-r--r--include/uhd/transport/udp.hpp7
-rw-r--r--include/uhd/usrp/mboard/usrp2.hpp5
-rw-r--r--include/uhd/usrp/usrp.hpp6
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/device.cpp26
-rw-r--r--lib/device_addr.cpp60
-rw-r--r--lib/shared_iovec.cpp28
-rw-r--r--lib/transport/udp.cpp16
-rw-r--r--lib/usrp/mboard/test.cpp4
-rw-r--r--lib/usrp/mboard/usrp2.cpp62
-rw-r--r--lib/usrp/mboard/usrp2_fw_common.h30
-rw-r--r--lib/usrp/usrp.cpp15
-rw-r--r--test/device_test.cpp11
20 files changed, 403 insertions, 173 deletions
diff --git a/apps/discover_usrps.cpp b/apps/discover_usrps.cpp
index 036d6378a..52eb85b0a 100644
--- a/apps/discover_usrps.cpp
+++ b/apps/discover_usrps.cpp
@@ -41,9 +41,10 @@ int main(int argc, char *argv[]){
}
//extract the ip address (not optional for now)
- uhd::device_addr_t device_addr(uhd::DEVICE_ADDR_TYPE_UDP);
+ uhd::device_addr_t device_addr;
+ device_addr["type"] = "udp";
if (vm.count("ip-addr")) {
- device_addr.udp_args.addr = vm["ip-addr"].as<std::string>();
+ device_addr["addr"] = vm["ip-addr"].as<std::string>();
} else {
std::cout << "IP Addess was not set" << std::endl;
return ~0;
diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c
index 1c43a2ca1..2cc414f02 100644
--- a/firmware/microblaze/apps/txrx.c
+++ b/firmware/microblaze/apps/txrx.c
@@ -159,28 +159,37 @@ void handle_udp_ctrl_packet(
struct socket_address src, struct socket_address dst,
unsigned char *payload, int payload_len
){
- printf("Got ctrl packet #words: %d\n", (int)payload_len);
+ //printf("Got ctrl packet #words: %d\n", (int)payload_len);
if (payload_len < sizeof(usrp2_ctrl_data_t)){
//TODO send err packet
return;
}
+
//setup the input and output data
usrp2_ctrl_data_t *ctrl_data_in = (usrp2_ctrl_data_t *)payload;
usrp2_ctrl_data_t ctrl_data_out = {
- .id=USRP2_CTRL_ID_NONE,
+ .id=USRP2_CTRL_ID_HUH_WHAT,
.seq=ctrl_data_in->seq
};
+
//handle the data based on the id
switch(ctrl_data_in->id){
- case USRP2_CTRL_ID_HELLO:
- ctrl_data_out.id = ctrl_data_in->id;
- //grab the addrs
+
+ case USRP2_CTRL_ID_GIVE_ME_YOUR_IP_ADDR_BRO:
+ ctrl_data_out.id = USRP2_CTRL_ID_THIS_IS_MY_IP_ADDR_DUDE;
struct ip_addr ip_addr = get_my_ip_addr();
+ memcpy(&ctrl_data_out.data.ip_addr, &ip_addr, sizeof(ip_addr));
+ break;
+
+ case USRP2_CTRL_ID_GIVE_ME_YOUR_MAC_ADDR_BRO:
+ ctrl_data_out.id = USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE;
eth_mac_addr_t mac_addr = get_my_eth_mac_addr();
- //copy them into the out data
- memcpy(&ctrl_data_out.data.discovery_addrs.ip_addr, &ip_addr, sizeof(ip_addr));
- memcpy(&ctrl_data_out.data.discovery_addrs.mac_addr, &mac_addr, sizeof(mac_addr));
+ memcpy(&ctrl_data_out.data.mac_addr, &mac_addr, sizeof(mac_addr));
break;
+
+ default:
+ ctrl_data_out.id = USRP2_CTRL_ID_HUH_WHAT;
+
}
send_udp_pkt(USRP2_UDP_CTRL_PORT, src, &ctrl_data_out, sizeof(ctrl_data_out));
}
diff --git a/include/uhd/Makefile.am b/include/uhd/Makefile.am
index 772d1e4b9..6c2034ea8 100644
--- a/include/uhd/Makefile.am
+++ b/include/uhd/Makefile.am
@@ -23,8 +23,10 @@ this_includedir = $(includedir)/uhd
this_include_HEADERS = \
device.hpp \
device_addr.hpp \
+ dict.hpp \
gain_handler.hpp \
props.hpp \
+ shared_iovec.hpp \
time_spec.hpp \
utils.hpp \
wax.hpp
diff --git a/include/uhd/device.hpp b/include/uhd/device.hpp
index 09a2bbb2f..dfbfbd7c0 100644
--- a/include/uhd/device.hpp
+++ b/include/uhd/device.hpp
@@ -25,6 +25,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/asio/buffer.hpp>
+#include <uhd/shared_iovec.hpp>
#include <vector>
namespace uhd{
@@ -51,7 +52,7 @@ public:
* \param hint a partially (or fully) filled in device address
* \return a vector of device addresses for all usrps on the system
*/
- static std::vector<device_addr_t> discover(const device_addr_t & hint);
+ static device_addrs_t discover(const device_addr_t &hint);
/*!
* \brief Create a new usrp device from the device address hint.
@@ -64,7 +65,7 @@ public:
* \param which which address to use when multiple are discovered
* \return a shared pointer to a new device instance
*/
- static sptr make(const device_addr_t & hint, size_t which = 0);
+ static sptr make(const device_addr_t &hint, size_t which = 0);
/*!
* Get the device address for this board.
@@ -73,7 +74,7 @@ public:
//the io interface
virtual void send_raw(const std::vector<boost::asio::const_buffer> &) = 0;
- virtual boost::asio::const_buffer recv_raw(void) = 0;
+ virtual uhd::shared_iovec recv_raw(void) = 0;
};
} //namespace uhd
diff --git a/include/uhd/device_addr.hpp b/include/uhd/device_addr.hpp
index 84ae60881..8ea580321 100644
--- a/include/uhd/device_addr.hpp
+++ b/include/uhd/device_addr.hpp
@@ -18,10 +18,12 @@
#ifndef INCLUDED_UHD_DEVICE_ADDR_HPP
#define INCLUDED_UHD_DEVICE_ADDR_HPP
+#include <uhd/dict.hpp>
#include <string>
#include <iostream>
#include <netinet/ether.h>
#include <stdint.h>
+#include <vector>
namespace uhd{
@@ -36,62 +38,30 @@ namespace uhd{
};
/*!
- * Possible usrp device interface types.
- */
- enum device_addr_type_t{
- DEVICE_ADDR_TYPE_AUTO,
- DEVICE_ADDR_TYPE_VIRTUAL,
- DEVICE_ADDR_TYPE_USB,
- DEVICE_ADDR_TYPE_ETH,
- DEVICE_ADDR_TYPE_UDP,
- DEVICE_ADDR_TYPE_GPMC
- };
+ * The device address args are just a mapping of key/value string pairs.
+ * When left empty, the discovery routine will try to find all usrps.
+ * The discovery can be narrowed down by specifying the transport type arguments.
+ *
+ * For example, to access a specific usrp2 one would specify the transport type
+ * ("type", "udp") and the transport args ("addr", "<resolvable_hostname_or_addr>").
+ */
+ typedef dict<std::string, std::string> device_addr_t;
+ typedef std::vector<device_addr_t> device_addrs_t;
/*!
- * Structure to hold properties that identify a usrp device.
- */
- struct device_addr_t{
- device_addr_type_t type;
- struct{
- size_t num_rx_dsps;
- size_t num_tx_dsps;
- size_t num_dboards;
- } virtual_args;
- struct{
- uint16_t vendor_id;
- uint16_t product_id;
- } usb_args;
- struct{
- std::string ifc;
- std::string mac_addr;
- } eth_args;
- struct{
- std::string addr;
- } udp_args;
- struct{
- //TODO unknown for now
- } gpmc_args;
-
- //the discovery args are filled in by the discovery routine
- struct{
- uint16_t mboard_id;
- } discovery_args;
-
- /*!
- * \brief Convert a usrp device_addr_t into a string representation
- */
- std::string to_string(void) const;
-
- /*!
- * \brief Default constructor to initialize the device_addr_t struct
- */
- device_addr_t(device_addr_type_t device_addr_type = DEVICE_ADDR_TYPE_AUTO);
- };
+ * Function to turn a device address into a string.
+ * Just having the operator<< below should be sufficient.
+ * However, boost format seems to complain with the %
+ * and this is just easier because it works.
+ * \param device_addr a device address instance
+ * \return the string representation
+ */
+ std::string device_addr_to_string(const device_addr_t &device_addr);
} //namespace uhd
//ability to use types with stream operators
-std::ostream& operator<<(std::ostream &os, const uhd::device_addr_t &x);
-std::ostream& operator<<(std::ostream &os, const uhd::mac_addr_t &x);
+std::ostream& operator<<(std::ostream &, const uhd::device_addr_t &);
+std::ostream& operator<<(std::ostream &, const uhd::mac_addr_t &);
#endif /* INCLUDED_UHD_DEVICE_ADDR_HPP */
diff --git a/include/uhd/dict.hpp b/include/uhd/dict.hpp
new file mode 100644
index 000000000..3abc4273c
--- /dev/null
+++ b/include/uhd/dict.hpp
@@ -0,0 +1,140 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_DICT_HPP
+#define INCLUDED_UHD_DICT_HPP
+
+#include <map>
+#include <vector>
+#include <boost/foreach.hpp>
+#include <stdexcept>
+
+namespace uhd{
+
+ /*!
+ * A templated dictionary class with a python-like interface.
+ * Its wraps around a std::map internally.
+ */
+ template <class Key, class Val> class dict{
+ public:
+ /*!
+ * Create a new empty dictionary.
+ */
+ dict(void){
+ /* NOP */
+ }
+
+ /*!
+ * Create a dictionary from a map.
+ * \param map a map with key value pairs
+ */
+ dict(const std::map<Key, Val> &map){
+ _map = map;
+ }
+
+ /*!
+ * Destroy this dict.
+ */
+ ~dict(void){
+ /* NOP */
+ }
+
+ /*!
+ * Get a list of the keys in this dict.
+ * \return vector of keys
+ */
+ std::vector<Key> get_keys(void) const{
+ std::vector<Key> keys;
+ std::pair<Key, Val> p;
+ BOOST_FOREACH(p, _map){
+ keys.push_back(p.first);
+ }
+ return keys;
+ }
+
+ /*!
+ * Get a list of the values in this dict.
+ * \return vector of values
+ */
+ std::vector<Val> get_vals(void) const{
+ std::vector<Val> vals;
+ std::pair<Key, Val> p;
+ BOOST_FOREACH(p, _map){
+ vals.push_back(p.second);
+ }
+ return vals;
+ }
+
+ /*!
+ * Does the dictionary contain this key?
+ * \param key the key to look for
+ * \return true if found
+ */
+ bool has_key(const Key &key) const{
+ std::pair<Key, Val> p;
+ BOOST_FOREACH(p, _map){
+ if (p.first == key) return true;
+ }
+ return false;
+ }
+
+ /*!
+ * Get a value for the given key if it exists.
+ * If the key is not found throw an error.
+ * \param key the key to look for
+ * \return the value at the key
+ * \throw an exception when not found
+ */
+ const Val &operator[](const Key &key) const{
+ if (has_key(key)){
+ return _map.find(key)->second;
+ }
+ throw std::invalid_argument("key not found in dict");
+ }
+
+ /*!
+ * Set a value for the given key, however, in reality
+ * it really returns a reference which can be assigned to.
+ * \param key the key to set to
+ * \return a reference to the value
+ */
+ Val &operator[](const Key &key){
+ return _map[key];
+ }
+
+ /*!
+ * Pop an item out of the dictionary.
+ * \param key the item key
+ * \return the value of the item
+ * \throw an exception when not found
+ */
+ Val pop_key(const Key &key){
+ if (has_key(key)){
+ Val val = _map.find(key)->second;
+ _map.erase(key);
+ return val;
+ }
+ throw std::invalid_argument("key not found in dict");
+ }
+
+ private:
+ std::map<Key, Val> _map; //private container
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_DICT_HPP */
diff --git a/include/uhd/shared_iovec.hpp b/include/uhd/shared_iovec.hpp
new file mode 100644
index 000000000..a120e55d5
--- /dev/null
+++ b/include/uhd/shared_iovec.hpp
@@ -0,0 +1,54 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_SHARED_IOVEC_HPP
+#define INCLUDED_UHD_SHARED_IOVEC_HPP
+
+#include <boost/shared_array.hpp>
+#include <stdint.h>
+
+namespace uhd{
+
+/*!
+ * A shared iovec contains a shared array and its length.
+ * Creating a new shared iovec allocates new memory.
+ * This memory is freed when all copies are destroyed.
+ */
+class shared_iovec{
+public:
+ /*!
+ * Create a shared iovec and allocate memory.
+ * \param len the length in bytes
+ */
+ shared_iovec(size_t len=0);
+
+ /*!
+ * Destroy a shared iovec.
+ * Will not free the memory unless this is the last copy.
+ */
+ ~shared_iovec(void);
+
+ void *base;
+ size_t len;
+
+private:
+ boost::shared_array<uint8_t> _shared_array;
+};
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_SHARED_IOVEC_HPP */
diff --git a/include/uhd/transport/udp.hpp b/include/uhd/transport/udp.hpp
index c9a9dd53b..6db6bd377 100644
--- a/include/uhd/transport/udp.hpp
+++ b/include/uhd/transport/udp.hpp
@@ -18,7 +18,7 @@
#include <boost/asio.hpp>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
-#include <stdio.h>
+#include <uhd/shared_iovec.hpp>
#ifndef INCLUDED_UHD_TRANSPORT_UDP_HPP
#define INCLUDED_UHD_TRANSPORT_UDP_HPP
@@ -59,16 +59,15 @@ public:
/*!
* Receive a buffer. The memory is managed internally.
* Calling recv will invalidate the buffer of the previous recv.
- * \return an asio const buffer with internal memory
+ * \return a shared iovec with allocated memory
*/
- boost::asio::const_buffer recv(void);
+ uhd::shared_iovec recv(void);
private:
boost::asio::ip::udp::socket *_socket;
boost::asio::ip::udp::endpoint _receiver_endpoint;
boost::asio::ip::udp::endpoint _sender_endpoint;
boost::asio::io_service _io_service;
- uint8_t _recv_buff[1500]; //max mtu
};
}} //namespace
diff --git a/include/uhd/usrp/mboard/usrp2.hpp b/include/uhd/usrp/mboard/usrp2.hpp
index 8c2430dbd..4950f4cd1 100644
--- a/include/uhd/usrp/mboard/usrp2.hpp
+++ b/include/uhd/usrp/mboard/usrp2.hpp
@@ -21,6 +21,7 @@
#include <uhd/usrp/mboard/base.hpp>
#include <uhd/device_addr.hpp>
#include <uhd/usrp/dboard/manager.hpp>
+#include <uhd/transport/udp.hpp>
#include <map>
namespace uhd{ namespace usrp{ namespace mboard{
@@ -36,7 +37,7 @@ public:
* \param hint a device addr with the usrp2 address filled in
* \return a vector of device addresses for all usrp2s found
*/
- static std::vector<device_addr_t> discover(const device_addr_t &hint);
+ static device_addrs_t discover(const device_addr_t &hint);
usrp2(const device_addr_t &);
~usrp2(void);
@@ -46,6 +47,8 @@ private:
void set(const wax::obj &, const wax::obj &);
std::map<std::string, dboard::manager::sptr> _dboard_managers;
+ uhd::transport::udp::sptr _udp_ctrl_transport;
+ uhd::transport::udp::sptr _udp_data_transport;
};
}}} //namespace
diff --git a/include/uhd/usrp/usrp.hpp b/include/uhd/usrp/usrp.hpp
index 975debed1..0dca36f62 100644
--- a/include/uhd/usrp/usrp.hpp
+++ b/include/uhd/usrp/usrp.hpp
@@ -32,12 +32,12 @@ namespace uhd{ namespace usrp{
*/
class usrp : public device{
public:
- usrp(const device_addr_t & device_addr);
+ usrp(const device_addr_t &device_addr);
~usrp(void);
//the io interface
void send_raw(const std::vector<boost::asio::const_buffer> &);
- boost::asio::const_buffer recv_raw(void);
+ uhd::shared_iovec recv_raw(void);
private:
void get(const wax::obj &, wax::obj &);
@@ -45,7 +45,7 @@ private:
std::map<std::string, mboard::base::sptr> _mboards;
boost::function<void(const std::vector<boost::asio::const_buffer> &)> _send_raw_cb;
- boost::function<boost::asio::const_buffer(void)> _recv_raw_cb;
+ boost::function<uhd::shared_iovec(void)> _recv_raw_cb;
};
}} //namespace
diff --git a/lib/Makefile.am b/lib/Makefile.am
index ff7c6b75d..58e43b8b2 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -27,6 +27,7 @@ libuhd_la_SOURCES = \
device.cpp \
device_addr.cpp \
gain_handler.cpp \
+ shared_iovec.cpp \
uhd.cpp \
wax.cpp
diff --git a/lib/device.cpp b/lib/device.cpp
index 4b51a70d4..822733217 100644
--- a/lib/device.cpp
+++ b/lib/device.cpp
@@ -23,35 +23,37 @@
using namespace uhd;
-std::vector<device_addr_t> device::discover(const device_addr_t & hint = device_addr_t()){
- std::vector<device_addr_t> device_addrs;
- if (hint.type == DEVICE_ADDR_TYPE_UDP){
+device_addrs_t device::discover(const device_addr_t &hint){
+ device_addrs_t device_addrs;
+ if (not hint.has_key("type")){
+ //TODO nothing
+ }
+ else if (hint["type"] == "test"){
+ //make a copy of the hint for testing
+ device_addr_t test_device_addr = hint;
+ device_addrs.push_back(test_device_addr);
+ }
+ else if (hint["type"] == "udp"){
std::vector<device_addr_t> usrp2_addrs = usrp::mboard::usrp2::discover(hint);
device_addrs.insert(device_addrs.begin(), usrp2_addrs.begin(), usrp2_addrs.end());
}
- if (hint.type == DEVICE_ADDR_TYPE_VIRTUAL){
- //make a copy of the hint for virtual testing
- device_addr_t virtual_device_addr = hint;
- device_addrs.push_back(virtual_device_addr);
- }
return device_addrs;
}
-device::sptr device::make(const device_addr_t & hint, size_t which){
+device::sptr device::make(const device_addr_t &hint, size_t which){
std::vector<device_addr_t> device_addrs = discover(hint);
//check that we found any devices
if (device_addrs.size() == 0){
throw std::runtime_error(str(
- boost::format("No devices found for %s") % hint.to_string()
+ boost::format("No devices found for %s") % device_addr_to_string(hint)
));
}
//check that the which index is valid
if (device_addrs.size() <= which){
throw std::runtime_error(str(
- boost::format("No device at index %d for %s")
- % which % hint.to_string()
+ boost::format("No device at index %d for %s") % which % device_addr_to_string(hint)
));
}
diff --git a/lib/device_addr.cpp b/lib/device_addr.cpp
index ee6dbbbc8..ffd511f92 100644
--- a/lib/device_addr.cpp
+++ b/lib/device_addr.cpp
@@ -21,6 +21,7 @@
#include <stdexcept>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/foreach.hpp>
//----------------------- u2 mac addr wrapper ------------------------//
uhd::mac_addr_t::mac_addr_t(const std::string &mac_addr_str_){
@@ -71,58 +72,15 @@ std::ostream& operator<<(std::ostream &os, const uhd::mac_addr_t &x){
}
//----------------------- usrp device_addr_t wrapper -------------------------//
-uhd::device_addr_t::device_addr_t(device_addr_type_t device_addr_type){
- type = device_addr_type;
- virtual_args.num_rx_dsps = 0;
- virtual_args.num_tx_dsps = 0;
- virtual_args.num_dboards = 0;
- usb_args.vendor_id = 0xffff;
- usb_args.product_id = 0xffff;
- eth_args.ifc = "eth0";
- eth_args.mac_addr = "";
- udp_args.addr = "";
- discovery_args.mboard_id = ~0;
-}
-
-std::string uhd::device_addr_t::to_string(void) const{
- std::ostringstream out;
- out << "USRP Type: ";
- switch(type){
- case DEVICE_ADDR_TYPE_AUTO:
- out << "Automatic" << std::endl;
- break;
- case DEVICE_ADDR_TYPE_VIRTUAL:
- out << "Virtual" << std::endl;
- out << "Num RX DSPs: " << virtual_args.num_rx_dsps << std::endl;
- out << "Num TX DSPs: " << virtual_args.num_rx_dsps << std::endl;
- out << "Num dboards: " << virtual_args.num_dboards << std::endl;
- break;
- case DEVICE_ADDR_TYPE_USB:
- out << "USB Port" << std::endl;
- out << "Vendor ID: 0x" << std::hex << usb_args.vendor_id << std::endl;
- out << "Product ID: 0x" << std::hex << usb_args.product_id << std::endl;
- break;
- case DEVICE_ADDR_TYPE_ETH:
- out << "Raw Ethernet" << std::endl;
- out << "Interface: " << eth_args.ifc << std::endl;
- out << "MAC Addr: " << eth_args.mac_addr << std::endl;
- break;
- case DEVICE_ADDR_TYPE_UDP:
- out << "UDP Socket" << std::endl;
- out << "Address: " << udp_args.addr << std::endl;
- break;
- case DEVICE_ADDR_TYPE_GPMC:
- out << "GPMC" << std::endl;
- break;
- default:
- out << "Unknown" << std::endl;
+std::string uhd::device_addr_to_string(const uhd::device_addr_t &device_addr){
+ std::stringstream ss;
+ BOOST_FOREACH(std::string key, device_addr.get_keys()){
+ ss << boost::format("%s: %s") % key % device_addr[key] << std::endl;
}
- out << std::endl;
- return out.str();
+ return ss.str();
}
-std::ostream& operator<<(std::ostream &os, const uhd::device_addr_t &x)
-{
- os << x.to_string();
- return os;
+std::ostream& operator<<(std::ostream &os, const uhd::device_addr_t &device_addr){
+ os << uhd::device_addr_to_string(device_addr);
+ return os;
}
diff --git a/lib/shared_iovec.cpp b/lib/shared_iovec.cpp
new file mode 100644
index 000000000..60062fbf0
--- /dev/null
+++ b/lib/shared_iovec.cpp
@@ -0,0 +1,28 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/shared_iovec.hpp>
+
+uhd::shared_iovec::shared_iovec(size_t len_){
+ _shared_array = boost::shared_array<uint8_t>(new uint8_t[len_]);
+ base = _shared_array.get();
+ len = len_;
+}
+
+uhd::shared_iovec::~shared_iovec(void){
+ /* NOP */
+}
diff --git a/lib/transport/udp.cpp b/lib/transport/udp.cpp
index f42ddcb75..06defb107 100644
--- a/lib/transport/udp.cpp
+++ b/lib/transport/udp.cpp
@@ -53,15 +53,15 @@ void uhd::transport::udp::send(const boost::asio::const_buffer &buff){
send(buffs);
}
-boost::asio::const_buffer uhd::transport::udp::recv(void){
- size_t len = 0;
- //recv if data is available
- if (_socket->available()){
- len = _socket->receive_from(
- boost::asio::buffer(_recv_buff, sizeof(_recv_buff)),
+uhd::shared_iovec uhd::transport::udp::recv(void){
+ //allocate a buffer for the number of bytes available (could be zero)
+ uhd::shared_iovec iov(_socket->available());
+ //call recv only if data is available
+ if (iov.len != 0){
+ _socket->receive_from(
+ boost::asio::buffer(iov.base, iov.len),
_sender_endpoint
);
}
- //return the buffer with the received length
- return boost::asio::buffer(_recv_buff, len);
+ return iov;
}
diff --git a/lib/usrp/mboard/test.cpp b/lib/usrp/mboard/test.cpp
index 9ad11c046..b4ac66eb7 100644
--- a/lib/usrp/mboard/test.cpp
+++ b/lib/usrp/mboard/test.cpp
@@ -109,8 +109,10 @@ private:
* test usrp mboard class
**********************************************************************/
test::test(const device_addr_t &device_addr){
+ //extract the number of dboards
+ size_t num_dboards = boost::lexical_cast<size_t>(device_addr["num_dboards"]);
//create a manager for each dboard
- for (size_t i = 0; i < device_addr.virtual_args.num_dboards; i++){
+ for (size_t i = 0; i < num_dboards; i++){
dboard::interface::sptr ifc(new dummy_interface());
_dboard_managers[boost::lexical_cast<std::string>(i)] = dboard::manager::sptr(
new dboard::manager(dboard::ID_BASIC_RX, dboard::ID_BASIC_TX, ifc)
diff --git a/lib/usrp/mboard/usrp2.cpp b/lib/usrp/mboard/usrp2.cpp
index 9282a541a..9de478672 100644
--- a/lib/usrp/mboard/usrp2.cpp
+++ b/lib/usrp/mboard/usrp2.cpp
@@ -16,7 +16,6 @@
//
#include <uhd/usrp/mboard/usrp2.hpp>
-#include <uhd/transport/udp.hpp>
#include "usrp2_fw_common.h"
#include <uhd/device.hpp>
#include <boost/thread.hpp>
@@ -29,35 +28,40 @@ using namespace uhd::usrp::mboard;
/***********************************************************************
* Discovery over the udp transport
**********************************************************************/
-std::vector<uhd::device_addr_t> usrp2::discover(const device_addr_t &hint){
- std::vector<uhd::device_addr_t> usrp2_addrs;
+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.udp_args.addr, ctrl_port, true);
+ 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_HELLO);
+ 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){
- boost::asio::const_buffer buff = udp_transport.recv();
+ uhd::shared_iovec iov = udp_transport.recv();
//std::cout << boost::asio::buffer_size(buff) << "\n";
- if (boost::asio::buffer_size(buff) < sizeof(usrp2_ctrl_data_t)){
+ 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 = boost::asio::buffer_cast<const usrp2_ctrl_data_t *>(buff);
+ 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_HELLO:
+ 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.discovery_addrs.ip_addr));
- std::cout << "hello " << ip_addr.to_string() << "\n";
+ 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;
}
}
@@ -65,3 +69,39 @@ std::vector<uhd::device_addr_t> usrp2::discover(const device_addr_t &hint){
return usrp2_addrs;
}
+
+/***********************************************************************
+ * Structors
+ **********************************************************************/
+usrp2::usrp2(const device_addr_t &device_addr){
+ _udp_ctrl_transport = uhd::transport::udp::sptr(
+ new uhd::transport::udp(
+ device_addr["addr"],
+ boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT)
+ )
+ );
+ _udp_data_transport = uhd::transport::udp::sptr(
+ new uhd::transport::udp(
+ device_addr["addr"],
+ boost::lexical_cast<std::string>(USRP2_UDP_DATA_PORT)
+ )
+ );
+}
+
+usrp2::~usrp2(void){
+ /* NOP */
+}
+
+/***********************************************************************
+ * Get Properties
+ **********************************************************************/
+void usrp2::get(const wax::obj &, wax::obj &){
+
+}
+
+/***********************************************************************
+ * Set Properties
+ **********************************************************************/
+void usrp2::set(const wax::obj &, const wax::obj &){
+
+}
diff --git a/lib/usrp/mboard/usrp2_fw_common.h b/lib/usrp/mboard/usrp2_fw_common.h
index 217d8cf1c..4ea9d5467 100644
--- a/lib/usrp/mboard/usrp2_fw_common.h
+++ b/lib/usrp/mboard/usrp2_fw_common.h
@@ -28,24 +28,38 @@ extern "C" {
#endif
// udp ports for the usrp2 communication
-// Dynamic and/or private ports: 49152–65535
+// Dynamic and/or private ports: 49152-65535
#define USRP2_UDP_CTRL_PORT 49152
#define USRP2_UDP_DATA_PORT 49153
typedef enum{
- USRP2_CTRL_ID_NONE,
- USRP2_CTRL_ID_HELLO
+ USRP2_CTRL_ID_HUH_WHAT,
+ //USRP2_CTRL_ID_FOR_SURE, //TODO error condition enums
+ //USRP2_CTRL_ID_SUX_MAN,
+ USRP2_CTRL_ID_GIVE_ME_YOUR_IP_ADDR_BRO,
+ USRP2_CTRL_ID_THIS_IS_MY_IP_ADDR_DUDE,
+ USRP2_CTRL_ID_HERE_IS_A_NEW_IP_ADDR_BRO,
+ USRP2_CTRL_ID_GIVE_ME_YOUR_MAC_ADDR_BRO,
+ USRP2_CTRL_ID_THIS_IS_MY_MAC_ADDR_DUDE,
+ USRP2_CTRL_ID_HERE_IS_A_NEW_MAC_ADDR_BRO
} usrp2_ctrl_id_t;
typedef struct{
uint32_t id;
uint32_t seq;
union{
- struct{
- uint32_t ip_addr;
- uint8_t mac_addr[6];
- uint8_t _padding[2];
- } discovery_addrs;
+ uint32_t ip_addr;
+ uint8_t mac_addr[6];
+ /*struct {
+ uint8_t bank;
+ uint16_t ddr;
+ uint16_t mask;
+ } gpio_ddr_args;
+ struct {
+ uint8_t bank;
+ uint16_t val;
+ uint16_t mask;
+ } gpio_val_args;*/
} data;
} usrp2_ctrl_data_t;
diff --git a/lib/usrp/usrp.cpp b/lib/usrp/usrp.cpp
index c49a63d49..68b423538 100644
--- a/lib/usrp/usrp.cpp
+++ b/lib/usrp/usrp.cpp
@@ -16,6 +16,7 @@
//
#include <uhd/usrp/usrp.hpp>
+#include <uhd/usrp/mboard/usrp2.hpp>
#include <uhd/usrp/mboard/test.hpp>
#include <uhd/utils.hpp>
#include <boost/format.hpp>
@@ -32,22 +33,28 @@ static void send_raw_default(const std::vector<boost::asio::const_buffer> &){
throw std::runtime_error("No callback registered for send raw");
}
-static boost::asio::const_buffer recv_raw_default(void){
+static uhd::shared_iovec recv_raw_default(void){
throw std::runtime_error("No callback registered for recv raw");
}
/***********************************************************************
* the usrp device wrapper
**********************************************************************/
-usrp::usrp(const device_addr_t & device_addr){
+usrp::usrp(const device_addr_t &device_addr){
//set the default callbacks, the code below should replace them
_send_raw_cb = boost::bind(&send_raw_default, _1);
_recv_raw_cb = boost::bind(&recv_raw_default);
//create mboard based on the device addr
- if (device_addr.type == DEVICE_ADDR_TYPE_VIRTUAL){
+ if (not device_addr.has_key("type")){
+ //TODO nothing
+ }
+ else if (device_addr["type"] == "test"){
_mboards[""] = mboard::base::sptr(new mboard::test(device_addr));
}
+ else if (device_addr["type"] == "udp"){
+ _mboards[""] = mboard::base::sptr(new mboard::usrp2(device_addr));
+ }
}
usrp::~usrp(void){
@@ -87,6 +94,6 @@ void usrp::send_raw(const std::vector<boost::asio::const_buffer> &buffs){
return _send_raw_cb(buffs);
}
-boost::asio::const_buffer usrp::recv_raw(void){
+uhd::shared_iovec usrp::recv_raw(void){
return _recv_raw_cb();
}
diff --git a/test/device_test.cpp b/test/device_test.cpp
index a868cf9f6..6373ff41b 100644
--- a/test/device_test.cpp
+++ b/test/device_test.cpp
@@ -21,10 +21,9 @@
using namespace uhd;
BOOST_AUTO_TEST_CASE(test_device){
- device_addr_t device_addr(DEVICE_ADDR_TYPE_VIRTUAL);
- device_addr.virtual_args.num_dboards = 2;
- device_addr.virtual_args.num_rx_dsps = 3;
- device_addr.virtual_args.num_tx_dsps = 4;
+ device_addr_t device_addr;
+ device_addr["type"] = "test";
+ device_addr["num_dboards"] = "2";
device::sptr dev = device::make(device_addr);
std::cout << "Access the device" << std::endl;
@@ -34,11 +33,11 @@ BOOST_AUTO_TEST_CASE(test_device){
wax::obj mb0 = (*dev)[DEVICE_PROP_MBOARD];
std::cout << wax::cast<std::string>(mb0[MBOARD_PROP_NAME]) << std::endl;
BOOST_CHECK_EQUAL(
- device_addr.virtual_args.num_dboards,
+ 2,
wax::cast<prop_names_t>(mb0[MBOARD_PROP_RX_DBOARD_NAMES]).size()
);
BOOST_CHECK_EQUAL(
- device_addr.virtual_args.num_dboards,
+ 2,
wax::cast<prop_names_t>(mb0[MBOARD_PROP_TX_DBOARD_NAMES]).size()
);