summaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-03-02 22:07:17 -0800
committerJosh Blum <josh@joshknows.com>2010-03-02 22:07:17 -0800
commit4efafcc2e20b9a980800a979edf5ea7a493b6462 (patch)
tree49fbf3c6e5b25f31a0de30ecf11ceb19872e590f /host/lib/transport
parent13bd67b4949a91df5e6696e708c935266b14c502 (diff)
downloaduhd-4efafcc2e20b9a980800a979edf5ea7a493b6462.tar.gz
uhd-4efafcc2e20b9a980800a979edf5ea7a493b6462.tar.bz2
uhd-4efafcc2e20b9a980800a979edf5ea7a493b6462.zip
Expanded the UDP api:
We can make simple udp transports for discovery and control. We can support a udp zero copy transport (currently just asio). Reworked the io_impl for usrp2 to work with the zero copy api. So far, all of this untested other than compiling. A cut-down vrt library is in the works to simplify the io impl.
Diffstat (limited to 'host/lib/transport')
-rw-r--r--host/lib/transport/udp.cpp98
-rw-r--r--host/lib/transport/udp_simple.cpp133
-rw-r--r--host/lib/transport/udp_zero_copy_none.cpp117
3 files changed, 250 insertions, 98 deletions
diff --git a/host/lib/transport/udp.cpp b/host/lib/transport/udp.cpp
deleted file mode 100644
index 878f71410..000000000
--- a/host/lib/transport/udp.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// 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/transport/udp.hpp>
-#include <boost/format.hpp>
-#include <iostream>
-
-/***********************************************************************
- * UDP implementation class
- **********************************************************************/
-class udp_impl : public uhd::transport::udp{
-public:
- //structors
- udp_impl(const std::string &addr, const std::string &port, bool bcast);
- ~udp_impl(void);
-
- //send/recv
- size_t send(const std::vector<boost::asio::const_buffer> &buffs);
- size_t send(const boost::asio::const_buffer &buff);
- size_t recv(const std::vector<boost::asio::mutable_buffer> &buffs);
- size_t recv(const boost::asio::mutable_buffer &buff);
-
-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;
-};
-
-/***********************************************************************
- * UDP public make function
- **********************************************************************/
-uhd::transport::udp::sptr uhd::transport::udp::make(
- const std::string &addr,
- const std::string &port,
- bool bcast
-){
- return uhd::transport::udp::sptr(new udp_impl(addr, port, bcast));
-}
-
-/***********************************************************************
- * UDP implementation methods
- **********************************************************************/
-udp_impl::udp_impl(const std::string &addr, const std::string &port, bool bcast){
- //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl;
-
- // resolve the address
- boost::asio::ip::udp::resolver resolver(_io_service);
- boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port);
- _receiver_endpoint = *resolver.resolve(query);
-
- // Create and open the socket
- _socket = new boost::asio::ip::udp::socket(_io_service);
- _socket->open(boost::asio::ip::udp::v4());
-
- if (bcast){
- // Allow broadcasting
- boost::asio::socket_base::broadcast option(true);
- _socket->set_option(option);
- }
-
-}
-
-udp_impl::~udp_impl(void){
- delete _socket;
-}
-
-size_t udp_impl::send(const std::vector<boost::asio::const_buffer> &buffs){
- return _socket->send_to(buffs, _receiver_endpoint);
-}
-
-size_t udp_impl::send(const boost::asio::const_buffer &buff){
- return _socket->send_to(boost::asio::buffer(buff), _receiver_endpoint);
-}
-
-size_t udp_impl::recv(const std::vector<boost::asio::mutable_buffer> &buffs){
- if (_socket->available() == 0) return 0;
- return _socket->receive_from(buffs, _sender_endpoint);
-}
-
-size_t udp_impl::recv(const boost::asio::mutable_buffer &buff){
- if (_socket->available() == 0) return 0;
- return _socket->receive_from(boost::asio::buffer(buff), _sender_endpoint);
-}
diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp
new file mode 100644
index 000000000..491cf59db
--- /dev/null
+++ b/host/lib/transport/udp_simple.cpp
@@ -0,0 +1,133 @@
+//
+// 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/transport/udp_simple.hpp>
+#include <boost/format.hpp>
+#include <iostream>
+
+using namespace uhd::transport;
+
+/***********************************************************************
+ * UDP connected implementation class
+ **********************************************************************/
+class udp_connected_impl : public udp_simple{
+public:
+ //structors
+ udp_connected_impl(const std::string &addr, const std::string &port);
+ ~udp_connected_impl(void);
+
+ //send/recv
+ size_t send(const boost::asio::const_buffer &buff);
+ size_t recv(const boost::asio::mutable_buffer &buff);
+
+private:
+ boost::asio::ip::udp::socket *_socket;
+ boost::asio::io_service _io_service;
+};
+
+udp_connected_impl::udp_connected_impl(const std::string &addr, const std::string &port){
+ //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl;
+
+ // resolve the address
+ boost::asio::ip::udp::resolver resolver(_io_service);
+ boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port);
+ boost::asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query);
+
+ // Create, open, and connect the socket
+ _socket = new boost::asio::ip::udp::socket(_io_service);
+ _socket->open(boost::asio::ip::udp::v4());
+ _socket->connect(receiver_endpoint);
+}
+
+udp_connected_impl::~udp_connected_impl(void){
+ delete _socket;
+}
+
+size_t udp_connected_impl::send(const boost::asio::const_buffer &buff){
+ return _socket->send(boost::asio::buffer(buff));
+}
+
+size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff){
+ if (_socket->available() == 0) return 0;
+ return _socket->receive(boost::asio::buffer(buff));
+}
+
+/***********************************************************************
+ * UDP broadcast implementation class
+ **********************************************************************/
+class udp_broadcast_impl : public udp_simple{
+public:
+ //structors
+ udp_broadcast_impl(const std::string &addr, const std::string &port);
+ ~udp_broadcast_impl(void);
+
+ //send/recv
+ size_t send(const boost::asio::const_buffer &buff);
+ size_t recv(const boost::asio::mutable_buffer &buff);
+
+private:
+ boost::asio::ip::udp::socket *_socket;
+ boost::asio::ip::udp::endpoint _receiver_endpoint;
+ boost::asio::io_service _io_service;
+};
+
+udp_broadcast_impl::udp_broadcast_impl(const std::string &addr, const std::string &port){
+ //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl;
+
+ // resolve the address
+ boost::asio::ip::udp::resolver resolver(_io_service);
+ boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port);
+ _receiver_endpoint = *resolver.resolve(query);
+
+ // Create and open the socket
+ _socket = new boost::asio::ip::udp::socket(_io_service);
+ _socket->open(boost::asio::ip::udp::v4());
+
+ // Allow broadcasting
+ boost::asio::socket_base::broadcast option(true);
+ _socket->set_option(option);
+
+}
+
+udp_broadcast_impl::~udp_broadcast_impl(void){
+ delete _socket;
+}
+
+size_t udp_broadcast_impl::send(const boost::asio::const_buffer &buff){
+ return _socket->send_to(boost::asio::buffer(buff), _receiver_endpoint);
+}
+
+size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff){
+ if (_socket->available() == 0) return 0;
+ boost::asio::ip::udp::endpoint sender_endpoint;
+ return _socket->receive_from(boost::asio::buffer(buff), sender_endpoint);
+}
+
+/***********************************************************************
+ * UDP public make functions
+ **********************************************************************/
+udp_simple::sptr udp_simple::make_connected(
+ const std::string &addr, const std::string &port
+){
+ return sptr(new udp_connected_impl(addr, port));
+}
+
+udp_simple::sptr udp_simple::make_broadcast(
+ const std::string &addr, const std::string &port
+){
+ return sptr(new udp_broadcast_impl(addr, port));
+}
diff --git a/host/lib/transport/udp_zero_copy_none.cpp b/host/lib/transport/udp_zero_copy_none.cpp
new file mode 100644
index 000000000..e95706d94
--- /dev/null
+++ b/host/lib/transport/udp_zero_copy_none.cpp
@@ -0,0 +1,117 @@
+//
+// 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/transport/udp_zero_copy.hpp>
+
+using namespace uhd::transport;
+
+/***********************************************************************
+ * Smart buffer implementation for udp zerocopy none
+ *
+ * This smart buffer implemention houses a const buffer.
+ * When the smart buffer is deleted, the buffer is freed.
+ * The memory in the const buffer is allocated with new [],
+ * and so the destructor frees the buffer with delete [].
+ **********************************************************************/
+class smart_buffer_impl : public smart_buffer{
+public:
+ smart_buffer_impl(const boost::asio::const_buffer &buff){
+ _buff = buff;
+ }
+
+ ~smart_buffer_impl(void){
+ delete [] boost::asio::buffer_cast<const uint32_t *>(_buff);
+ }
+
+ const boost::asio::const_buffer &get(void) const{
+ return _buff;
+ }
+
+private:
+ boost::asio::const_buffer _buff;
+};
+
+/***********************************************************************
+ * UDP zero copy implementation class
+ *
+ * This is the portable zero copy implementation for systems
+ * where a faster, platform specific solution is not available.
+ *
+ * It uses boost asio udp sockets and the standard recv() class,
+ * and in-fact, is not actually doing a zero-copy implementation.
+ **********************************************************************/
+class udp_zero_copy_impl : public udp_zero_copy{
+public:
+ //structors
+ udp_zero_copy_impl(const std::string &addr, const std::string &port);
+ ~udp_zero_copy_impl(void);
+
+ //send/recv
+ size_t send(const boost::asio::const_buffer &buff);
+ smart_buffer::sptr recv(void);
+
+private:
+ boost::asio::ip::udp::socket *_socket;
+ boost::asio::io_service _io_service;
+};
+
+udp_zero_copy_impl::udp_zero_copy_impl(const std::string &addr, const std::string &port){
+ //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl;
+
+ // resolve the address
+ boost::asio::ip::udp::resolver resolver(_io_service);
+ boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port);
+ boost::asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query);
+
+ // Create, open, and connect the socket
+ _socket = new boost::asio::ip::udp::socket(_io_service);
+ _socket->open(boost::asio::ip::udp::v4());
+ _socket->connect(receiver_endpoint);
+}
+
+udp_zero_copy_impl::~udp_zero_copy_impl(void){
+ delete _socket;
+}
+
+size_t udp_zero_copy_impl::send(const boost::asio::const_buffer &buff){
+ return _socket->send(boost::asio::buffer(buff));
+}
+
+smart_buffer::sptr udp_zero_copy_impl::recv(void){
+ size_t available = _socket->available();
+
+ //allocate memory and create buffer
+ uint32_t *buff_mem = new uint32_t[available/sizeof(uint32_t)];
+ boost::asio::mutable_buffer buff(buff_mem, available);
+
+ //receive only if data is available
+ if (available > 0){
+ _socket->receive(boost::asio::buffer(buff));
+ }
+
+ //create a new smart buffer to house the data
+ return smart_buffer::sptr(new smart_buffer_impl(buff));
+}
+
+/***********************************************************************
+ * UDP zero copy make function
+ **********************************************************************/
+udp_zero_copy::sptr udp_zero_copy::make(
+ const std::string &addr, const std::string &port
+){
+ return sptr(new udp_zero_copy_impl(addr, port));
+}