aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-02-12 18:07:55 -0800
committerJosh Blum <josh@joshknows.com>2010-02-12 18:07:55 -0800
commit9fff25f4e5da179ea29ff44278e0415a337870cb (patch)
treecfbee4cf2921fd4bd415e3af1c1d466f79bab3d7 /lib
parent350f5c5decca20a54132867283448fd32226bbc2 (diff)
downloaduhd-9fff25f4e5da179ea29ff44278e0415a337870cb.tar.gz
uhd-9fff25f4e5da179ea29ff44278e0415a337870cb.tar.bz2
uhd-9fff25f4e5da179ea29ff44278e0415a337870cb.zip
Added a templated dictionary class because its more useful than map.
Made the device addrs into a string:string dict. If its all strings we dont have to change the top level caller for new product. Created shared_iovec class to manage memory for device recvs. Work on the bro/dude control protocol for usrp2.
Diffstat (limited to 'lib')
-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
9 files changed, 147 insertions, 95 deletions
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();
}