diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | Makefile.common | 2 | ||||
-rw-r--r-- | apps/.gitignore | 3 | ||||
-rw-r--r-- | apps/Makefile.am | 31 | ||||
-rw-r--r-- | apps/discover_usrps.cpp | 62 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | include/usrp_uhd/device_addr.hpp | 13 | ||||
-rw-r--r-- | include/usrp_uhd/usrp/mboard/Makefile.am | 3 | ||||
-rw-r--r-- | include/usrp_uhd/usrp/mboard/usrp2.hpp | 53 | ||||
-rw-r--r-- | lib/device.cpp | 5 | ||||
-rw-r--r-- | lib/device_addr.cpp | 18 | ||||
-rw-r--r-- | lib/usrp/mboard/Makefile.am | 5 | ||||
-rw-r--r-- | lib/usrp/mboard/usrp2.cpp | 113 | ||||
-rw-r--r-- | lib/usrp/mboard/usrp2_fw_common.h | 55 | ||||
-rw-r--r-- | test/Makefile.am | 4 | ||||
-rw-r--r-- | test/addr_test.cpp | 9 |
16 files changed, 335 insertions, 46 deletions
diff --git a/Makefile.am b/Makefile.am index fb145bf47..a1f915f93 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,7 +17,7 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = include lib test +SUBDIRS = include lib test apps ######################################################################## ## Handle the pkgconfig file generation diff --git a/Makefile.common b/Makefile.common index 65cbf3695..80ed49f2b 100644 --- a/Makefile.common +++ b/Makefile.common @@ -18,7 +18,9 @@ USRP_UHD_LA = $(abs_top_builddir)/lib/libusrp_uhd.la USRP_UHD_USRP_LA = $(abs_top_builddir)/lib/usrp/lib.la + USRP_UHD_USRP_DBOARD_LA = $(abs_top_builddir)/lib/usrp/dboard/lib.la + USRP_UHD_USRP_MBOARD_LA = $(abs_top_builddir)/lib/usrp/mboard/lib.la GENERAL_CPPFLAGS = \ diff --git a/apps/.gitignore b/apps/.gitignore new file mode 100644 index 000000000..e24022663 --- /dev/null +++ b/apps/.gitignore @@ -0,0 +1,3 @@ +/Makefile +/Makefile.in +discover_usrps diff --git a/apps/Makefile.am b/apps/Makefile.am new file mode 100644 index 000000000..c18b8c8f5 --- /dev/null +++ b/apps/Makefile.am @@ -0,0 +1,31 @@ +# +# 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 $(top_srcdir)/Makefile.common + +SUBDIRS = + +AM_CPPFLAGS = $(GENERAL_CPPFLAGS) + +LDADD = \ + $(GENERAL_LDDFLAGS) \ + $(USRP_UHD_LA) + +noinst_PROGRAMS = discover_usrps + +discover_usrps_SOURCES = discover_usrps.cpp + diff --git a/apps/discover_usrps.cpp b/apps/discover_usrps.cpp new file mode 100644 index 000000000..a8d82e015 --- /dev/null +++ b/apps/discover_usrps.cpp @@ -0,0 +1,62 @@ +// +// 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 <usrp_uhd.hpp> +#include <boost/program_options.hpp> +#include <boost/format.hpp> +#include <iostream> + +namespace po = boost::program_options; +using namespace usrp_uhd; + +int main(int argc, char *argv[]){ + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("ip-addr", po::value<std::string>(), "usrp2 ip address") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")) { + std::cout << boost::format("Discover USRPs %s") % desc << std::endl; + return ~0; + } + + //extract the ip address (not optional for now) + usrp_uhd::device_addr_t device_addr(usrp_uhd::DEVICE_ADDR_TYPE_UDP); + if (vm.count("ip-addr")) { + device_addr.udp_args.addr = vm["ip-addr"].as<std::string>(); + } else { + std::cout << "IP Addess was not set" << std::endl; + return ~0; + } + + //discover the usrps + std::vector<usrp_uhd::device_addr_t> device_addrs = usrp_uhd::device::discover(device_addr); + for (size_t i = 0; i < device_addrs.size(); i++){ + std::cout << "--------------------------------------------------" << std::endl; + std::cout << "-- USRP Device " << i << std::endl; + std::cout << "--------------------------------------------------" << std::endl; + std::cout << device_addrs[i] << std::endl << std::endl; + } + + return 0; +} diff --git a/configure.ac b/configure.ac index f4453278c..64c50c7da 100644 --- a/configure.ac +++ b/configure.ac @@ -77,7 +77,7 @@ AC_DEFUN([UHD_CHECK_HEADER],[ AC_CHECK_HEADER([$1], [], [AC_MSG_ERROR("cannot find header $1")]) ]) -UHD_CHECK_HEADER([arpa/inet.h]) +UHD_CHECK_HEADER([netinet/in.h]) UHD_CHECK_HEADER([netinet/ether.h]) ################################################## @@ -104,6 +104,7 @@ AC_PATH_PROG(PYTHON, python) ################################################## AC_CONFIG_FILES([ \ Makefile \ + apps/Makefile \ include/Makefile \ include/usrp_uhd/Makefile \ include/usrp_uhd/usrp/Makefile \ diff --git a/include/usrp_uhd/device_addr.hpp b/include/usrp_uhd/device_addr.hpp index 412a847a5..011e474df 100644 --- a/include/usrp_uhd/device_addr.hpp +++ b/include/usrp_uhd/device_addr.hpp @@ -21,7 +21,7 @@ #include <string> #include <iostream> #include <netinet/ether.h> -#include <arpa/inet.h> +#include <stdint.h> namespace usrp_uhd{ @@ -36,16 +36,6 @@ namespace usrp_uhd{ }; /*! - * Wrapper for an ipv4 address. - * Provides conversion between string and binary formats. - */ - struct ip_addr_t{ - struct in_addr ip_addr; - ip_addr_t(const std::string &ip_addr_str = "0.0.0.0"); - std::string to_string(void) const; - }; - - /*! * Possible usrp device interface types. */ enum device_addr_type_t{ @@ -103,6 +93,5 @@ namespace usrp_uhd{ //ability to use types with stream operators std::ostream& operator<<(std::ostream &os, const usrp_uhd::device_addr_t &x); std::ostream& operator<<(std::ostream &os, const usrp_uhd::mac_addr_t &x); -std::ostream& operator<<(std::ostream &os, const usrp_uhd::ip_addr_t &x); #endif /* INCLUDED_USRP_UHD_DEVICE_ADDR_HPP */ diff --git a/include/usrp_uhd/usrp/mboard/Makefile.am b/include/usrp_uhd/usrp/mboard/Makefile.am index 558999850..bcc6b832c 100644 --- a/include/usrp_uhd/usrp/mboard/Makefile.am +++ b/include/usrp_uhd/usrp/mboard/Makefile.am @@ -22,4 +22,5 @@ SUBDIRS = this_includedir = $(includedir)/usrp_uhd/usrp/mboard this_include_HEADERS = \ base.hpp \ - test.hpp + test.hpp \ + usrp2.hpp diff --git a/include/usrp_uhd/usrp/mboard/usrp2.hpp b/include/usrp_uhd/usrp/mboard/usrp2.hpp new file mode 100644 index 000000000..ea0083bc4 --- /dev/null +++ b/include/usrp_uhd/usrp/mboard/usrp2.hpp @@ -0,0 +1,53 @@ +// +// 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_USRP_UHD_USRP_MBOARD_USRP2_HPP +#define INCLUDED_USRP_UHD_USRP_MBOARD_USRP2_HPP + +#include <usrp_uhd/usrp/mboard/base.hpp> +#include <usrp_uhd/device_addr.hpp> +#include <usrp_uhd/usrp/dboard/manager.hpp> +#include <map> + +namespace usrp_uhd{ namespace usrp{ namespace mboard{ + +/*! + * The usrp2 mboard class. + */ +class usrp2 : public base{ +public: + /*! + * Discover usrp2 devices over the ethernet. + * This static method will be called by the device::discover. + * \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); + + usrp2(const device_addr_t &); + ~usrp2(void); + +private: + void get(const wax::type &, wax::type &); + void set(const wax::type &, const wax::type &); + + std::map<std::string, dboard::manager::sptr> _dboard_managers; +}; + +}}} //namespace + +#endif /* INCLUDED_USRP_UHD_USRP_MBOARD_USRP2_HPP */ diff --git a/lib/device.cpp b/lib/device.cpp index a314da3a8..5718c71e7 100644 --- a/lib/device.cpp +++ b/lib/device.cpp @@ -16,6 +16,7 @@ // #include <usrp_uhd/usrp/usrp.hpp> +#include <usrp_uhd/usrp/mboard/usrp2.hpp> #include <usrp_uhd/device.hpp> #include <boost/format.hpp> #include <stdexcept> @@ -24,6 +25,10 @@ using namespace usrp_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){ + 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; diff --git a/lib/device_addr.cpp b/lib/device_addr.cpp index 784795444..e11d51580 100644 --- a/lib/device_addr.cpp +++ b/lib/device_addr.cpp @@ -70,24 +70,6 @@ std::ostream& operator<<(std::ostream &os, const usrp_uhd::mac_addr_t &x){ return os; } -//----------------------- u2 ipv4 wrapper ----------------------------// -usrp_uhd::ip_addr_t::ip_addr_t(const std::string &ip_addr_str_){ - std::string ip_addr_str = (ip_addr_str_ == "")? "255.255.255.255" : ip_addr_str_; - int ret = inet_pton(AF_INET, ip_addr_str.c_str(), &ip_addr); - if (ret == 0) throw std::runtime_error("Invalid ip address: " + ip_addr_str); -} - -std::string usrp_uhd::ip_addr_t::to_string(void) const{ - char addr_buf[128]; - inet_ntop(AF_INET, &ip_addr, addr_buf, INET_ADDRSTRLEN); - return std::string(addr_buf); -} - -std::ostream& operator<<(std::ostream &os, const usrp_uhd::ip_addr_t &x){ - os << x.to_string(); - return os; -} - //----------------------- usrp device_addr_t wrapper -------------------------// usrp_uhd::device_addr_t::device_addr_t(device_addr_type_t device_addr_type){ type = device_addr_type; diff --git a/lib/usrp/mboard/Makefile.am b/lib/usrp/mboard/Makefile.am index 33782556d..0cb258e93 100644 --- a/lib/usrp/mboard/Makefile.am +++ b/lib/usrp/mboard/Makefile.am @@ -25,6 +25,9 @@ noinst_LTLIBRARIES = lib.la lib_la_SOURCES = \ base.cpp \ - test.cpp + test.cpp \ + usrp2.cpp lib_la_LIBADD = $(GENERAL_LDDFLAGS) + +noinst_HEADERS = usrp2_fw_common.h diff --git a/lib/usrp/mboard/usrp2.cpp b/lib/usrp/mboard/usrp2.cpp new file mode 100644 index 000000000..7064f1460 --- /dev/null +++ b/lib/usrp/mboard/usrp2.cpp @@ -0,0 +1,113 @@ +// +// 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 <usrp_uhd/usrp/mboard/usrp2.hpp> +#include "usrp2_fw_common.h" +#include <usrp_uhd/device.hpp> +#include <boost/asio.hpp> +#include <boost/thread.hpp> +#include <boost/format.hpp> +#include <boost/utility.hpp> +#include <boost/lexical_cast.hpp> +#include <netinet/in.h> + +using namespace usrp_uhd; +using namespace usrp_uhd::usrp::mboard; +using boost::asio::ip::udp; + +/*********************************************************************** + * Wrapper for the udp transport + **********************************************************************/ +class udp_transport : boost::noncopyable{ +public: + udp_transport(const std::string &addr, const std::string &port, bool bcast = false){ + //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; + + // resolve the address + udp::resolver resolver(_io_service); + udp::resolver::query query(udp::v4(), addr, port); + _receiver_endpoint = *resolver.resolve(query); + + // Create and open the socket + _socket = new udp::socket(_io_service); + _socket->open(udp::v4()); + + if (bcast){ + // Allow broadcasting + boost::asio::socket_base::broadcast option(true); + _socket->set_option(option); + } + + } + + ~udp_transport(void){ + delete _socket; + } + + void send(const device::send_args_t &buffs){ + _socket->send_to(buffs, _receiver_endpoint); + } + + void send(const void *buff, size_t len){ + _socket->send_to(boost::asio::buffer(buff, len), _receiver_endpoint); + } + + void recv(const device::recv_args_t &handler){ + // make sure that bytes are available (crappy timeout 100 ms) + for (size_t i = 0; i < 10; i++){ + if (_socket->available()) break; + boost::this_thread::sleep(boost::posix_time::milliseconds(10)); + } + + // receive the bytes and call the handler + udp::endpoint sender_endpoint; + while (_socket->available()){ + size_t len = _socket->receive_from( + boost::asio::buffer(_recv_buff, sizeof(_recv_buff)), + sender_endpoint + ); + bool done = handler(boost::asio::buffer(_recv_buff, len)); + if (done) return; + } + } + +private: + udp::socket *_socket; + udp::endpoint _receiver_endpoint; + boost::asio::io_service _io_service; + uint8_t _recv_buff[1500]; +}; + +/*********************************************************************** + * Discovery over the udp transport + **********************************************************************/ +std::vector<device_addr_t> usrp2::discover(const device_addr_t &hint){ + std::vector<device_addr_t> usrp2_addrs; + + //create a udp transport to communicate + std::string ctrl_port = boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT); + udp_transport trans(hint.udp_args.addr, ctrl_port, true); + + //send a hello control packet + usrp2_ctrl_data_t data; + data.id = htonl(USRP2_CTRL_ID_HELLO); + trans.send(&data, sizeof(data)); + + //TODO start a thread to listen and sleep for timeout + + return usrp2_addrs; +} diff --git a/lib/usrp/mboard/usrp2_fw_common.h b/lib/usrp/mboard/usrp2_fw_common.h new file mode 100644 index 000000000..eb097c3fe --- /dev/null +++ b/lib/usrp/mboard/usrp2_fw_common.h @@ -0,0 +1,55 @@ +// +// 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_USRP2_FW_COMMON_H +#define INCLUDED_USRP2_FW_COMMON_H + +/*! + * Structs and constants for usrp2 communication. + * This header is shared by the firmware and host code. + * Therefore, this header may only contain valid C code. + */ +#ifdef __cplusplus +extern "C" { +#endif + +// udp ports for the usrp2 communication +// Dynamic and/or private ports: 49152–65535 +#define USRP2_UDP_CTRL_PORT 49152 +#define USRP2_UDP_DATA_PORT 49153 + +typedef enum{ + USRP2_CTRL_ID_HELLO +} usrp2_ctrl_id_t; + +typedef struct{ + uint32_t id; + uint32_t seq; + union data{ + struct discovery_addrs{ + uint32_t ip_addr; + uint8_t mac_addr[6]; + uint8_t _padding[2]; + }; + }; +} usrp2_ctrl_data_t; + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDED_USRP2_FW_COMMON_H */ diff --git a/test/Makefile.am b/test/Makefile.am index a18683045..83214efec 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -21,9 +21,7 @@ SUBDIRS = if HAVE_UNIT_TEST -AM_CPPFLAGS = \ - $(GENERAL_CPPFLAGS) \ - $(CPPUNIT_CFLAGS) +AM_CPPFLAGS = $(GENERAL_CPPFLAGS) LDADD = \ $(GENERAL_LDDFLAGS) \ diff --git a/test/addr_test.cpp b/test/addr_test.cpp index d3e18c714..c5823cc65 100644 --- a/test/addr_test.cpp +++ b/test/addr_test.cpp @@ -26,12 +26,3 @@ BOOST_AUTO_TEST_CASE(test_mac_addr){ std::cout << "Output: " << mac_addr << std::endl; BOOST_CHECK_EQUAL(mac_addr_str, mac_addr.to_string()); } - -BOOST_AUTO_TEST_CASE(test_ip_addr){ - std::cout << "Testing ip addr..." << std::endl; - const std::string ip_addr_str("192.168.1.10"); - usrp_uhd::ip_addr_t ip_addr(ip_addr_str); - std::cout << "Input: " << ip_addr_str << std::endl; - std::cout << "Output: " << ip_addr << std::endl; - BOOST_CHECK_EQUAL(ip_addr_str, ip_addr.to_string()); -} |