summaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
Diffstat (limited to 'host')
-rw-r--r--host/CMakeLists.txt9
-rw-r--r--host/include/uhd/CMakeLists.txt1
-rw-r--r--host/include/uhd/device.hpp33
-rw-r--r--host/include/uhd/metadata.hpp47
-rw-r--r--host/include/uhd/transport/udp.hpp17
-rw-r--r--host/lib/transport/udp.cpp20
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp74
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp4
8 files changed, 184 insertions, 21 deletions
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index 70c04631b..30f4789a3 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -73,6 +73,15 @@ INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
########################################################################
+# Setup Endianess
+########################################################################
+INCLUDE(TestBigEndian)
+TEST_BIG_ENDIAN(HAVE_BIG_ENDIAN)
+IF(HAVE_BIG_ENDIAN)
+ ADD_DEFINITIONS("-DHAVE_BIG_ENDIAN=/* */")
+ENDIF(HAVE_BIG_ENDIAN)
+
+########################################################################
# Create Uninstall Target
########################################################################
CONFIGURE_FILE(
diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt
index 006c54f22..e87f74291 100644
--- a/host/include/uhd/CMakeLists.txt
+++ b/host/include/uhd/CMakeLists.txt
@@ -24,6 +24,7 @@ INSTALL(FILES
device_addr.hpp
dict.hpp
gain_handler.hpp
+ metadata.hpp
props.hpp
shared_iovec.hpp
time_spec.hpp
diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp
index dfbfbd7c0..da58d4f85 100644
--- a/host/include/uhd/device.hpp
+++ b/host/include/uhd/device.hpp
@@ -20,13 +20,12 @@
#include <uhd/device_addr.hpp>
#include <uhd/props.hpp>
+#include <uhd/metadata.hpp>
#include <uhd/wax.hpp>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/asio/buffer.hpp>
-#include <uhd/shared_iovec.hpp>
-#include <vector>
namespace uhd{
@@ -72,9 +71,33 @@ public:
*/
device_addr_t get_device_addr(void);
- //the io interface
- virtual void send_raw(const std::vector<boost::asio::const_buffer> &) = 0;
- virtual uhd::shared_iovec recv_raw(void) = 0;
+ /*!
+ * Send a buffer containing IF data with its metadata.
+ *
+ * \param buff a buffer pointing to some read-only memory
+ * \param metadata data describing the buffer's contents
+ * \param the type of data loaded in the buffer (32fc, 16sc)
+ * \return the number of bytes sent
+ */
+ virtual size_t send(
+ const boost::asio::const_buffer &buff,
+ const metadata_t &metadata,
+ const std::string &type = "32fc"
+ ) = 0;
+
+ /*!
+ * Receive a buffer containing IF data and its metadata.
+ *
+ * \param buff the buffer to fill with IF data
+ * \param metadata data to fill describing the buffer
+ * \param the type of data to fill into the buffer (32fc, 16sc)
+ * \return the number of bytes received
+ */
+ virtual size_t recv(
+ const boost::asio::mutable_buffer &buff,
+ metadata_t &metadata,
+ const std::string &type = "32fc"
+ ) = 0;
};
} //namespace uhd
diff --git a/host/include/uhd/metadata.hpp b/host/include/uhd/metadata.hpp
new file mode 100644
index 000000000..43b91d1b0
--- /dev/null
+++ b/host/include/uhd/metadata.hpp
@@ -0,0 +1,47 @@
+//
+// 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_METADATA_HPP
+#define INCLUDED_UHD_METADATA_HPP
+
+#include <uhd/time_spec.hpp>
+
+namespace uhd{
+
+/*!
+ * Metadata structure for describing the IF data.
+ * Includes stream ID, time specification, and burst flags.
+ * The receive routines will convert IF data headers into metadata.
+ * The send routines will convert the metadata to IF data headers.
+ */
+struct metadata_t{
+ uint32_t stream_id;
+ time_spec_t time_spec;
+ bool start_of_burst;
+ bool end_of_burst;
+
+ metadata_t(void){
+ stream_id = 0;
+ time_spec = time_spec_t();
+ start_of_burst = false;
+ end_of_burst = false;
+ }
+};
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_METADATA_HPP */
diff --git a/host/include/uhd/transport/udp.hpp b/host/include/uhd/transport/udp.hpp
index 554234b43..07d84e62a 100644
--- a/host/include/uhd/transport/udp.hpp
+++ b/host/include/uhd/transport/udp.hpp
@@ -41,18 +41,31 @@ public:
/*!
* Send a vector of buffer (like send_msg).
+ * Blocks until the data is sent.
* \param buffs a vector of asio buffers
+ * \return the number of bytes sent
*/
- virtual void send(const std::vector<boost::asio::const_buffer> &buffs) = 0;
+ virtual size_t send(const std::vector<boost::asio::const_buffer> &buffs) = 0;
/*!
* Send a single buffer.
+ * Blocks until the data is sent.
* \param buff single asio buffer
+ * \return the number of bytes sent
*/
- virtual void send(const boost::asio::const_buffer &buff) = 0;
+ virtual size_t send(const boost::asio::const_buffer &buff) = 0;
+
+ /*!
+ * Receive a buffer. Write into the memory provided.
+ * Returns empty when data is not available.
+ * \param buff a mutable buffer to receive into
+ * \return the number of bytes received.
+ */
+ virtual size_t recv(const boost::asio::mutable_buffer &buff) = 0;
/*!
* Receive a buffer. The memory is managed internally.
+ * Returns zero when data is not available.
* Calling recv will invalidate the buffer of the previous recv.
* \return a shared iovec with allocated memory
*/
diff --git a/host/lib/transport/udp.cpp b/host/lib/transport/udp.cpp
index af60760a5..fca4dd7d6 100644
--- a/host/lib/transport/udp.cpp
+++ b/host/lib/transport/udp.cpp
@@ -17,7 +17,6 @@
#include <uhd/transport/udp.hpp>
#include <boost/format.hpp>
-#include <boost/assign/list_of.hpp>
#include <iostream>
/***********************************************************************
@@ -30,8 +29,9 @@ public:
~udp_impl(void);
//send/recv
- void send(const std::vector<boost::asio::const_buffer> &buffs);
- void send(const boost::asio::const_buffer &buff);
+ size_t send(const std::vector<boost::asio::const_buffer> &buffs);
+ size_t send(const boost::asio::const_buffer &buff);
+ size_t recv(const boost::asio::mutable_buffer &buff);
uhd::shared_iovec recv(void);
private:
@@ -79,13 +79,17 @@ udp_impl::~udp_impl(void){
delete _socket;
}
-void udp_impl::send(const std::vector<boost::asio::const_buffer> &buffs){
- _socket->send_to(buffs, _receiver_endpoint);
+size_t udp_impl::send(const std::vector<boost::asio::const_buffer> &buffs){
+ return _socket->send_to(buffs, _receiver_endpoint);
}
-void udp_impl::send(const boost::asio::const_buffer &buff){
- std::vector<boost::asio::const_buffer> buffs = boost::assign::list_of(buff);
- send(buffs);
+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 boost::asio::mutable_buffer &buff){
+ if (_socket->available() == 0) return 0;
+ return _socket->receive_from(boost::asio::buffer(buff), _sender_endpoint);
}
uhd::shared_iovec udp_impl::recv(void){
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index f44964394..47bf06aff 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -130,6 +130,10 @@ usrp2_impl::usrp2_impl(
//init the tx and rx dboards (do last)
dboard_init();
+ //send a small data packet so the usrp2 knows the udp source port
+ uint32_t zero_data = 0;
+ _data_transport->send(boost::asio::buffer(&zero_data, sizeof(zero_data)));
+
}
usrp2_impl::~usrp2_impl(void){
@@ -204,10 +208,72 @@ void usrp2_impl::set(const wax::obj &, const wax::obj &){
/***********************************************************************
* IO Interface
**********************************************************************/
-void usrp2_impl::send_raw(const std::vector<boost::asio::const_buffer> &){
- return;
+static const float float_scale_factor = pow(2.0, 15);
+
+size_t usrp2_impl::send(
+ const boost::asio::const_buffer &buff,
+ const uhd::metadata_t &metadata,
+ const std::string &type
+){
+ if (type == "fc32"){
+ //extract the buffer elements
+ const float *float_buff = boost::asio::buffer_cast<const float*>(buff);
+ const size_t buff_len = boost::asio::buffer_size(buff)/sizeof(float);
+
+ //convert floats into the shorts buffer
+ int16_t *shorts_buff = new int16_t[buff_len];
+ for (size_t i = 0; i < buff_len; i++){
+ shorts_buff[i] = float_buff[i]*float_scale_factor;
+ }
+
+ //send from a buffer of shorts
+ size_t bytes_sent = send(
+ boost::asio::buffer(shorts_buff, buff_len*sizeof(int16_t)),
+ metadata, "sc16"
+ );
+
+ //cleanup
+ delete [] shorts_buff;
+ return bytes_sent;
+ }
+
+ if (type == "sc16"){
+ throw std::runtime_error("not implemented");
+ }
+
+ throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%s\"") % type));
}
-uhd::shared_iovec usrp2_impl::recv_raw(void){
- throw std::runtime_error("not implemented");
+size_t usrp2_impl::recv(
+ const boost::asio::mutable_buffer &buff,
+ uhd::metadata_t &metadata,
+ const std::string &type
+){
+ if (type == "fc32"){
+ //extract the buffer elements
+ float *float_buff = boost::asio::buffer_cast<float*>(buff);
+ const size_t buff_len = boost::asio::buffer_size(buff)/sizeof(float);
+
+ //receive into a buffer of shorts
+ int16_t *shorts_buff = new int16_t[buff_len];
+ size_t bytes_received = recv(
+ boost::asio::buffer(shorts_buff, buff_len*sizeof(int16_t)),
+ metadata, "sc16"
+ );
+
+ //convert floats into the shorts buffer
+ for (size_t i = 0; i < bytes_received/sizeof(int16_t); i++){
+ float_buff[i] = shorts_buff[i]/float_scale_factor;
+ }
+
+ //cleanup
+ delete [] shorts_buff;
+ return bytes_received;
+ }
+
+ if (type == "sc16"){
+ throw std::runtime_error("not implemented");
+ }
+
+ throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%s\"") % type));
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 2545efd58..2476bcf1d 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -98,8 +98,8 @@ public:
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);
+ size_t send(const boost::asio::const_buffer &, const uhd::metadata_t &, const std::string &);
+ size_t recv(const boost::asio::mutable_buffer &, uhd::metadata_t &, const std::string &);
private:
//udp transports for control and data