summaryrefslogtreecommitdiff
path: root/usrp2/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'usrp2/host/lib')
-rw-r--r--usrp2/host/lib/.gitignore5
-rw-r--r--usrp2/host/lib/Makefile.am66
-rw-r--r--usrp2/host/lib/control.cc68
-rw-r--r--usrp2/host/lib/control.h179
-rw-r--r--usrp2/host/lib/copiers.cc133
-rw-r--r--usrp2/host/lib/copy_handler.cc60
-rw-r--r--usrp2/host/lib/data_handler.cc32
-rw-r--r--usrp2/host/lib/eth_buffer.cc279
-rw-r--r--usrp2/host/lib/eth_buffer.h198
-rw-r--r--usrp2/host/lib/eth_common.h38
-rw-r--r--usrp2/host/lib/ethernet.cc230
-rw-r--r--usrp2/host/lib/ethernet.h124
-rw-r--r--usrp2/host/lib/find.cc182
-rw-r--r--usrp2/host/lib/open_usrp2_socket.cc130
-rw-r--r--usrp2/host/lib/open_usrp2_socket.h34
-rw-r--r--usrp2/host/lib/pktfilter.cc187
-rw-r--r--usrp2/host/lib/pktfilter.h64
-rw-r--r--usrp2/host/lib/ring.cc78
-rw-r--r--usrp2/host/lib/ring.h83
-rw-r--r--usrp2/host/lib/rx_nop_handler.cc35
-rw-r--r--usrp2/host/lib/rx_sample_handler.cc27
-rw-r--r--usrp2/host/lib/strtod_si.c53
-rw-r--r--usrp2/host/lib/usrp2.cc504
-rw-r--r--usrp2/host/lib/usrp2_bytesex.h19
-rw-r--r--usrp2/host/lib/usrp2_impl.cc1667
-rw-r--r--usrp2/host/lib/usrp2_impl.h210
-rw-r--r--usrp2/host/lib/usrp2_socket_opener.cc143
27 files changed, 0 insertions, 4828 deletions
diff --git a/usrp2/host/lib/.gitignore b/usrp2/host/lib/.gitignore
deleted file mode 100644
index 8f5500b33f..0000000000
--- a/usrp2/host/lib/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-/.libs
-/.deps
-/Makefile
-/Makefile.in
-/usrp2_socket_opener
diff --git a/usrp2/host/lib/Makefile.am b/usrp2/host/lib/Makefile.am
deleted file mode 100644
index 85bec46736..0000000000
--- a/usrp2/host/lib/Makefile.am
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# Copyright 2007,2008,2010 Free Software Foundation, Inc.
-#
-# 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
-
-AM_CPPFLAGS = \
- $(USRP2_INCLUDES) \
- $(GRUEL_INCLUDES) \
- $(STD_DEFINES_AND_INCLUDES) \
- $(BOOST_CPPFLAGS) \
- $(CPPUNIT_INCLUDES)
-
-bin_PROGRAMS = usrp2_socket_opener
-usrp2_socket_opener_SOURCES = usrp2_socket_opener.cc
-
-lib_LTLIBRARIES = \
- libusrp2.la
-
-libusrp2_la_LDFLAGS = $(LTVERSIONFLAGS)
-
-libusrp2_la_SOURCES = \
- control.cc \
- copiers.cc \
- copy_handler.cc \
- data_handler.cc \
- eth_buffer.cc \
- ethernet.cc \
- find.cc \
- open_usrp2_socket.cc \
- pktfilter.cc \
- ring.cc \
- rx_nop_handler.cc \
- rx_sample_handler.cc \
- strtod_si.c \
- usrp2.cc \
- usrp2_impl.cc
-
-libusrp2_la_LIBADD = \
- $(GRUEL_LA) \
- $(BOOST_LDFLAGS) $(BOOST_THREAD_LIB)
-
-# Private headers not needed for above the API development
-noinst_HEADERS = \
- control.h \
- eth_buffer.h \
- eth_common.h \
- ethernet.h \
- open_usrp2_socket.h \
- pktfilter.h \
- ring.h \
- usrp2_bytesex.h \
- usrp2_impl.h \ No newline at end of file
diff --git a/usrp2/host/lib/control.cc b/usrp2/host/lib/control.cc
deleted file mode 100644
index 3b5533eb80..0000000000
--- a/usrp2/host/lib/control.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2009,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "control.h"
-#include <iostream>
-#include <gruel/thread.h>
-
-#include <boost/date_time/posix_time/posix_time.hpp>
-namespace pt = boost::posix_time;
-
-namespace usrp2 {
-
- pending_reply::pending_reply(unsigned int rid, void *buffer, size_t len)
- : d_rid(rid), d_buffer(buffer), d_len(len), d_mutex(), d_cond(),
- d_complete(false)
- {
- }
-
- pending_reply::~pending_reply()
- {
- notify_completion(); // Needed?
- }
-
- int
- pending_reply::wait_for_completion(double secs)
- {
- gruel::scoped_lock l(d_mutex);
-
- while (!d_complete) {
- if (!d_cond.timed_wait(l, pt::milliseconds(long(secs*1e3))))
- return 0; // timed out
- }
-
- return 1;
- }
-
- void
- pending_reply::notify_completion()
- {
- gruel::scoped_lock l(d_mutex);
- d_complete = true;
- d_cond.notify_one();
- }
-
-} // namespace usrp2
-
diff --git a/usrp2/host/lib/control.h b/usrp2/host/lib/control.h
deleted file mode 100644
index 3515ba10fe..0000000000
--- a/usrp2/host/lib/control.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2009,2010 Free Software Foundation, Inc.
- *
- * 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_CONTROL_H
-#define INCLUDED_CONTROL_H
-
-#include <gruel/thread.h>
-#include <usrp2_eth_packet.h>
-
-namespace usrp2 {
-
- struct op_generic_cmd {
- u2_eth_packet_t h;
- op_generic_t op;
- op_generic_t eop;
- };
-
- /*!
- * OP_CONFIG_RX_V2 command packet
- */
- struct op_config_rx_v2_cmd
- {
- u2_eth_packet_t h;
- op_config_rx_v2_t op;
- op_generic_t eop;
- };
-
- struct op_start_rx_streaming_cmd
- {
- u2_eth_packet_t h;
- op_start_rx_streaming_t op;
- op_generic_t eop;
- };
-
- struct op_sync_and_start_rx_streaming_cmd
- {
- u2_eth_packet_t h;
- op_generic_t sync_op;
- op_start_rx_streaming_t rx_op;
- op_generic_t eop;
- };
-
- struct op_stop_rx_cmd {
- u2_eth_packet_t h;
- op_generic_t op;
- op_generic_t eop;
- };
-
- struct op_config_tx_v2_cmd
- {
- u2_eth_packet_t h;
- op_config_tx_v2_t op;
- op_generic_t eop;
- };
-
- struct op_config_mimo_cmd
- {
- u2_eth_packet_t h;
- op_config_mimo_t op;
- op_generic_t eop;
- };
-
- struct op_burn_mac_addr_cmd
- {
- u2_eth_packet_t h;
- op_burn_mac_addr_t op;
- op_generic_t eop;
- };
-
- struct op_dboard_info_cmd {
- u2_eth_packet_t h;
- op_generic_t op;
- op_generic_t eop;
- };
-
- struct op_peek_cmd {
- u2_eth_packet_t h;
- op_peek_t op;
- op_generic_t eop;
- };
-
- struct op_poke_cmd {
- u2_eth_packet_t h;
- op_poke_t op;
- // words to write go here
- // eop must be dynamically written here
- };
-
- struct op_freq_cmd {
- u2_eth_packet_t h;
- op_freq_t op;
- op_generic_t eop;
- };
-
- struct op_gpio_cmd {
- u2_eth_packet_t h;
- op_gpio_t op;
- op_generic_t eop;
- };
-
- struct op_gpio_set_sels_cmd {
- u2_eth_packet_t h;
- op_gpio_set_sels_t op;
- op_generic_t eop;
- };
-
- /*!
- * Control mechanism to allow API calls to block waiting for reply packets
- */
- class pending_reply
- {
- private:
- unsigned int d_rid;
- void *d_buffer;
- size_t d_len;
-
- // d_mutex is used with d_cond and also protects d_complete
- gruel::mutex d_mutex;
- gruel::condition_variable d_cond;
- bool d_complete;
-
- public:
- /*!
- * Construct a pending reply from the reply ID, response packet
- * buffer, and buffer length.
- */
- pending_reply(unsigned int rid, void *buffer, size_t len);
-
- /*!
- * Destructor. Signals creating thread.
- */
- ~pending_reply();
-
- /*!
- * Block, waiting for reply packet.
- * Returns: 1 = ok, reply packet in buffer
- * 0 = timeout
- */
- int wait_for_completion(double secs);
-
- /*!
- * Allows creating thread to resume after copying reply into buffer
- */
- void notify_completion();
-
- /*!
- * Retrieve pending reply ID
- */
- unsigned int rid() const { return d_rid; }
-
- /*!
- * Retrieve destination buffer address
- */
- void *buffer() const { return d_buffer; }
-
- /*!
- * Retrieve destination buffer length
- */
- size_t len() const { return d_len; }
- };
-
-} // namespace usrp2
-
-#endif /* INCLUDED_CONTROL_H */
diff --git a/usrp2/host/lib/copiers.cc b/usrp2/host/lib/copiers.cc
deleted file mode 100644
index 52c66f6161..0000000000
--- a/usrp2/host/lib/copiers.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <usrp2/copiers.h>
-#include <gruel/inet.h>
-#include <gr_math.h>
-#include <math.h>
-#include <stdexcept>
-#include <assert.h>
-#include <string.h>
-
-// FIXME need gruel::not_implemented
-
-namespace usrp2 {
-
- /*
- * N.B., in all of these, uint32_t *items is NOT 32-bit aligned!
- * FIXME Needs fix for non-x86 machines.
- */
-
- /*
- * ----------------------------------------------------------------
- * Copy and convert from USRP2 wire format to host format
- * ----------------------------------------------------------------
- */
- void
- copy_u2_16sc_to_host_16sc(size_t nitems,
- const uint32_t *items,
- std::complex<int16_t> *host_items)
- {
-#ifdef WORDS_BIGENDIAN
-
- assert(sizeof(items[0]) == sizeof(host_items[0]));
- memcpy(host_items, items, nitems * sizeof(items[0]));
-
-#else
-
- // FIXME SIMD welcome here
-
- for (size_t i = 0; i < nitems; i++){
- uint32_t t = ntohx(items[i]);
- //printf("%9d\n", items[i]);
- host_items[i] = std::complex<int16_t>((t >> 16), t & 0xffff);
- }
-
-#endif
- }
-
-
- /*
- * endian swap if required and map [-32768, 32767] -> [1.0, +1.0)
- */
- void
- copy_u2_16sc_to_host_32fc(size_t nitems,
- const uint32_t *items,
- std::complex<float> *host_items)
- {
- for (size_t i = 0; i < nitems; i++){
- uint32_t t = ntohx(items[i]);
- int16_t re = (t >> 16) & 0xffff;
- int16_t im = (t & 0xffff);
- host_items[i] = std::complex<float>(re * 1.0/32768, im * 1.0/32768);
- }
- }
-
- /*
- * ----------------------------------------------------------------
- * Copy and convert from host format to USRP2 wire format
- * ----------------------------------------------------------------
- */
- void
- copy_host_16sc_to_u2_16sc(size_t nitems,
- const std::complex<int16_t> *host_items,
- uint32_t *items)
- {
-#ifdef WORDS_BIGENDIAN
-
- assert(sizeof(items[0]) == sizeof(host_items[0]));
- memcpy(items, host_items, nitems * sizeof(items[0]));
-
-#else
-
- // FIXME SIMD welcome here
-
- for (size_t i = 0; i < nitems; i++){
- items[i] = htonl((host_items[i].real() << 16) | (host_items[i].imag() & 0xffff));
- }
-
-#endif
- }
-
-
- static inline int16_t
- clip_and_scale(float x)
- {
- return static_cast<int16_t>(rintf(gr_branchless_clip(x, 1.0) * 32767.0));
- }
-
- void
- copy_host_32fc_to_u2_16sc(size_t nitems,
- const std::complex<float> *host_items,
- uint32_t *items)
- {
- for (size_t i = 0; i < nitems; i++){
- int16_t re = clip_and_scale(host_items[i].real());
- int16_t im = clip_and_scale(host_items[i].imag());
-
- items[i] = htonl((re << 16) | (im & 0xffff));
- }
- }
-
-}
diff --git a/usrp2/host/lib/copy_handler.cc b/usrp2/host/lib/copy_handler.cc
deleted file mode 100644
index 92759084bf..0000000000
--- a/usrp2/host/lib/copy_handler.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <usrp2/copy_handler.h>
-#include <iostream>
-#include <string.h>
-
-namespace usrp2 {
-
- copy_handler::copy_handler(void *dest, size_t len)
- : d_dest((uint8_t *)dest), d_space(len), d_bytes(0), d_times(0)
- {
- }
-
- copy_handler::~copy_handler()
- {
- // NOP
- }
-
- data_handler::result
- copy_handler::operator()(const void *base, size_t len)
- {
- if (len > d_space)
- return KEEP|DONE; // can't do anything, retry later
-
- memcpy(&d_dest[d_bytes], base, len);
- d_space -= len;
- d_bytes += len;
- d_times++;
-
- if (d_space < MIN_COPY_LEN)
- return DONE; // don't call me anymore
-
- return 0;
- }
-
-} // namespace usrp2
-
diff --git a/usrp2/host/lib/data_handler.cc b/usrp2/host/lib/data_handler.cc
deleted file mode 100644
index ba91236816..0000000000
--- a/usrp2/host/lib/data_handler.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <usrp2/data_handler.h>
-
-namespace usrp2 {
-
- data_handler::~data_handler()
- {
- // default nop destructor
- }
-
-}
-
diff --git a/usrp2/host/lib/eth_buffer.cc b/usrp2/host/lib/eth_buffer.cc
deleted file mode 100644
index e8ca05283c..0000000000
--- a/usrp2/host/lib/eth_buffer.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2009 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "eth_buffer.h"
-#include "ethernet.h"
-#include <usrp2/data_handler.h>
-#include <linux/if_packet.h>
-#include <sys/socket.h>
-#include <sys/mman.h>
-#include <sys/poll.h>
-#include <iostream>
-#include <cmath>
-#include <errno.h>
-#include <stdexcept>
-#include <string.h>
-#include <cstdio>
-
-
-#define ETH_BUFFER_DEBUG 0 // define to 0 or 1
-#if ETH_BUFFER_DEBUG
-#define DEBUG_LOG(x) ::write(2, (x), 1)
-#else
-#define DEBUG_LOG(X)
-#endif
-
-#define DEFAULT_MEM_SIZE 25e6 // ~0.25s @ 100 MB/s
-#define MAX_MEM_SIZE 1000e6 // ~10.00s @ 100 MB/s.
-#define MAX_SLAB_SIZE 131072 // 128 KB (FIXME fish out of /proc/slabinfo)
-#define MAX_PKT_SIZE 1512 // we don't do jumbo frames
-
-namespace usrp2 {
-
- eth_buffer::eth_buffer(size_t rx_bufsize)
- : d_fd(0), d_using_tpring(false), d_buflen(0), d_buf(0), d_frame_nr(0),
- d_frame_size(0), d_head(0), d_ring(0), d_ethernet(new ethernet())
- {
- if (rx_bufsize == 0)
- d_buflen = (size_t)DEFAULT_MEM_SIZE;
- else
- d_buflen = std::min((size_t)MAX_MEM_SIZE, rx_bufsize);
-
- memset(d_mac, 0, sizeof(d_mac));
- }
-
- eth_buffer::~eth_buffer()
- {
- close();
- }
-
- bool
- eth_buffer::open(const std::string &ifname, int protocol)
- {
- if (!d_ethernet->open(ifname, protocol)) {
- std::cerr << "eth_buffer: unable to open interface "
- << ifname << std::endl;
- return false;
- }
-
- d_fd = d_ethernet->fd();
- memcpy(d_mac, d_ethernet->mac(), sizeof(d_mac));
-
- struct tpacket_req req;
- size_t page_size = getpagesize();
-
- // Calculate minimum power-of-two aligned size for frames
- req.tp_frame_size =
- (unsigned int)rint(pow(2, ceil(log2(TPACKET_ALIGN(TPACKET_HDRLEN)+TPACKET_ALIGN(MAX_PKT_SIZE)))));
- d_frame_size = req.tp_frame_size;
-
- // Calculate minimum contiguous pages needed to enclose a frame
- int npages = (page_size > req.tp_frame_size) ? 1 : ((req.tp_frame_size+page_size-1)/page_size);
- req.tp_block_size = page_size << (int)ceil(log2(npages));
-
- // Calculate number of blocks
- req.tp_block_nr = (int)(d_buflen/req.tp_block_size);
-
-
- // Recalculate buffer length
- d_buflen = req.tp_block_nr*req.tp_block_size;
-
- // Finally, calculate total number of frames. Since frames, blocks,
- // and pages are all power-of-two aligned, frames are contiguous
- req.tp_frame_nr = d_buflen/req.tp_frame_size;
- d_frame_nr = req.tp_frame_nr;
-
-#if 0
- if (ETH_BUFFER_DEBUG)
- std::cerr << "eth_buffer:"
- << " frame_size=" << req.tp_frame_size
- << " block_size=" << req.tp_block_size
- << " block_nr=" << req.tp_block_nr
- << " frame_nr=" << req.tp_frame_nr
- << " buflen=" << d_buflen
- << std::endl;
-#endif
-
- // Try to get kernel shared memory buffer
- if (setsockopt(d_fd, SOL_PACKET, PACKET_RX_RING, (void *)&req, sizeof(req))) {
- perror("eth_buffer: setsockopt");
- d_using_tpring = false;
- if (!(d_buf = (uint8_t *)malloc(d_buflen))) {
- std::cerr << "eth_buffer: failed to allocate packet memory" << std::endl;
- return false;
- }
-
- std::cerr << "eth_buffer: using malloc'd memory for buffer" << std::endl;
- }
- else {
- d_using_tpring = true;
- void *p = mmap(0, d_buflen, PROT_READ|PROT_WRITE, MAP_SHARED, d_fd, 0);
- if (p == MAP_FAILED){
- perror("eth_buffer: mmap");
- return false;
- }
- d_buf = (uint8_t *) p;
-
- if (ETH_BUFFER_DEBUG)
- std::cerr << "eth_buffer: using kernel shared mem for buffer" << std::endl;
- }
-
- // Initialize our pointers into the packet ring
- d_ring = std::vector<uint8_t *>(req.tp_frame_nr);
- for (unsigned int i=0; i < req.tp_frame_nr; i++) {
- d_ring[i] = (uint8_t *)(d_buf+i*req.tp_frame_size);
- }
-
- // If not using kernel ring, instantiate select/read thread here
-
- return true;
- }
-
- bool
- eth_buffer::close()
- {
- // if we have background thread, stop it here
-
- if(d_buf) {
- if (!d_using_tpring)
- free(d_buf);
- else
- munmap(d_buf, d_buflen);
- }
-
- return d_ethernet->close();
- }
-
- bool
- eth_buffer::attach_pktfilter(pktfilter *pf)
- {
- return d_ethernet->attach_pktfilter(pf);
- }
-
- inline bool
- eth_buffer::frame_available()
- {
- return (((tpacket_hdr *)d_ring[d_head])->tp_status != TP_STATUS_KERNEL);
- }
-
- eth_buffer::result
- eth_buffer::rx_frames(data_handler *f, int timeout_in_ms)
- {
- DEBUG_LOG("\n");
-
- while (!frame_available()) {
- if (timeout_in_ms == 0) {
- DEBUG_LOG("w");
- return EB_WOULD_BLOCK;
- }
-
- struct pollfd pfd;
- pfd.fd = d_fd;
- pfd.revents = 0;
- pfd.events = POLLIN;
-
- DEBUG_LOG("P");
-
- int pres = poll(&pfd, 1, timeout_in_ms);
- if (pres == -1) {
- perror("poll");
- return EB_ERROR;
- }
-
- if (pres == 0) {
- DEBUG_LOG("t");
- return EB_TIMED_OUT;
- }
- }
-
- // Iterate through available packets
- while (frame_available()) {
- // Get start of ethernet frame and length
- tpacket_hdr *hdr = (tpacket_hdr *)d_ring[d_head];
- void *base = (uint8_t *)hdr+hdr->tp_mac;
- size_t len = hdr->tp_len;
-
- // FYI, (base % 4 == 2) Not what we want given the current FPGA
- // code. This means that our uint32_t samples are not 4-byte
- // aligned. We'll have to deal with it downstream.
-
- if (0)
- fprintf(stderr, "eth_buffer: base = %p tp_mac = %3d tp_net = %3d\n",
- base, hdr->tp_mac, hdr->tp_net);
-
- // Invoke data handler
- data_handler::result r = (*f)(base, len);
- if (!(r & data_handler::KEEP))
- hdr->tp_status = TP_STATUS_KERNEL; // mark it free
-
- inc_head();
-
- if (r & data_handler::DONE)
- break;
- }
-
- DEBUG_LOG("|");
- return EB_OK;
- }
-
- eth_buffer::result
- eth_buffer::tx_frame(const void *base, size_t len, int flags)
- {
- DEBUG_LOG("T");
-
- if (flags & EF_DONTWAIT) // FIXME: implement flags
- throw std::runtime_error("tx_frame: EF_DONTWAIT not implemented");
-
- int res = d_ethernet->write_packet(base, len);
- if (res < 0 || (unsigned int)res != len)
- return EB_ERROR;
-
- return EB_OK;
- }
-
- eth_buffer::result
- eth_buffer::tx_framev(const eth_iovec *iov, int iovcnt, int flags)
- {
- DEBUG_LOG("T");
-
- if (flags & EF_DONTWAIT) // FIXME: implement flags
- throw std::runtime_error("tx_frame: EF_DONTWAIT not implemented");
-
- int res = d_ethernet->write_packetv(iov, iovcnt);
- if (res < 0)
- return EB_ERROR;
-
- return EB_OK;
- }
-
- void
- eth_buffer::release_frame(void *base)
- {
- // Get d_frame_size aligned header
- tpacket_hdr *hdr = (tpacket_hdr *)((intptr_t)base & ~(d_frame_size-1));
- hdr->tp_status = TP_STATUS_KERNEL; // mark it free
- }
-
-} // namespace usrp2
diff --git a/usrp2/host/lib/eth_buffer.h b/usrp2/host/lib/eth_buffer.h
deleted file mode 100644
index 8dee9a4a25..0000000000
--- a/usrp2/host/lib/eth_buffer.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef INCLUDED_USRP2_ETH_BUFFER_H
-#define INCLUDED_USRP2_ETH_BUFFER_H
-
-#include "pktfilter.h"
-#include <eth_common.h>
-#include <boost/utility.hpp>
-#include <vector>
-#include <memory>
-#include <stdint.h>
-
-namespace usrp2 {
-
- class ethernet;
- class data_handler;
-
- /*!
- * \brief high-performance interface to send and receive raw
- * ethernet frames with out-of-order retirement of received frames.
- *
- * On many systems it should be possible to implement this on top of libpcap
- *
- * \internal
- */
- class eth_buffer : boost::noncopyable
- {
-
- int d_fd; // socket file descriptor
- uint8_t d_mac[6]; // our mac address
- bool d_using_tpring; // using kernel mapped packet ring
- size_t d_buflen; // length of our buffer
- uint8_t *d_buf; // packet ring
- unsigned int d_frame_nr; // max frames on ring
- size_t d_frame_size; // frame storage size
- unsigned int d_head; // pointer to next frame
-
- std::vector<uint8_t *> d_ring; // pointers into buffer
- std::auto_ptr<ethernet> d_ethernet; // our underlying interface
-
- bool frame_available();
-
- void inc_head()
- {
- if (d_head + 1 >= d_frame_nr)
- d_head = 0;
- else
- d_head = d_head + 1;
- }
-
-
- public:
-
- enum result {
- EB_OK, //< everything's fine
- EB_ERROR, //< A non-recoverable error occurred
- EB_WOULD_BLOCK, //< A timeout of 0 was specified and nothing was ready
- EB_TIMED_OUT, //< The timeout expired before anything was ready
- };
-
- static const unsigned int MAX_PKTLEN = 1512;
- static const unsigned int MIN_PKTLEN = 64;
-
- /*!
- * \param rx_bufsize is a hint as to the number of bytes of memory
- * to allocate for received ethernet frames (0 -> reasonable default)
- */
- eth_buffer(size_t rx_bufsize = 0);
- ~eth_buffer();
-
- /*!
- * \brief open the specified interface
- *
- * \param ifname ethernet interface name, e.g., "eth0"
- * \param protocol is the ethertype protocol number in network order.
- * Use 0 to receive all protocols.
- */
- bool open(const std::string &ifname, int protocol);
-
- /*!
- * \brief close the interface
- */
- bool close();
-
- /*!
- * \brief attach packet filter to socket to restrict which packets read sees.
- * \param pf the packet filter
- */
- bool attach_pktfilter(pktfilter *pf);
-
- /*!
- * \brief return 6 byte string containing our MAC address
- */
- const uint8_t *mac() const { return d_mac; }
-
- /*!
- * \brief Call \p f for each frame in the receive buffer.
- * \param f is the frame data handler
- * \param timeout (in ms) controls behavior when there are no frames to read
- *
- * If \p timeout is 0, rx_frames will not wait for frames if none are
- * available, and f will not be invoked. If \p timeout is -1 (the
- * default), rx_frames will block indefinitely until frames are
- * available. If \p timeout is positive, it indicates the number of
- * milliseconds to wait for a frame to become available. Once the
- * timeout has expired, rx_frames will return, f never having been
- * invoked.
- *
- * \p f will be called on each ethernet frame that is available.
- * \p f returns a bit mask with one of the following set or cleared:
- *
- * data_handler::KEEP - hold onto the frame and present it again during
- * the next call to rx_frames, otherwise discard it
- *
- * data_handler::DONE - return from rx_frames now even though more frames
- * might be available; otherwise continue if more
- * frames are ready.
- *
- * The idea of holding onto a frame for the next iteration allows
- * the caller to scan the received packet stream for particular
- * classes of frames (such as command replies) leaving the rest
- * intact. On the next call all kept frames, followed by any new
- * frames received, will be presented in order to \p f.
- * See usrp2.cc for an example of the pattern.
- *
- * \returns EB_OK if at least one frame was received
- * \returns EB_WOULD_BLOCK if \p timeout is 0 and the call would have blocked
- * \returns EB_TIMED_OUT if timeout occurred
- * \returns EB_ERROR if there was an unrecoverable error.
- */
- result rx_frames(data_handler *f, int timeout=-1);
-
- /*
- * \brief Release frame from buffer
- *
- * Call to release a frame previously held by a data_handler::KEEP.
- * The pointer may be offset from the base of the frame up to its length.
- */
- void release_frame(void *p);
-
- /*
- * \brief Write an ethernet frame to the interface.
- *
- * \param base points to the beginning of the frame (the 14-byte ethernet header).
- * \param len is the length of the frame in bytes.
- * \param flags is 0 or the bitwise-or of values from eth_flags
- *
- * The frame must begin with a 14-byte ethernet header.
- *
- * \returns EB_OK if the frame was successfully enqueued.
- * \returns EB_WOULD_BLOCK if flags contains EF_DONT_WAIT and the call would have blocked.
- * \returns EB_ERROR if there was an unrecoverable error.
- */
- result tx_frame(const void *base, size_t len, int flags=0);
-
- /*
- * \brief Write an ethernet frame to the interface using scatter/gather.
- *
- * \param iov points to an array of iovec structs
- * \param iovcnt is the number of entries
- * \param flags is 0 or the bitwise-or of values from eth_flags
- *
- * The frame must begin with a 14-byte ethernet header.
- *
- * \returns EB_OK if the frame was successfully enqueued.
- * \returns EB_WOULD_BLOCK if flags contains EF_DONT_WAIT and the call would have blocked.
- * \returns EB_ERROR if there was an unrecoverable error.
- */
- result tx_framev(const eth_iovec *iov, int iovcnt, int flags=0);
-
- /*
- * \brief Returns maximum possible number of frames in buffer
- */
- unsigned int max_frames() const { return d_frame_nr; }
-
- };
-
-}; // namespace usrp2
-
-#endif /* INCLUDED_USRP2_ETH_BUFFER_H */
diff --git a/usrp2/host/lib/eth_common.h b/usrp2/host/lib/eth_common.h
deleted file mode 100644
index 7c9feaa25b..0000000000
--- a/usrp2/host/lib/eth_common.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef INCLUDED_USRP2_ETH_COMMON_H
-#define INCLUDED_USRP2_ETH_COMMON_H
-
-#include <sys/uio.h> // FIXME autoconf this
-
-namespace usrp2 {
-
- enum eth_flags {
- EF_DONTWAIT = 0x0001,
- };
-
- typedef struct iovec eth_iovec; // FIXME autoconf this
-
-} // namespace usrp2
-
-
-#endif /* INCLUDED_USRP2_ETH_COMMON_H */
diff --git a/usrp2/host/lib/ethernet.cc b/usrp2/host/lib/ethernet.cc
deleted file mode 100644
index e51680b2e5..0000000000
--- a/usrp2/host/lib/ethernet.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,2007,2008 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "eth_buffer.h"
-#include "ethernet.h"
-#include "pktfilter.h"
-#include <open_usrp2_socket.h>
-
-#include <cstdio>
-#include <iostream>
-#include <unistd.h>
-#include <fcntl.h>
-//#include <features.h>
-#include <errno.h>
-#include <string.h>
-#include <net/if.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <net/ethernet.h>
-#include <netinet/in.h>
-
-#include <linux/types.h>
-#include <netpacket/packet.h>
-#include <linux/filter.h> // packet filter
-
-namespace usrp2 {
-
- static int
- open_packet_socket (std::string ifname, int protocol)
- {
-#if 0
- if (protocol == 0)
- protocol = htons(ETH_P_ALL);
-
- int fd = socket (PF_PACKET, SOCK_RAW, protocol);
-#else
- int fd = usrp2::open_usrp2_socket();
-#endif
-
- if (fd == -1){
- fprintf (stderr, "%s: socket: %s\n", ifname.c_str(), strerror (errno));
- return -1;
- }
-
- // get interface index
- struct ifreq ifr;
- memset (&ifr, 0, sizeof(ifr));
- strncpy (ifr.ifr_name, ifname.c_str(), sizeof (ifr.ifr_name));
- int res = ioctl (fd, SIOCGIFINDEX, &ifr);
- if (res != 0){
- ::close (fd);
- fprintf (stderr, "%s: SIOCGIFINDEX: %s\n", ifname.c_str(), strerror(errno));
- return -1;
- }
- int ifindex = ifr.ifr_ifindex;
-
- // bind to the specified interface
- sockaddr_ll sa;
- memset (&sa, 0, sizeof (sa));
- sa.sll_family = AF_PACKET;
- sa.sll_protocol = protocol;
- sa.sll_ifindex = ifindex;
- res = bind (fd, (struct sockaddr *)&sa, sizeof (sa));
- if (res != 0){
- ::close (fd);
- fprintf (stderr, "%s: bind: %s\n", ifname.c_str(), strerror(errno));
- return -1;
- }
- return fd;
- }
-
- static void
- extract_mac_addr (unsigned char *mac, const unsigned char *hwaddr)
- {
- int i;
- for (i = 0; i < 6; i++)
- mac[i] = 0xff;
-
- i = 0;
- for (int j = 0; j < 14; j++){
- if (hwaddr[j] != 0xff){
- mac[i++] = hwaddr[j];
- if (i == 6)
- return;
- }
- }
- }
-
- static bool
- get_mac_addr (std::string ifname, int fd, unsigned char *mac)
- {
- struct ifreq ifr;
- memset (&ifr, 0, sizeof(ifr));
- strncpy (ifr.ifr_name, ifname.c_str(), sizeof (ifr.ifr_name));
- int res = ioctl (fd, SIOCGIFHWADDR, &ifr);
- if (res != 0){
- fprintf (stderr, "%s: SIOCGIFHWADDR: %s\n", ifname.c_str(), strerror(errno));
- return false;
- }
- else {
- if (0){
- for (unsigned i = 0; i < sizeof (ifr.ifr_hwaddr.sa_data); i++)
- fprintf (stderr, "%02x", ifr.ifr_hwaddr.sa_data[i]);
- fprintf (stderr, "\n");
- }
- }
- extract_mac_addr (mac, (unsigned char *)ifr.ifr_hwaddr.sa_data);
- return true;
- }
-
- ethernet::ethernet ()
- {
- d_fd = -1;
- memset (d_mac, 0, sizeof (d_mac));
- }
-
- ethernet::~ethernet ()
- {
- close ();
- }
-
- bool
- ethernet::open (std::string ifname, int protocol)
- {
- if (d_fd != -1){
- fprintf (stderr, "ethernet: already open\n");
- return false;
- }
- if ((d_fd = open_packet_socket (ifname, protocol)) == -1){
- return false;
- }
- get_mac_addr (ifname, d_fd, d_mac);
- return true;
- }
-
- bool
- ethernet::close ()
- {
- if (d_fd >= 0){
- ::close (d_fd);
- d_fd = -1;
- }
- return true;
- }
-
- int
- ethernet::read_packet (void *buf, int buflen)
- {
- int len = recvfrom (d_fd, buf, buflen, 0, (sockaddr *) 0, 0);
- return len;
- }
-
- int
- ethernet::read_packet_dont_block (void *buf, int buflen)
- {
- int len = recvfrom (d_fd, buf, buflen, MSG_DONTWAIT, 0, 0);
- if (len == -1 && errno == EAGAIN)
- return 0;
-
- return len;
- }
-
- int
- ethernet::write_packet (const void *buf, int buflen)
- {
- int retval = send (d_fd, buf, buflen, 0);
- if (retval < 0){
- if (errno == EINTR)
- return write_packet (buf, buflen);
-
- perror ("ethernet:write_packet: send");
- return -1;
- }
- return retval;
- }
-
- int
- ethernet::write_packetv(const eth_iovec *iov, size_t iovlen)
- {
- struct msghdr mh;
- memset(&mh, 0, sizeof(mh));
- mh.msg_iov = const_cast<eth_iovec*>(iov);
- mh.msg_iovlen = iovlen;
-
- int retval = sendmsg(d_fd, &mh, 0);
- if (retval < 0){
- if (errno == EINTR)
- return write_packetv(iov, iovlen);
-
- perror("ethernet:write_packetv: send");
- return -1;
- }
- return retval;
- }
-
- bool
- ethernet::attach_pktfilter (pktfilter *pf)
- {
- struct sock_fprog filter;
- filter.len = pf->d_len;
- filter.filter = pf->d_inst;
-
- int r = setsockopt (d_fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof (filter));
- if (r < 0){
- perror ("ethernet:attach: SO_ATTACH_FILTER");
- return false;
- }
- return true;
- }
-
-} // namespace usrp2
diff --git a/usrp2/host/lib/ethernet.h b/usrp2/host/lib/ethernet.h
deleted file mode 100644
index 24624f441a..0000000000
--- a/usrp2/host/lib/ethernet.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,2007,2008 Free Software Foundation, Inc.
- *
- * 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_ETHERNET_H
-#define INCLUDED_USRP2_ETHERNET_H
-
-#include <string>
-#include <vector>
-#include <eth_common.h>
-
-namespace usrp2 {
-
- class pktfilter;
-
- /*!
- * \brief Read and write ethernet frames.
- *
- * This provides a low level interface to hardware that communicates
- * via raw (non-IP) ethernet frames.
- */
- class ethernet {
- int d_fd;
- uint8_t d_mac[6];
-
- public:
- ethernet ();
- ~ethernet ();
-
- static const int MAX_PKTLEN = 1512;
- static const int MIN_PKTLEN = 64;
-
- /*!
- * \param ifname ethernet interface name, e.g., "eth0"
- * \param protocol is the ethertype protocol number in network order.
- * Use 0 to receive all protocols.
- */
- bool open (std::string ifname, int protocol);
-
- bool close ();
-
- /*!
- * \brief attach packet filter to socket to restrict which packets read sees.
- * \param pf the packet filter
- */
- bool attach_pktfilter (pktfilter *pf);
-
- /*!
- * \brief return 6 byte string containing our MAC address
- */
- const uint8_t *mac () const { return d_mac; }
-
- /*!
- * \brief Return file descriptor associated with socket.
- */
- int fd () const { return d_fd; }
-
- /*!
- * \brief Read packet from interface.
- *
- * \param buf where to put the packet
- * \param buflen maximum length of packet in bytes (should be >= 1528)
- *
- * \returns number of bytes read or -1 if trouble.
- *
- * Returned packet includes 14-byte ethhdr
- */
- int read_packet (void *buf, int buflen);
-
- /*!
- * \brief Read packet from interface, but don't block waiting
- *
- * \param buf where to put the packet
- * \param buflen maximum length of packet in bytes (should be >= 1528)
- *
- * \returns number of bytes read, -1 if trouble or 0 if nothing available.
- *
- * Returned packet includes 14-byte ethhdr
- */
- int read_packet_dont_block (void *buf, int buflen);
-
- /*
- * \brief Write ethernet packet to interface.
- *
- * \param buf the packet to write
- * \param buflen length of packet in bytes
- *
- * \returns number of bytes written or -1 if trouble.
- *
- * Packet must begin with 14-byte ethhdr, but does not include the FCS.
- */
- int write_packet (const void *buf, int buflen);
-
- /*
- * \brief Write ethernet packet to interface.
- *
- * \param iov scatter/gather array
- * \param iovlen number of elements in iov
- *
- * \returns number of bytes written or -1 if trouble.
- *
- * Packet must begin with 14-byte ethhdr, but does not include the FCS.
- */
- int write_packetv (const eth_iovec *iov, size_t iovlen);
-
- };
-
-} // namespace usrp2
-
-#endif /* INCLUDED_USRP2_ETHERNET_H */
diff --git a/usrp2/host/lib/find.cc b/usrp2/host/lib/find.cc
deleted file mode 100644
index d1df47fc5c..0000000000
--- a/usrp2/host/lib/find.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <usrp2_eth_packet.h>
-#include <usrp2/usrp2.h>
-#include <boost/scoped_ptr.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include "ethernet.h"
-#include "pktfilter.h"
-#include <string.h>
-#include <iostream>
-#include <stdexcept>
-#include <cstdio>
-
-#define FIND_DEBUG 0
-
-
-// FIXME move to gruel
-
-static struct timeval
-time_duration_to_timeval(boost::posix_time::time_duration delta)
-{
- long total_us = delta.total_microseconds();
- if (total_us < 0)
- throw std::invalid_argument("duration_to_time: delta is negative");
-
- struct timeval tv;
- tv.tv_sec = total_us / 1000000;
- tv.tv_usec = total_us % 1000000;
- return tv;
-}
-
-
-namespace usrp2 {
-
- static props
- reply_to_props(const op_id_reply_t *r)
- {
- const uint8_t *mac = (const uint8_t *)&r->addr;
- char addr_buf[128];
- snprintf(addr_buf, sizeof(addr_buf), "%02x:%02x:%02x:%02x:%02x:%02x",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-
- props p;
- p.addr = std::string(addr_buf);
- p.hw_rev = ntohs(r->hw_rev);
- memcpy(p.fpga_md5sum, r->fpga_md5sum, sizeof(p.fpga_md5sum));
- memcpy(p.sw_md5sum, r->sw_md5sum, sizeof(p.sw_md5sum));
- return p;
- }
-
- static void
- read_replies(ethernet *enet, struct timeval timeout,
- const std::string &target_addr, props_vector_t &result)
- {
- struct reply {
- u2_eth_packet_t h;
- op_id_reply_t op_id_reply;
- };
-
- uint8_t pktbuf[ethernet::MAX_PKTLEN];
- memset(pktbuf, 0, sizeof(pktbuf));
-
- fd_set read_fds;
- FD_ZERO(&read_fds);
- FD_SET(enet->fd(), &read_fds);
-
- select(enet->fd()+1, &read_fds, 0, 0, &timeout);
- while(1) {
- memset(pktbuf, 0, sizeof(pktbuf));
- int len = enet->read_packet_dont_block(pktbuf, sizeof(pktbuf));
- if (len < 0){
- perror("usrp2_basic: read_packet_dont_block");
- return;
- }
- if (len == 0)
- break;
-
- reply *rp = (reply *)pktbuf;
- if (u2p_chan(&rp->h.fixed) != CONTROL_CHAN) // ignore
- continue;
- if (rp->op_id_reply.opcode != OP_ID_REPLY) // ignore
- continue;
-
- props p = reply_to_props(&rp->op_id_reply);
- if (FIND_DEBUG)
- std::cerr << "usrp2::find: response from " << p.addr << std::endl;
-
- if ((target_addr == "") || (target_addr == p.addr))
- result.push_back(p);
- }
- }
-
- props_vector_t
- find(const std::string &ifc, const std::string &addr)
- {
- if (FIND_DEBUG) {
- std::cerr << "usrp2::find: Searching interface " << ifc << " for "
- << (addr == "" ? "all USRP2s" : addr)
- << std::endl;
- }
-
- props_vector_t result;
- struct command {
- u2_eth_packet_t h;
- op_generic_t op_id;
- };
-
- std::auto_ptr<ethernet> enet(new ethernet());
-
- if (!enet->open(ifc, htons(U2_ETHERTYPE)))
- return result;
-
- std::auto_ptr<pktfilter> pf(pktfilter::make_ethertype_inbound(U2_ETHERTYPE, enet->mac()));
- if (!enet->attach_pktfilter(pf.get()))
- return result;
-
- static u2_mac_addr_t broadcast_mac_addr =
- {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }};
-
- uint8_t pktbuf[ethernet::MAX_PKTLEN];
- memset(pktbuf, 0, sizeof(pktbuf));
-
- command *c = (command *)pktbuf;
- c->h.ehdr.ethertype = htons(U2_ETHERTYPE);
- c->h.ehdr.dst = broadcast_mac_addr;
- memcpy(&c->h.ehdr.src, enet->mac(), 6);
- c->h.thdr.flags = 0;
- c->h.thdr.seqno = 0;
- c->h.thdr.ack = 0;
- u2p_set_word0(&c->h.fixed, 0, CONTROL_CHAN);
- u2p_set_timestamp(&c->h.fixed, -1);
- c->op_id.opcode = OP_ID;
- c->op_id.len = sizeof(c->op_id);
- int len = std::max((size_t) ethernet::MIN_PKTLEN, sizeof(command));
- if (enet->write_packet(c, len) != len)
- return result;
-
- if (FIND_DEBUG)
- std::cerr << "usrp2::find: broadcast ID command" << std::endl;
-
- /*
- * Gather all responses that occur within 50ms
- */
- boost::posix_time::ptime start(boost::posix_time::microsec_clock::universal_time());
- boost::posix_time::ptime limit(start + boost::posix_time::milliseconds(50));
- boost::posix_time::ptime now;
-
- while (1){
- now = boost::posix_time::microsec_clock::universal_time();
- if (now >= limit)
- break;
-
- boost::posix_time::time_duration delta(limit - now);
- struct timeval timeout = time_duration_to_timeval(delta);
-
- read_replies(enet.get(), timeout, addr, result);
- }
- return result;
- }
-
-} // namespace usrp2
-
diff --git a/usrp2/host/lib/open_usrp2_socket.cc b/usrp2/host/lib/open_usrp2_socket.cc
deleted file mode 100644
index cd729205da..0000000000
--- a/usrp2/host/lib/open_usrp2_socket.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <open_usrp2_socket.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string>
-
-static const char *helper = "usrp2_socket_opener";
-
-static ssize_t
-read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
-{
- struct msghdr msg;
- struct iovec iov[1];
- ssize_t n;
-
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- union {
- struct cmsghdr cm;
- char control[CMSG_SPACE(sizeof (int))];
- } control_un;
- struct cmsghdr *cmptr;
-
- msg.msg_control = control_un.control;
- msg.msg_controllen = sizeof(control_un.control);
-#else
- int newfd;
-
- msg.msg_accrights = (char *) &newfd;
- msg.msg_accrightslen = sizeof(int);
-#endif
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
-
- iov[0].iov_base = ptr;
- iov[0].iov_len = nbytes;
- msg.msg_iov = iov;
- msg.msg_iovlen = 1;
-
- if ((n = recvmsg(fd, &msg, 0)) <= 0)
- return n;
-
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL
- && cmptr->cmsg_len == CMSG_LEN(sizeof(int))){
- if (cmptr->cmsg_level != SOL_SOCKET){
- fprintf(stderr, "read_fd: control level != SOL_SOCKET\n");
- return -1;
- }
- if (cmptr->cmsg_type != SCM_RIGHTS){
- fprintf(stderr, "read_fd: control type != SCM_RIGHTS\n");
- return -1;
- }
- *recvfd = *((int *) CMSG_DATA(cmptr));
- } else
- *recvfd = -1; /* descriptor was not passed */
-#else
- if (msg.msg_accrightslen == sizeof(int))
- *recvfd = newfd;
- else
- *recvfd = -1; /* descriptor was not passed */
-#endif
-
- return n;
-}
-
-int
-usrp2::open_usrp2_socket()
-{
- int fd = -1, sockfd[2], status;
- pid_t childpid;
- char c, argsockfd[10];
-
- if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd) != 0){
- perror("socketpair");
- return -1;
- }
-
- if ((childpid = fork()) == 0) { /* child process */
- close(sockfd[0]);
- snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]);
- execlp(helper, helper, argsockfd, (char *) NULL);
- std::string msg("execlp: couldn't exec " + std::string(helper));
- perror(msg.c_str());
- close(sockfd[0]);
- close(sockfd[1]);
- return -1;
- }
-
- /* parent process - wait for the child to terminate */
- close(sockfd[1]); /* close the end we don't use */
-
- waitpid(childpid, &status, 0);
- if (!WIFEXITED(status)){
- fprintf(stderr, "child did not terminate\n");
- return -1;
- }
- if ((status = WEXITSTATUS(status)) == 0)
- read_fd(sockfd[0], &c, 1, &fd);
- else {
- errno = status; /* bogus: set errno value from child's status */
- fd = -1;
- }
-
- close(sockfd[0]);
- return (fd);
-}
diff --git a/usrp2/host/lib/open_usrp2_socket.h b/usrp2/host/lib/open_usrp2_socket.h
deleted file mode 100644
index d42440ea0a..0000000000
--- a/usrp2/host/lib/open_usrp2_socket.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * 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_OPEN_USRP2_SOCKET_H
-#define INCLUDED_OPEN_USRP2_SOCKET_H
-
-namespace usrp2 {
-
- /*!
- * Return the result of executing:
- *
- * int fd = socket(PF_PACKET, SOCK_RAW, htons(0xBEEF));
- *
- * Doing it in a way that we don't need to be running as root.
- */
- int open_usrp2_socket();
-};
-
-
-#endif /* INCLUDED_OPEN_USRP2_SOCKET_H */
diff --git a/usrp2/host/lib/pktfilter.cc b/usrp2/host/lib/pktfilter.cc
deleted file mode 100644
index 1ccf904465..0000000000
--- a/usrp2/host/lib/pktfilter.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,2007,2008 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "pktfilter.h"
-#include <iostream>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <features.h>
-#include <netpacket/packet.h>
-#include <net/ethernet.h>
-#include <netinet/in.h>
-#include <assert.h>
-#include <linux/types.h>
-#include <linux/filter.h> // packet filter
-
-namespace usrp2 {
-
- /*
- * This is all based on the Berkeley Packet Filter (BPF) as implemented on Linux.
- *
- * The BPF allows you to run an interpreted program (a filter) in the
- * kernel that sorts through the packets looking for ones you are
- * interested in. This eliminates the overhead of passing all of the
- * networking packets up into user space for filtering there.
- *
- * For documentation on this see
- * /usr/src/linux/Documentation/networking/filter.txt, The BSD
- * Berkeley Packet Filter manual page, and "The BSD Packet Filter: A
- * New Architecture for User-level Packet Capture", by Steven McCanne
- * and Van Jacobson.
- */
-
- pktfilter::pktfilter ()
- : d_len (0), d_inst (0)
- {
- // NOP
- }
-
- pktfilter::~pktfilter ()
- {
- delete [] d_inst;
- }
-
- inline static sock_filter
- make_stmt (__u16 code, __u32 k)
- {
- sock_filter f;
- f.code = code;
- f.jt = 0;
- f.jf = 0;
- f.k = k;
- return f;
- }
-
- inline static sock_filter
- make_jump (__u16 code, __u32 k, __u8 jt, __u8 jf)
- {
- sock_filter f;
- f.code = code;
- f.jt = jt;
- f.jf = jf;
- f.k = k;
- return f;
- }
-
- /*
- * Return a filter that harvests packets with the specified ethertype.
- */
- pktfilter *
- pktfilter::make_ethertype (unsigned short ethertype)
- {
- static const int MAX_LEN = 20;
- sock_filter *inst = new sock_filter [MAX_LEN];
- pktfilter *pf = new pktfilter ();
-
- // nothing quite like coding in assembly without the benefit of an assembler ;-)
-
- // ignore packets that don't have the right ethertype
-
- int i = 0;
- inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12); // load ethertype
- inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 1, 0);
- inst[i++] = make_stmt (BPF_RET|BPF_K, 0); // return 0 (ignore packet)
- inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1); // return whole packet
-
- assert (i <= MAX_LEN);
-
- pf->d_inst = inst;
- pf->d_len = i;
-
- return pf;
- }
-
- /*
- * Return a filter that harvests inbound packets with the specified ethertype.
- * \param ethertype the ethertype we're looking for
- * \param our_mac our ethernet MAC address so we can avoid pkts we sent
- */
- pktfilter *
- pktfilter::make_ethertype_inbound (unsigned short ethertype, const unsigned char *our_mac)
- {
- static const int MAX_LEN = 20;
- sock_filter *inst = new sock_filter [MAX_LEN];
- pktfilter *pf = new pktfilter ();
-
- __u16 smac_hi = (our_mac[0] << 8) | our_mac[1];
- __u32 smac_lo = (our_mac[2] << 24) | (our_mac[3] << 16) | (our_mac[4] << 8) | our_mac[5];
-
- // nothing quite like coding in assembly without the benefit of an assembler ;-)
-
- // ignore packets that have a different ethertype
- // and packets that have a source mac address == our_mac (packets we sent)
-
- int i = 0;
- inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12); // load ethertype
- inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 0, 5);
- inst[i++] = make_stmt (BPF_LD|BPF_W|BPF_ABS, 8); // load low 32-bit of src mac
- inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, smac_lo, 0, 2);
- inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 6); // load high 16-bits of src mac
- inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, smac_hi, 1, 0);
- inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1); // return whole packet
- inst[i++] = make_stmt (BPF_RET|BPF_K, 0); // return 0 (ignore packet)
-
- assert (i <= MAX_LEN);
-
- pf->d_inst = inst;
- pf->d_len = i;
-
- return pf;
- }
- /*
- * Return a filter that harvests inbound packets with the specified ethertype and target USRP2 MAC address.
- * \param ethertype the ethertype we're looking for
- * \param usrp_mac our target USRP2 MAC address
- */
- pktfilter *
- pktfilter::make_ethertype_inbound_target (unsigned short ethertype, const unsigned char *usrp_mac)
- {
- static const int MAX_LEN = 20;
- sock_filter *inst = new sock_filter [MAX_LEN];
- pktfilter *pf = new pktfilter ();
-
- __u16 tmac_hi = (usrp_mac[0] << 8) | usrp_mac[1];
- __u32 tmac_lo = (usrp_mac[2] << 24) | (usrp_mac[3] << 16) | (usrp_mac[4] << 8) | usrp_mac[5];
-
- // ignore packets that have a different ethertype
- // and only return packets that have a source mac address == usrp_mac
-
- int i = 0;
- inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 12); // load ethertype
- inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, ethertype, 0, 5);
- inst[i++] = make_stmt (BPF_LD|BPF_W|BPF_ABS, 8); // load low 32-bit of src mac
- inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, tmac_lo, 0, 3);
- inst[i++] = make_stmt (BPF_LD|BPF_H|BPF_ABS, 6); // load high 16-bits of src mac
- inst[i++] = make_jump (BPF_JMP|BPF_JEQ|BPF_K, tmac_hi, 0, 1);
- inst[i++] = make_stmt (BPF_RET|BPF_K, (unsigned) -1); // return whole packet
- inst[i++] = make_stmt (BPF_RET|BPF_K, 0); // return 0 (ignore packet)
-
- assert (i <= MAX_LEN);
-
- pf->d_inst = inst;
- pf->d_len = i;
-
- return pf;
- }
-
-} // namespace usrp2
diff --git a/usrp2/host/lib/pktfilter.h b/usrp2/host/lib/pktfilter.h
deleted file mode 100644
index 09937ae34e..0000000000
--- a/usrp2/host/lib/pktfilter.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,2007,2008 Free Software Foundation, Inc.
- *
- * 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_PKTFILTER_H
-#define INCLUDED_USRP2_PKTFILTER_H
-
-struct sock_filter;
-
-namespace usrp2 {
-
- /*
- * \brief Compile programs for the Berkeley Packet Filter
- */
- class pktfilter {
- public:
-
- unsigned d_len; // # of instructions
- struct sock_filter *d_inst; // the instructions
-
- pktfilter ();
- ~pktfilter ();
-
- /*!
- * \brief Return a filter that harvests packets with the specified ethertype.
- * \param ethertype the ethertype we're looking for.
- */
- static pktfilter *make_ethertype (unsigned short ethertype);
-
- /*!
- * \brief Return a filter that harvests inbound packets with the specified ethertype.
- * \param ethertype the ethertype we're looking for
- * \param our_mac our MAC address so we can avoid pkts we sent
- */
- static pktfilter *make_ethertype_inbound (unsigned short ethertype,
- const unsigned char *our_mac);
-
- /*!
- * \brief Return a filter that harvests inbound packets with the specified ethertype
- * and source MAC address
- * \param ethertype the ethertype we're looking for
- * \param usrp_mac the source MAC address
- */
- static pktfilter *make_ethertype_inbound_target (unsigned short ethertype,
- const unsigned char *usrp_mac);
- };
-
-} // namespace usrp2
-
-#endif /* INCLUDED_USRP2_PKTFILTER_H */
diff --git a/usrp2/host/lib/ring.cc b/usrp2/host/lib/ring.cc
deleted file mode 100644
index d0048418cf..0000000000
--- a/usrp2/host/lib/ring.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ring.h"
-
-namespace usrp2 {
-
- ring::ring(unsigned int entries)
- : d_max(entries), d_read_ind(0), d_write_ind(0), d_ring(entries),
- d_mutex(), d_not_empty()
- {
- for (unsigned int i = 0; i < entries; i++) {
- d_ring[i].d_base = 0;
- d_ring[i].d_len = 0;
- }
- }
-
- void
- ring::wait_for_not_empty()
- {
- gruel::scoped_lock l(d_mutex);
- while (empty())
- d_not_empty.wait(l);
- }
-
- bool
- ring::enqueue(void *p, size_t len)
- {
- gruel::scoped_lock l(d_mutex);
- if (full())
- return false;
-
- d_ring[d_write_ind].d_len = len;
- d_ring[d_write_ind].d_base = p;
-
- inc_write_ind();
- d_not_empty.notify_one();
- return true;
- }
-
- bool
- ring::dequeue(void **p, size_t *len)
- {
- gruel::scoped_lock l(d_mutex);
- if (empty())
- return false;
-
- *p = d_ring[d_read_ind].d_base;
- *len = d_ring[d_read_ind].d_len;
-
- inc_read_ind();
- return true;
- }
-
-} // namespace usrp2
-
diff --git a/usrp2/host/lib/ring.h b/usrp2/host/lib/ring.h
deleted file mode 100644
index fd0ad0a9f3..0000000000
--- a/usrp2/host/lib/ring.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2010 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef INCLUDED_RING_H
-#define INCLUDED_RING_H
-
-#include <stddef.h>
-#include <vector>
-#include <boost/shared_ptr.hpp>
-#include <gruel/thread.h>
-
-namespace usrp2 {
-
- class ring;
- typedef boost::shared_ptr<ring> ring_sptr;
-
- class ring
- {
- private:
-
- size_t d_max;
- size_t d_read_ind;
- size_t d_write_ind;
-
- struct ring_desc
- {
- void *d_base;
- size_t d_len;
- };
- std::vector<ring_desc> d_ring;
-
- gruel::mutex d_mutex;
- gruel::condition_variable d_not_empty;
-
- void inc_read_ind()
- {
- if (d_read_ind + 1 >= d_max)
- d_read_ind = 0;
- else
- d_read_ind = d_read_ind + 1;
- }
-
- void inc_write_ind()
- {
- if (d_write_ind + 1 >= d_max)
- d_write_ind = 0;
- else
- d_write_ind = d_write_ind + 1;
- }
-
- bool empty() const { return d_read_ind == d_write_ind; }
- bool full() const { return (d_write_ind+1)%d_max == d_read_ind; }
-
- public:
-
- ring(unsigned int entries);
-
- void wait_for_not_empty();
-
- bool enqueue(void *p, size_t len);
- bool dequeue(void **p, size_t *len);
- };
-
-} // namespace usrp2
-
-#endif /* INCLUDED_RING_H */
diff --git a/usrp2/host/lib/rx_nop_handler.cc b/usrp2/host/lib/rx_nop_handler.cc
deleted file mode 100644
index 96c9164a52..0000000000
--- a/usrp2/host/lib/rx_nop_handler.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio 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, or (at your option)
- * any later version.
- *
- * GNU Radio 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <usrp2/rx_nop_handler.h>
-
-namespace usrp2 {
-
- rx_nop_handler::~rx_nop_handler()
- {
- }
-
-} // namespace usrp2
-
diff --git a/usrp2/host/lib/rx_sample_handler.cc b/usrp2/host/lib/rx_sample_handler.cc
deleted file mode 100644
index 4521025cb6..0000000000
--- a/usrp2/host/lib/rx_sample_handler.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <usrp2/rx_sample_handler.h>
-
-usrp2::rx_sample_handler::~rx_sample_handler()
-{
- // nop
-}
diff --git a/usrp2/host/lib/strtod_si.c b/usrp2/host/lib/strtod_si.c
deleted file mode 100644
index 5e5deb2b6d..0000000000
--- a/usrp2/host/lib/strtod_si.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 Free Software Foundation, Inc.
- *
- * 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 <usrp2/strtod_si.h>
-#include <stdlib.h>
-
-#define true 1
-#define false 0
-
-int
-strtod_si(const char *s, double *result)
-{
- *result = 0;
-
- char *endptr;
- double r = strtod(s, &endptr);
- if (s == endptr)
- return false;
-
- switch (*endptr){
- case 'p': r *= 1e-12; break;
- case 'n': r *= 1e-9; break;
- case 'u': r *= 1e-6; break;
- case 'm': r *= 1e-3; break;
- case 'k': r *= 1e3; break;
- case 'M': r *= 1e6; break;
- case 'G': r *= 1e9; break;
- case 'T': r *= 1e12; break;
- default:
- // ignore. FIXME could be more robust
- break;
- }
-
- *result = r;
- return true;
-}
-
-
diff --git a/usrp2/host/lib/usrp2.cc b/usrp2/host/lib/usrp2.cc
deleted file mode 100644
index 0842482e40..0000000000
--- a/usrp2/host/lib/usrp2.cc
+++ /dev/null
@@ -1,504 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2009 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <usrp2/usrp2.h>
-#include "usrp2_impl.h"
-#include <vector>
-#include <boost/thread.hpp>
-#include <boost/weak_ptr.hpp>
-#include <string>
-#include <stdexcept>
-#include <cstdio>
-
-namespace usrp2 {
-
- // --- Table of weak pointers to usrps we know about ---
-
- // (Could be cleaned up and turned into a template)
-
- struct usrp_table_entry {
- // inteface + normalized mac addr ("eth0:01:23:45:67:89:ab")
- std::string key;
- boost::weak_ptr<usrp2> value;
-
- usrp_table_entry(const std::string &_key, boost::weak_ptr<usrp2> _value)
- : key(_key), value(_value) {}
- };
-
- typedef std::vector<usrp_table_entry> usrp_table;
-
- static boost::mutex s_table_mutex;
- static usrp_table s_table;
-
- usrp2::sptr
- usrp2::find_existing_or_make_new(const std::string &ifc, props *pr, size_t rx_bufsize)
- {
- std::string key = ifc + ":" + pr->addr;
-
- boost::mutex::scoped_lock guard(s_table_mutex);
-
- for (usrp_table::iterator p = s_table.begin(); p != s_table.end();){
- if (p->value.expired()) // weak pointer is now dead
- p = s_table.erase(p); // erase it
- else {
- if (key == p->key) // found it
- return usrp2::sptr(p->value);
- else
- ++p; // keep looking
- }
- }
-
- // We don't have the USRP2 we're looking for
-
- // create a new one and stick it in the table.
- usrp2::sptr r(new usrp2(ifc, pr, rx_bufsize));
- usrp_table_entry t(key, r);
- s_table.push_back(t);
-
- return r;
- }
-
- // --- end of table code ---
-
- static bool
- parse_mac_addr(const std::string &s, std::string &ns)
- {
- u2_mac_addr_t p;
-
- p.addr[0] = 0x00; // Matt's IAB
- p.addr[1] = 0x50;
- p.addr[2] = 0xC2;
- p.addr[3] = 0x85;
- p.addr[4] = 0x30;
- p.addr[5] = 0x00;
-
- int len = s.size();
- switch (len) {
-
- case 5:
- if (sscanf(s.c_str(), "%hhx:%hhx", &p.addr[4], &p.addr[5]) != 2)
- return false;
- break;
-
- case 17:
- if (sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
- &p.addr[0], &p.addr[1], &p.addr[2],
- &p.addr[3], &p.addr[4], &p.addr[5]) != 6)
- return false;
- break;
-
- default:
- return false;
- }
-
- char buf[128];
- snprintf(buf, sizeof(buf),
- "%02x:%02x:%02x:%02x:%02x:%02x",
- p.addr[0],p.addr[1],p.addr[2],
- p.addr[3],p.addr[4],p.addr[5]);
- ns = std::string(buf);
- return true;
- }
-
- usrp2::sptr
- usrp2::make(const std::string &ifc, const std::string &addr, size_t rx_bufsize)
- {
- std::string naddr = "";
- if (addr != "" && !parse_mac_addr(addr, naddr))
- throw std::runtime_error("Invalid MAC address");
-
- props_vector_t u2s = find(ifc, naddr);
- int n = u2s.size();
-
- if (n == 0) {
- if (addr == "")
- throw std::runtime_error("No USRPs found on interface " + ifc);
- else
- throw std::runtime_error("No USRP found with addr " + addr + " on interface " + ifc);
- }
-
- if (n > 1)
- throw std::runtime_error("Multiple USRPs found on interface; must select by MAC address.");
-
- return find_existing_or_make_new(ifc, &u2s[0], rx_bufsize);
- }
-
- // Private constructor. Sole function is to create an impl.
- usrp2::usrp2(const std::string &ifc, props *p, size_t rx_bufsize)
- : d_impl(new usrp2::impl(ifc, p, rx_bufsize))
- {
- // NOP
- }
-
- // Public class destructor. d_impl will auto-delete.
- usrp2::~usrp2()
- {
- // NOP
- }
-
- std::string
- usrp2::mac_addr()
- {
- return d_impl->mac_addr();
- }
-
- std::string
- usrp2::interface_name()
- {
- return d_impl->interface_name();
- }
-
- // Receive
-
- bool
- usrp2::set_rx_antenna(int ant){
- return d_impl->set_rx_antenna(ant);
- }
-
- bool
- usrp2::set_rx_gain(double gain)
- {
- return d_impl->set_rx_gain(gain);
- }
-
- double
- usrp2::rx_gain_min()
- {
- return d_impl->rx_gain_min();
- }
-
- double
- usrp2::rx_gain_max()
- {
- return d_impl->rx_gain_max();
- }
-
- double
- usrp2::rx_gain_db_per_step()
- {
- return d_impl->rx_gain_db_per_step();
- }
-
- bool
- usrp2::set_rx_lo_offset(double frequency)
- {
- return d_impl->set_rx_lo_offset(frequency);
- }
-
- bool
- usrp2::set_rx_center_freq(double frequency, tune_result *result)
- {
- return d_impl->set_rx_center_freq(frequency, result);
- }
-
- double
- usrp2::rx_freq_min()
- {
- return d_impl->rx_freq_min();
- }
-
- double
- usrp2::rx_freq_max()
- {
- return d_impl->rx_freq_max();
- }
-
- bool
- usrp2::set_rx_decim(int decimation_factor)
- {
- return d_impl->set_rx_decim(decimation_factor);
- }
-
- int
- usrp2::rx_decim()
- {
- return d_impl->rx_decim();
- }
-
- bool
- usrp2::set_rx_scale_iq(int scale_i, int scale_q)
- {
- return d_impl->set_rx_scale_iq(scale_i, scale_q);
- }
-
- bool
- usrp2::start_rx_streaming(unsigned int channel, unsigned int items_per_frame)
- {
- return d_impl->start_rx_streaming(channel, items_per_frame);
- }
-
- bool
- usrp2::start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time)
- {
- return d_impl->start_rx_streaming_at(channel, items_per_frame,time);
- }
-
- bool
- usrp2::sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time)
- {
- return d_impl->sync_and_start_rx_streaming_at(channel, items_per_frame, time);
- }
-
- bool
- usrp2::rx_samples(unsigned int channel, rx_sample_handler *handler)
- {
- return d_impl->rx_samples(channel, handler);
- }
-
- bool
- usrp2::stop_rx_streaming(unsigned int channel)
- {
- return d_impl->stop_rx_streaming(channel);
- }
-
- unsigned int
- usrp2::rx_overruns()
- {
- return d_impl->rx_overruns();
- }
-
- unsigned int
- usrp2::rx_missing()
- {
- return d_impl->rx_missing();
- }
-
- // Transmit
-
- bool
- usrp2::set_tx_antenna(int ant){
- return d_impl->set_tx_antenna(ant);
- }
-
- bool
- usrp2::set_tx_gain(double gain)
- {
- return d_impl->set_tx_gain(gain);
- }
-
- double
- usrp2::tx_gain_min()
- {
- return d_impl->tx_gain_min();
- }
-
- double
- usrp2::tx_gain_max()
- {
- return d_impl->tx_gain_max();
- }
-
- double
- usrp2::tx_gain_db_per_step()
- {
- return d_impl->tx_gain_db_per_step();
- }
-
- bool
- usrp2::set_tx_lo_offset(double frequency)
- {
- return d_impl->set_tx_lo_offset(frequency);
- }
-
- bool
- usrp2::set_tx_center_freq(double frequency, tune_result *result)
- {
- return d_impl->set_tx_center_freq(frequency, result);
- }
-
- double
- usrp2::tx_freq_min()
- {
- return d_impl->tx_freq_min();
- }
-
- double
- usrp2::tx_freq_max()
- {
- return d_impl->tx_freq_max();
- }
-
-
- bool
- usrp2::set_tx_interp(int interpolation_factor)
- {
- return d_impl->set_tx_interp(interpolation_factor);
- }
-
- int
- usrp2::tx_interp()
- {
- return d_impl->tx_interp();
- }
-
- void
- usrp2::default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q)
- {
- d_impl->default_tx_scale_iq(interpolation_factor, scale_i, scale_q);
- }
-
- bool
- usrp2::set_tx_scale_iq(int scale_i, int scale_q)
- {
- return d_impl->set_tx_scale_iq(scale_i, scale_q);
- }
-
- bool
- usrp2::tx_32fc(unsigned int channel,
- const std::complex<float> *samples,
- size_t nsamples,
- const tx_metadata *metadata)
- {
- return d_impl->tx_32fc(channel, samples, nsamples, metadata);
- }
-
- bool
- usrp2::tx_16sc(unsigned int channel,
- const std::complex<int16_t> *samples,
- size_t nsamples,
- const tx_metadata *metadata)
- {
- return d_impl->tx_16sc(channel, samples, nsamples, metadata);
- }
-
- bool
- usrp2::tx_raw(unsigned int channel,
- const uint32_t *items,
- size_t nitems,
- const tx_metadata *metadata)
- {
- return d_impl->tx_raw(channel, items, nitems, metadata);
- }
-
- // miscellaneous methods
-
- bool
- usrp2::config_mimo(int flags)
- {
- return d_impl->config_mimo(flags);
- }
-
- bool
- usrp2::fpga_master_clock_freq(long *freq)
- {
- return d_impl->fpga_master_clock_freq(freq);
- }
-
- bool
- usrp2::adc_rate(long *rate)
- {
- return d_impl->adc_rate(rate);
- }
-
- bool
- usrp2::dac_rate(long *rate)
- {
- return d_impl->dac_rate(rate);
- }
-
- bool
- usrp2::tx_daughterboard_id(int *dbid)
- {
- return d_impl->tx_daughterboard_id(dbid);
- }
-
- bool
- usrp2::rx_daughterboard_id(int *dbid)
- {
- return d_impl->rx_daughterboard_id(dbid);
- }
-
-
- // low level methods
-
- bool
- usrp2::burn_mac_addr(const std::string &new_addr)
- {
- return d_impl->burn_mac_addr(new_addr);
- }
-
- bool
- usrp2::sync_to_pps()
- {
- return d_impl->sync_to_pps();
- }
-
- bool
- usrp2::sync_every_pps(bool enable)
- {
- return d_impl->sync_every_pps(enable);
- }
-
- std::vector<uint32_t>
- usrp2::peek32(uint32_t addr, uint32_t words)
- {
- return d_impl->peek32(addr, words);
- }
-
- bool
- usrp2::poke32(uint32_t addr, const std::vector<uint32_t> &data)
- {
- return d_impl->poke32(addr, data);
- }
-
- bool
- usrp2::set_gpio_ddr(int bank, uint16_t value, uint16_t mask)
- {
- return d_impl->set_gpio_ddr(bank, value, mask);
- }
-
- bool
- usrp2::set_gpio_sels(int bank, std::string src)
- {
- return d_impl->set_gpio_sels(bank, src);
- }
-
- bool
- usrp2::write_gpio(int bank, uint16_t value, uint16_t mask)
- {
- return d_impl->write_gpio(bank, value, mask);
- }
-
- bool
- usrp2::read_gpio(int bank, uint16_t *value)
- {
- return d_impl->read_gpio(bank, value);
- }
-
- bool
- usrp2::enable_gpio_streaming(int bank, int enable)
- {
- return d_impl->enable_gpio_streaming(bank, enable);
- }
-
-} // namespace usrp2
-
-std::ostream& operator<<(std::ostream &os, const usrp2::props &x)
-{
- os << x.addr;
-
- char buf[128];
- snprintf(buf, sizeof(buf)," hw_rev = 0x%04x", x.hw_rev);
-
- os << buf;
- return os;
-}
diff --git a/usrp2/host/lib/usrp2_bytesex.h b/usrp2/host/lib/usrp2_bytesex.h
deleted file mode 100644
index 4f63d07938..0000000000
--- a/usrp2/host/lib/usrp2_bytesex.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * 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 <gruel/inet.h>
diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc
deleted file mode 100644
index 333e2d1e78..0000000000
--- a/usrp2/host/lib/usrp2_impl.cc
+++ /dev/null
@@ -1,1667 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2009,2010 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <usrp2/usrp2.h>
-#include <usrp2/tune_result.h>
-#include <usrp2/copiers.h>
-#include <gruel/inet.h>
-#include <gruel/realtime.h>
-#include <boost/bind.hpp>
-#include <usrp2_types.h>
-#include "usrp2_impl.h"
-#include "eth_buffer.h"
-#include "pktfilter.h"
-#include "control.h"
-#include "ring.h"
-#include <stdexcept>
-#include <iostream>
-#include <stdio.h>
-#include <stddef.h>
-#include <assert.h>
-#include <string.h>
-
-#define USRP2_IMPL_DEBUG 0
-#if USRP2_IMPL_DEBUG
-#define DEBUG_LOG(x) ::write(2, x, 1)
-#else
-#define DEBUG_LOG(x)
-#endif
-
-static const int DEFAULT_RX_SCALE = 1024;
-
-namespace usrp2 {
-
- static const double DEF_CMD_TIMEOUT = 0.1;
-
- std::string
- opcode_to_string(int opcode)
- {
- switch(opcode){
- case OP_EOP: return "OP_EOP";
- case OP_ID: return "OP_ID";
- case OP_ID_REPLY: return "OP_ID_REPLY";
- case OP_BURN_MAC_ADDR: return "OP_BURN_MAC_ADDR";
- case OP_READ_TIME: return "OP_READ_TIME";
- case OP_READ_TIME_REPLY: return "OP_READ_TIME_REPLY";
- case OP_CONFIG_RX_V2: return "OP_CONFIG_RX_V2";
- case OP_CONFIG_RX_REPLY_V2: return "OP_CONFIG_RX_REPLY_V2";
- case OP_CONFIG_TX_V2: return "OP_CONFIG_TX_V2";
- case OP_CONFIG_TX_REPLY_V2: return "OP_CONFIG_TX_REPLY_V2";
- case OP_START_RX_STREAMING: return "OP_START_RX_STREAMING";
- case OP_STOP_RX: return "OP_STOP_RX";
- case OP_CONFIG_MIMO: return "OP_CONFIG_MIMO";
- case OP_DBOARD_INFO: return "OP_DBOARD_INFO";
- case OP_DBOARD_INFO_REPLY: return "OP_DBOARD_INFO_REPLY";
- case OP_SYNC_TO_PPS: return "OP_SYNC_TO_PPS";
- case OP_PEEK: return "OP_PEEK";
- case OP_PEEK_REPLY: return "OP_PEEK_REPLY";
- case OP_SET_TX_LO_OFFSET: return "OP_SET_TX_LO_OFFSET";
- case OP_SET_TX_LO_OFFSET_REPLY: return "OP_SET_TX_LO_OFFSET_REPLY";
- case OP_SET_RX_LO_OFFSET: return "OP_SET_RX_LO_OFFSET";
- case OP_SET_RX_LO_OFFSET_REPLY: return "OP_SET_RX_LO_OFFSET_REPLY";
- case OP_SYNC_EVERY_PPS: return "OP_SYNC_EVERY_PPS";
- case OP_SYNC_EVERY_PPS_REPLY: return "OP_SYNC_EVERY_PPS_REPLY";
-
- default:
- char buf[64];
- snprintf(buf, sizeof(buf), "<unknown opcode: %d>", opcode);
- return buf;
- }
- }
-
-
- /*!
- * \param p points to fixed header
- * \param payload_len_in_bytes is length of the fixed hdr and the payload
- * \param[out] items is set to point to the first uint32 item in the payload
- * \param[out] nitems is set to the number of uint32 items in the payload
- * \param[out] md is filled in with the parsed metadata from the frame.
- */
- static bool
- parse_rx_metadata(void *p, size_t payload_len_in_bytes,
- uint32_t **items, size_t *nitems_in_uint32s, rx_metadata *md)
- {
- if (payload_len_in_bytes < sizeof(u2_fixed_hdr_t)) // invalid format
- return false;
-
- // FIXME deal with the fact that (p % 4) == 2
- //assert((((uintptr_t) p) % 4) == 0); // must be 4-byte aligned
-
- u2_fixed_hdr_t *fh = static_cast<u2_fixed_hdr_t *>(p);
-
- // FIXME unaligned loads!
- md->word0 = u2p_word0(fh);
- md->timestamp = u2p_timestamp(fh);
-
- // FIXME when we've got more info
- // md->start_of_burst = (md->word0 & XXX) != 0;
- // md->end_of_burst = (md->word0 & XXX) != 0;
- // md->rx_overrun = (md->word0 & XXX) != 0;
- md->start_of_burst = 0;
- md->end_of_burst = 0;
- md->rx_overrun = 0;
-
- *items = (uint32_t *)(&fh[1]);
- size_t nbytes = payload_len_in_bytes - sizeof(u2_fixed_hdr_t);
- assert((nbytes % sizeof(uint32_t)) == 0);
- *nitems_in_uint32s = nbytes / sizeof(uint32_t);
-
- return true;
- }
-
-
- usrp2::impl::impl(const std::string &ifc, props *p, size_t rx_bufsize)
- : d_eth_buf(new eth_buffer(rx_bufsize)), d_interface_name(ifc), d_pf(0),
- d_bg_running(false), d_rx_seqno(-1), d_tx_seqno(0), d_next_rid(0),
- d_num_rx_frames(0), d_num_rx_missing(0), d_num_rx_overruns(0), d_num_rx_bytes(0),
- d_num_enqueued(0), d_enqueued_mutex(), d_bg_pending_cond(),
- d_channel_rings(NCHANS), d_tx_interp(0), d_rx_decim(0), d_dont_enqueue(true)
- {
- if (!d_eth_buf->open(ifc, htons(U2_ETHERTYPE)))
- throw std::runtime_error("Unable to register USRP2 protocol");
-
- d_addr = p->addr;
-
- // Create a packet filter for U2_ETHERTYPE packets sourced from target USRP2
- u2_mac_addr_t usrp_mac;
- parse_mac_addr(d_addr, &usrp_mac);
- d_pf = pktfilter::make_ethertype_inbound_target(U2_ETHERTYPE, (const unsigned char*)&(usrp_mac.addr));
- if (!d_pf || !d_eth_buf->attach_pktfilter(d_pf))
- throw std::runtime_error("Unable to attach packet filter.");
-
- if (USRP2_IMPL_DEBUG)
- std::cerr << "usrp2 constructor: using USRP2 at " << d_addr << std::endl;
-
- memset(d_pending_replies, 0, sizeof(d_pending_replies));
-
- // Kick off receive thread
- start_bg();
-
- // In case the USRP2 was left streaming RX
- // FIXME: only one channel right now
- stop_rx_streaming(0);
-
- if (!dboard_info()) // we're hosed
- throw std::runtime_error("Unable to retrieve daughterboard info");
-
- if (0){
- int dbid;
-
- tx_daughterboard_id(&dbid);
- fprintf(stderr, "Tx dboard 0x%x\n", dbid);
- fprintf(stderr, " freq_min = %g\n", tx_freq_min());
- fprintf(stderr, " freq_max = %g\n", tx_freq_max());
- fprintf(stderr, " gain_min = %g\n", tx_gain_min());
- fprintf(stderr, " gain_max = %g\n", tx_gain_max());
- fprintf(stderr, " gain_db_per_step = %g\n", tx_gain_db_per_step());
-
- rx_daughterboard_id(&dbid);
- fprintf(stderr, "Rx dboard 0x%x\n", dbid);
- fprintf(stderr, " freq_min = %g\n", rx_freq_min());
- fprintf(stderr, " freq_max = %g\n", rx_freq_max());
- fprintf(stderr, " gain_min = %g\n", rx_gain_min());
- fprintf(stderr, " gain_max = %g\n", rx_gain_max());
- fprintf(stderr, " gain_db_per_step = %g\n", rx_gain_db_per_step());
- }
-
- // Ensure any custom values in hardware are cleared
- if (!reset_db())
- std::cerr << "usrp2::ctor reset_db failed\n";
-
- // default gains to mid point
- if (!set_tx_gain((tx_gain_min() + tx_gain_max()) / 2))
- std::cerr << "usrp2::ctor set_tx_gain failed\n";
-
- if (!set_rx_gain((rx_gain_min() + rx_gain_max()) / 2))
- std::cerr << "usrp2::ctor set_rx_gain failed\n";
-
- // default interp and decim
- if (!set_tx_interp(12))
- std::cerr << "usrp2::ctor set_tx_interp failed\n";
-
- if (!set_rx_decim(12))
- std::cerr << "usrp2::ctor set_rx_decim failed\n";
-
- // set workable defaults for scaling
- if (!set_rx_scale_iq(DEFAULT_RX_SCALE, DEFAULT_RX_SCALE))
- std::cerr << "usrp2::ctor set_rx_scale_iq failed\n";
- }
-
- usrp2::impl::~impl()
- {
- stop_bg();
- delete d_pf;
- d_eth_buf->close();
- delete d_eth_buf;
-
- if (USRP2_IMPL_DEBUG) {
- std::cerr << std::endl
- << "usrp2 destructor: received " << d_num_rx_frames
- << " frames, with " << d_num_rx_missing << " lost ("
- << (d_num_rx_frames == 0 ? 0 : (int)(100.0*d_num_rx_missing/d_num_rx_frames))
- << "%), totaling " << d_num_rx_bytes
- << " bytes" << std::endl;
- }
- }
-
- bool
- usrp2::impl::parse_mac_addr(const std::string &s, u2_mac_addr_t *p)
- {
- p->addr[0] = 0x00; // Matt's IAB
- p->addr[1] = 0x50;
- p->addr[2] = 0xC2;
- p->addr[3] = 0x85;
- p->addr[4] = 0x30;
- p->addr[5] = 0x00;
-
- int len = s.size();
-
- switch (len){
-
- case 5:
- return sscanf(s.c_str(), "%hhx:%hhx", &p->addr[4], &p->addr[5]) == 2;
-
- case 17:
- return sscanf(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
- &p->addr[0], &p->addr[1], &p->addr[2],
- &p->addr[3], &p->addr[4], &p->addr[5]) == 6;
- default:
- return false;
- }
- }
-
- void
- usrp2::impl::init_et_hdrs(u2_eth_packet_t *p, const std::string &dst)
- {
- p->ehdr.ethertype = htons(U2_ETHERTYPE);
- parse_mac_addr(dst, &p->ehdr.dst);
- memcpy(&p->ehdr.src, d_eth_buf->mac(), 6);
- p->thdr.flags = 0; // FIXME transport header values?
- p->thdr.seqno = d_tx_seqno++;
- p->thdr.ack = 0;
- }
-
- void
- usrp2::impl::init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
- int word0_flags, int chan, uint32_t timestamp)
- {
- init_et_hdrs(p, dst);
- u2p_set_word0(&p->fixed, word0_flags, chan);
- u2p_set_timestamp(&p->fixed, timestamp);
-
- if (chan == CONTROL_CHAN) { // no sequence numbers, back it out
- p->thdr.seqno = 0;
- d_tx_seqno--;
- }
- }
-
- void
- usrp2::impl::init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd)
- {
- memset(cmd, 0, sizeof(*cmd));
- init_etf_hdrs(&cmd->h, d_addr, 0, CONTROL_CHAN, -1);
- cmd->op.opcode = OP_CONFIG_RX_V2;
- cmd->op.len = sizeof(cmd->op);
- cmd->op.rid = d_next_rid++;
- cmd->eop.opcode = OP_EOP;
- cmd->eop.len = sizeof(cmd->eop);
- }
-
- void
- usrp2::impl::init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd)
- {
- memset(cmd, 0, sizeof(*cmd));
- init_etf_hdrs(&cmd->h, d_addr, 0, CONTROL_CHAN, -1);
- cmd->op.opcode = OP_CONFIG_TX_V2;
- cmd->op.len = sizeof(cmd->op);
- cmd->op.rid = d_next_rid++;
- cmd->eop.opcode = OP_EOP;
- cmd->eop.len = sizeof(cmd->eop);
- }
-
-
- bool
- usrp2::impl::transmit_cmd(void *cmd_, size_t len_)
- {
- const void *cmd = cmd_;
- int len = len_;
- unsigned char tmp[64];
-
- if (len_ < 64){ // pad to minimum ethernet frame size
- memset(tmp, 0, sizeof(tmp));
- memcpy(tmp, cmd_, len_);
- cmd = tmp;
- len = sizeof(tmp);
- }
-
- return d_eth_buf->tx_frame(cmd, len) == eth_buffer::EB_OK;
- }
-
- bool
- usrp2::impl::transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs)
- {
- d_pending_replies[p->rid()] = p;
-
- if (!transmit_cmd(cmd, len)){
- d_pending_replies[p->rid()] = 0;
- return false;
- }
-
- int res = p->wait_for_completion(secs);
- d_pending_replies[p->rid()] = 0;
- return res == 1;
- }
-
- // ----------------------------------------------------------------
- // Background loop: received packet demuxing
- // ----------------------------------------------------------------
-
- void
- usrp2::impl::start_bg()
- {
- d_rx_tg.create_thread(boost::bind(&usrp2::impl::bg_loop, this));
- }
-
- void
- usrp2::impl::stop_bg()
- {
- d_bg_running = false;
- d_bg_pending_cond.notify_one(); // FIXME: check if needed
- d_rx_tg.join_all();
- }
-
- void
- usrp2::impl::bg_loop()
- {
- gruel::enable_realtime_scheduling();
-
- d_bg_running = true;
- while(d_bg_running) {
- DEBUG_LOG(":");
- // Receive available frames from ethernet buffer. Handler will
- // process control frames, enqueue data packets in channel
- // rings, and signal blocked API threads
- int res = d_eth_buf->rx_frames(this, 100); // FIXME magic timeout
- if (res == eth_buffer::EB_ERROR)
- break;
-
- // Wait for user API thread(s) to process all enqueued packets.
- // The channel ring thread that decrements d_num_enqueued to zero
- // will signal this thread to continue.
- {
- gruel::scoped_lock l(d_enqueued_mutex);
- while(d_num_enqueued > 0 && d_bg_running)
- d_bg_pending_cond.wait(l);
- }
- }
- d_bg_running = false;
- }
-
- //
- // passed to eth_buffer::rx_frames
- //
- data_handler::result
- usrp2::impl::operator()(const void *base, size_t len)
- {
- u2_eth_samples_t *pkt = (u2_eth_samples_t *)base;
-
- // FIXME unaligned load!
- int chan = u2p_chan(&pkt->hdrs.fixed);
-
- if (chan == CONTROL_CHAN) { // control packets
- DEBUG_LOG("c");
- return handle_control_packet(base, len);
- }
- else { // data packets
-
- if (d_dont_enqueue) // toss packet
- return data_handler::RELEASE;
-
- return handle_data_packet(base, len);
- }
-
- // not reached
- }
-
- data_handler::result
- usrp2::impl::handle_control_packet(const void *base, size_t len)
- {
- // point to beginning of payload (subpackets)
- unsigned char *p = (unsigned char *)base + sizeof(u2_eth_packet_t);
-
- // FIXME (p % 4) == 2. Not good. Must watch for unaligned loads.
-
- // FIXME iterate over payload, handling more than a single subpacket.
-
- int opcode = p[0];
- unsigned int oplen = p[1];
- unsigned int rid = p[2];
-
- pending_reply *rp = d_pending_replies[rid];
- if (rp) {
- unsigned int buflen = rp->len();
- if (oplen != buflen) {
- std::cerr << "usrp2: mismatched command reply length (expected: "
- << buflen << " got: " << oplen << "). "
- << "op = " << opcode_to_string(opcode) << std::endl;
- }
-
- // Copy reply into caller's buffer
- memcpy(rp->buffer(), p, std::min(oplen, buflen));
- rp->notify_completion();
- d_pending_replies[rid] = 0;
- return data_handler::RELEASE;
- }
-
- // TODO: handle unsolicited, USRP2 initiated, or late replies
- DEBUG_LOG("l");
- return data_handler::RELEASE;
- }
-
- data_handler::result
- usrp2::impl::handle_data_packet(const void *base, size_t len)
- {
- u2_eth_samples_t *pkt = (u2_eth_samples_t *)base;
- d_num_rx_frames++;
- d_num_rx_bytes += len;
-
- /* --- FIXME start of fake transport layer handler --- */
-
- if (d_rx_seqno != -1) {
- int expected_seqno = (d_rx_seqno + 1) & 0xFF;
- int seqno = pkt->hdrs.thdr.seqno;
-
- if (seqno != expected_seqno) {
- ::write(2, "S", 1); // missing sequence number
- int missing = seqno - expected_seqno;
- if (missing < 0)
- missing += 256;
-
- d_num_rx_overruns++;
- d_num_rx_missing += missing;
- }
- }
-
- d_rx_seqno = pkt->hdrs.thdr.seqno;
-
- /* --- end of fake transport layer handler --- */
-
- // FIXME unaligned load!
- unsigned int chan = u2p_chan(&pkt->hdrs.fixed);
-
- {
- gruel::scoped_lock l(d_channel_rings_mutex);
-
- if (!d_channel_rings[chan]) {
- DEBUG_LOG("!");
- return data_handler::RELEASE; // discard packet, no channel handler
- }
-
- // Strip off ethernet header and transport header and enqueue the rest
-
- size_t offset = offsetof(u2_eth_samples_t, hdrs.fixed);
- if (d_channel_rings[chan]->enqueue(&pkt->hdrs.fixed, len-offset)) {
- inc_enqueued();
- DEBUG_LOG("+");
- return data_handler::KEEP; // channel ring runner will mark frame done
- }
- else {
- DEBUG_LOG("!");
- return data_handler::RELEASE; // discard, no room in channel ring
- }
- return data_handler::RELEASE;
- }
- }
-
-
- // ----------------------------------------------------------------
- // Receive
- // ----------------------------------------------------------------
-
- bool
- usrp2::impl::set_rx_antenna(int ant){
- op_config_mimo_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_RX_ANTENNA;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.flags = ant;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- return ntohx(reply.ok) == 1;
- }
-
- bool
- usrp2::impl::set_rx_gain(double gain)
- {
- op_config_rx_v2_cmd cmd;
- op_config_rx_reply_v2_t reply;
-
- init_config_rx_v2_cmd(&cmd);
- cmd.op.valid = htons(CFGV_GAIN);
- cmd.op.gain = htons(u2_double_to_fxpt_gain(gain));
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool
- usrp2::impl::set_rx_lo_offset(double frequency)
- {
- op_freq_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_SET_RX_LO_OFFSET;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
-
- u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency);
- cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt));
- cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
-
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool
- usrp2::impl::set_rx_center_freq(double frequency, tune_result *result)
- {
- op_config_rx_v2_cmd cmd;
- op_config_rx_reply_v2_t reply;
-
- init_config_rx_v2_cmd(&cmd);
- cmd.op.valid = htons(CFGV_FREQ);
- u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency);
- cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt));
- cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- if (result && success) {
- result->baseband_freq =
- u2_fxpt_freq_to_double(
- u2_fxpt_freq_from_hilo(ntohl(reply.baseband_freq_hi),
- ntohl(reply.baseband_freq_lo)));
-
- result->dxc_freq =
- u2_fxpt_freq_to_double(
- u2_fxpt_freq_from_hilo(ntohl(reply.ddc_freq_hi),
- ntohl(reply.ddc_freq_lo)));
-
- result->residual_freq =
- u2_fxpt_freq_to_double(
- u2_fxpt_freq_from_hilo(ntohl(reply.residual_freq_hi),
- ntohl(reply.residual_freq_lo)));
-
- result->spectrum_inverted = (bool)(ntohx(reply.inverted) == 1);
- }
-
- return success;
- }
-
- bool
- usrp2::impl::set_rx_decim(int decimation_factor)
- {
- op_config_rx_v2_cmd cmd;
- op_config_rx_reply_v2_t reply;
-
- init_config_rx_v2_cmd(&cmd);
- cmd.op.valid = htons(CFGV_INTERP_DECIM);
- cmd.op.decim = htonl(decimation_factor);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- if (success)
- d_rx_decim = decimation_factor;
- return success;
- }
-
- bool
- usrp2::impl::set_rx_scale_iq(int scale_i, int scale_q)
- {
- op_config_rx_v2_cmd cmd;
- op_config_rx_reply_v2_t reply;
-
- init_config_rx_v2_cmd(&cmd);
- cmd.op.valid = htons(CFGV_SCALE_IQ);
- cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool
- usrp2::impl::start_rx_streaming(unsigned int channel, unsigned int items_per_frame)
- {
- if (channel > MAX_CHAN) {
- std::cerr << "usrp2: invalid channel number (" << channel
- << ")" << std::endl;
- return false;
- }
-
- if (channel > 0) { // until firmware supports multiple streams
- std::cerr << "usrp2: channel " << channel
- << " not implemented" << std::endl;
- return false;
- }
-
- {
- gruel::scoped_lock l(d_channel_rings_mutex);
- if (d_channel_rings[channel]) {
- std::cerr << "usrp2: channel " << channel
- << " already streaming" << std::endl;
- return false;
- }
-
- if (items_per_frame == 0)
- items_per_frame = U2_MAX_SAMPLES; // minimize overhead
-
- op_start_rx_streaming_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_START_RX_STREAMING;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.items_per_frame = htonl(items_per_frame);
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- d_dont_enqueue = false;
- bool success = false;
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
- success = success && (ntohx(reply.ok) == 1);
-
- if (success)
- d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames()));
- else
- d_dont_enqueue = true;
-
- //fprintf(stderr, "usrp2::start_rx_streaming: success = %d\n", success);
- return success;
- }
- }
-
- bool
- usrp2::impl::start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time)
- {
- if (channel > MAX_CHAN) {
- std::cerr << "usrp2: invalid channel number (" << channel
- << ")" << std::endl;
- return false;
- }
-
- if (channel > 0) { // until firmware supports multiple streams
- std::cerr << "usrp2: channel " << channel
- << " not implemented" << std::endl;
- return false;
- }
-
- {
- gruel::scoped_lock guard(d_channel_rings_mutex);
- if (d_channel_rings[channel]) {
- std::cerr << "usrp2: channel " << channel
- << " already streaming" << std::endl;
- return false;
- }
-
- if (items_per_frame == 0)
- items_per_frame = U2_MAX_SAMPLES; // minimize overhead
-
- op_start_rx_streaming_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, time);
- cmd.op.opcode = OP_START_RX_STREAMING;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.items_per_frame = htonl(items_per_frame);
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- d_dont_enqueue = false;
- bool success = false;
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
- success = success && (ntohx(reply.ok) == 1);
-
- if (success)
- d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames()));
- else
- d_dont_enqueue = true;
-
- return success;
- }
- }
-
- bool
- usrp2::impl::sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time)
- {
-
- if (channel > MAX_CHAN) {
- std::cerr << "usrp2: invalid channel number (" << channel
- << ")" << std::endl;
- return false;
- }
-
- if (channel > 0) { // until firmware supports multiple streams
- std::cerr << "usrp2: channel " << channel
- << " not implemented" << std::endl;
- return false;
- }
-
- {
- gruel::scoped_lock guard(d_channel_rings_mutex);
- if (d_channel_rings[channel]) {
- std::cerr << "usrp2: channel " << channel
- << " already streaming" << std::endl;
- return false;
- }
-
- if (items_per_frame == 0)
- items_per_frame = U2_MAX_SAMPLES; // minimize overhead
-
- op_sync_and_start_rx_streaming_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, time);
- cmd.sync_op.opcode = OP_SYNC_TO_PPS;
- cmd.sync_op.len = sizeof(cmd.sync_op);
- cmd.sync_op.rid = d_next_rid++;
- cmd.rx_op.opcode = OP_START_RX_STREAMING;
- cmd.rx_op.len = sizeof(cmd.rx_op);
- cmd.rx_op.rid = d_next_rid++;
- cmd.rx_op.items_per_frame = htonl(items_per_frame);
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- d_dont_enqueue = false;
- bool success = false;
- pending_reply p(cmd.sync_op.rid, &reply, sizeof(reply));
- success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
- success = success && (ntohx(reply.ok) == 1);
-
- if (success)
- d_channel_rings[channel] = ring_sptr(new ring(d_eth_buf->max_frames()));
- else
- d_dont_enqueue = true;
-
- return success;
- }
- }
-
- bool
- usrp2::impl::stop_rx_streaming(unsigned int channel)
- {
- if (channel > MAX_CHAN) {
- std::cerr << "usrp2: invalid channel number (" << channel
- << ")" << std::endl;
- return false;
- }
-
- if (channel > 0) { // until firmware supports multiple streams
- std::cerr << "usrp2: channel " << channel
- << " not implemented" << std::endl;
- return false;
- }
-
- d_dont_enqueue = true; // no new samples
- flush_rx_samples(channel); // dump any we may already have
-
- op_stop_rx_cmd cmd;
- op_generic_t reply;
-
- {
- gruel::scoped_lock l(d_channel_rings_mutex);
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_STOP_RX;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- bool success = false;
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- success = transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT);
- success = success && (ntohx(reply.ok) == 1);
- d_channel_rings[channel].reset();
- d_rx_seqno = -1;
- //fprintf(stderr, "usrp2::stop_rx_streaming: success = %d\n", success);
- return success;
- }
- }
-
- bool
- usrp2::impl::rx_samples(unsigned int channel, rx_sample_handler *handler)
- {
- if (channel > MAX_CHAN) {
- std::cerr << "usrp2: invalid channel (" << channel
- << " )" << std::endl;
- return false;
- }
-
- if (channel > 0) {
- std::cerr << "usrp2: channel " << channel
- << " not implemented" << std::endl;
- return false;
- }
-
- ring_sptr rp = d_channel_rings[channel];
- if (!rp){
- std::cerr << "usrp2: channel " << channel
- << " not receiving" << std::endl;
- return false;
- }
-
- // Wait for frames available in channel ring
- DEBUG_LOG("W");
- rp->wait_for_not_empty();
- DEBUG_LOG("s");
-
- // Iterate through frames and present to user
- void *p;
- size_t frame_len_in_bytes;
- while (rp->dequeue(&p, &frame_len_in_bytes)) {
- uint32_t *items; // points to beginning of data items
- size_t nitems_in_uint32s;
- rx_metadata md;
- if (!parse_rx_metadata(p, frame_len_in_bytes, &items, &nitems_in_uint32s, &md))
- return false;
-
- bool want_more = (*handler)(items, nitems_in_uint32s, &md);
- d_eth_buf->release_frame(p);
- DEBUG_LOG("-");
- dec_enqueued();
-
- if (!want_more)
- break;
- }
- return true;
- }
-
- bool
- usrp2::impl::flush_rx_samples(unsigned int channel)
- {
- if (channel > MAX_CHAN) {
- std::cerr << "usrp2: invalid channel (" << channel
- << " )" << std::endl;
- return false;
- }
-
- if (channel > 0) {
- std::cerr << "usrp2: channel " << channel
- << " not implemented" << std::endl;
- return false;
- }
-
- ring_sptr rp = d_channel_rings[channel];
- if (!rp){
- return false;
- }
-
- // Iterate through frames and drop them
- void *p;
- size_t frame_len_in_bytes;
- while (rp->dequeue(&p, &frame_len_in_bytes)) {
- d_eth_buf->release_frame(p);
- dec_enqueued();
- }
- return true;
- }
-
- // ----------------------------------------------------------------
- // Transmit
- // ----------------------------------------------------------------
-
- bool
- usrp2::impl::set_tx_antenna(int ant){
- op_config_mimo_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_TX_ANTENNA;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.flags = ant;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- return ntohx(reply.ok) == 1;
- }
-
- bool
- usrp2::impl::set_tx_gain(double gain)
- {
- op_config_tx_v2_cmd cmd;
- op_config_tx_reply_v2_t reply;
-
- init_config_tx_v2_cmd(&cmd);
- cmd.op.valid = htons(CFGV_GAIN);
- cmd.op.gain = htons(u2_double_to_fxpt_gain(gain));
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool
- usrp2::impl::set_tx_lo_offset(double frequency)
- {
- op_freq_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_SET_TX_LO_OFFSET;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
-
- u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency);
- cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt));
- cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
-
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool
- usrp2::impl::set_tx_center_freq(double frequency, tune_result *result)
- {
- op_config_tx_v2_cmd cmd;
- op_config_tx_reply_v2_t reply;
-
- init_config_tx_v2_cmd(&cmd);
- cmd.op.valid = htons(CFGV_FREQ);
- u2_fxpt_freq_t fxpt = u2_double_to_fxpt_freq(frequency);
- cmd.op.freq_hi = htonl(u2_fxpt_freq_hi(fxpt));
- cmd.op.freq_lo = htonl(u2_fxpt_freq_lo(fxpt));
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- if (result && success) {
- result->baseband_freq =
- u2_fxpt_freq_to_double(
- u2_fxpt_freq_from_hilo(ntohl(reply.baseband_freq_hi),
- ntohl(reply.baseband_freq_lo)));
-
- result->dxc_freq =
- u2_fxpt_freq_to_double(
- u2_fxpt_freq_from_hilo(ntohl(reply.duc_freq_hi),
- ntohl(reply.duc_freq_lo)));
-
- result->residual_freq =
- u2_fxpt_freq_to_double(
- u2_fxpt_freq_from_hilo(ntohl(reply.residual_freq_hi),
- ntohl(reply.residual_freq_lo)));
-
- result->spectrum_inverted = (bool)(ntohx(reply.inverted) == 1);
- }
-
- return success;
- }
-
- bool
- usrp2::impl::set_tx_interp(int interpolation_factor)
- {
- op_config_tx_v2_cmd cmd;
- op_config_tx_reply_v2_t reply;
-
- init_config_tx_v2_cmd(&cmd);
- cmd.op.valid = htons(CFGV_INTERP_DECIM);
- cmd.op.interp = htonl(interpolation_factor);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- if (success) {
- d_tx_interp = interpolation_factor;
-
- // Auto-set TX scaling based on interpolation rate
- int scale_i, scale_q;
- default_tx_scale_iq(d_tx_interp, &scale_i, &scale_q);
- return set_tx_scale_iq(scale_i, scale_q);
- }
-
- return success;
- }
-
- void
- usrp2::impl::default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q)
- {
- // Calculate CIC interpolation (i.e., without halfband interpolators)
- int i = interpolation_factor;
- if (i > 128)
- i = i >> 1;
- if (i > 128)
- i = i >> 1;
-
- // Calculate dsp_core_tx gain absent scale multipliers
- float gain = (1.65*i*i*i)/(4096*pow(2, ceil(log2(i*i*i))));
-
- // Calculate closest multiplier constant to reverse gain
- int scale = (int)rint(1.0/gain);
- // fprintf(stderr, "if=%i i=%i gain=%f scale=%i\n", interpolation_factor, i, gain, scale);
-
- // Both I and Q are identical in this case
- if (scale_i)
- *scale_i = scale;
- if (scale_q)
- *scale_q = scale;
- }
-
- bool
- usrp2::impl::set_tx_scale_iq(int scale_i, int scale_q)
- {
- op_config_tx_v2_cmd cmd;
- op_config_tx_reply_v2_t reply;
-
- init_config_tx_v2_cmd(&cmd);
- cmd.op.valid = htons(CFGV_SCALE_IQ);
- cmd.op.scale_iq = htonl(((scale_i & 0xffff) << 16) | (scale_q & 0xffff));
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool
- usrp2::impl::tx_32fc(unsigned int channel,
- const std::complex<float> *samples,
- size_t nsamples,
- const tx_metadata *metadata)
- {
- uint32_t items[nsamples];
- copy_host_32fc_to_u2_16sc(nsamples, samples, items);
- return tx_raw(channel, items, nsamples, metadata);
- }
-
- bool
- usrp2::impl::tx_16sc(unsigned int channel,
- const std::complex<int16_t> *samples,
- size_t nsamples,
- const tx_metadata *metadata)
- {
-#ifdef WORDS_BIGENDIAN
-
- // Already binary equivalent to 16-bit I/Q on the wire.
- // No conversion required.
-
- assert(sizeof(samples[0]) == sizeof(uint32_t));
- return tx_raw(channel, (const uint32_t *) samples, nsamples, metadata);
-
-#else
-
- uint32_t items[nsamples];
- copy_host_16sc_to_u2_16sc(nsamples, samples, items);
- return tx_raw(channel, items, nsamples, metadata);
-
-#endif
- }
-
- bool
- usrp2::impl::tx_raw(unsigned int channel,
- const uint32_t *items,
- size_t nitems,
- const tx_metadata *metadata)
- {
- if (nitems == 0)
- return true;
-
- // FIXME can't deal with nitems < U2_MIN_SAMPLES (will be fixed in VRT)
- // FIXME need to check the MTU instead of assuming 1500 bytes
-
- // fragment as necessary then fire away
-
- size_t nframes = (nitems + U2_MAX_SAMPLES - 1) / U2_MAX_SAMPLES;
- size_t last_frame = nframes - 1;
- u2_eth_packet_t hdrs;
-
- size_t n = 0;
- for (size_t fn = 0; fn < nframes; fn++){
- uint32_t timestamp = 0;
- uint32_t flags = 0;
-
- if (fn == 0){
- timestamp = metadata->timestamp;
- if (metadata->send_now)
- flags |= U2P_TX_IMMEDIATE;
- if (metadata->start_of_burst)
- flags |= U2P_TX_START_OF_BURST;
- }
- if (fn > 0){
- flags |= U2P_TX_IMMEDIATE;
- }
- if (fn == last_frame){
- if (metadata->end_of_burst)
- flags |= U2P_TX_END_OF_BURST;
- }
-
- init_etf_hdrs(&hdrs, d_addr, flags, channel, timestamp);
-
- // Avoid short packet by splitting last two packets if reqd
- size_t i;
- if ((nitems - n) > U2_MAX_SAMPLES && (nitems - n) < (U2_MAX_SAMPLES + U2_MIN_SAMPLES))
- i = (nitems - n) / 2;
- else
- i = std::min((size_t) U2_MAX_SAMPLES, nitems - n);
-
- eth_iovec iov[2];
- iov[0].iov_base = &hdrs;
- iov[0].iov_len = sizeof(hdrs);
- iov[1].iov_base = const_cast<uint32_t *>(&items[n]);
- iov[1].iov_len = i * sizeof(uint32_t);
-
- size_t total = iov[0].iov_len + iov[1].iov_len;
- if (total < 64)
- fprintf(stderr, "usrp2::tx_raw: FIXME: short packet: %zd items (%zd bytes)\n", i, total);
-
- if (d_eth_buf->tx_framev(iov, 2) != eth_buffer::EB_OK){
- return false;
- }
-
- n += i;
- }
-
- return true;
- }
-
- // ----------------------------------------------------------------
- // misc commands
- // ----------------------------------------------------------------
-
- bool
- usrp2::impl::config_mimo(int flags)
- {
- op_config_mimo_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_CONFIG_MIMO;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.flags = flags;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- return ntohx(reply.ok) == 1;
- }
-
- bool
- usrp2::impl::fpga_master_clock_freq(long *freq)
- {
- *freq = 100000000L; // 100 MHz
- return true;
- }
-
- bool
- usrp2::impl::adc_rate(long *rate)
- {
- return fpga_master_clock_freq(rate);
- }
-
- bool
- usrp2::impl::dac_rate(long *rate)
- {
- return fpga_master_clock_freq(rate);
- }
-
- bool
- usrp2::impl::tx_daughterboard_id(int *dbid)
- {
- *dbid = d_tx_db_info.dbid;
- return true;
- }
-
- bool
- usrp2::impl::rx_daughterboard_id(int *dbid)
- {
- *dbid = d_rx_db_info.dbid;
- return true;
- }
-
-
- // ----------------------------------------------------------------
- // low-level commands
- // ----------------------------------------------------------------
-
- bool
- usrp2::impl::burn_mac_addr(const std::string &new_addr)
- {
- op_burn_mac_addr_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_BURN_MAC_ADDR;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- if (!parse_mac_addr(new_addr, &cmd.op.addr))
- return false;
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, 4*DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- static void
- fill_dboard_info(db_info *dst, const u2_db_info_t *src)
- {
- dst->dbid = ntohl(src->dbid);
-
- dst->freq_min =
- u2_fxpt_freq_to_double(u2_fxpt_freq_from_hilo(ntohl(src->freq_min_hi),
- ntohl(src->freq_min_lo)));
- dst->freq_max =
- u2_fxpt_freq_to_double(u2_fxpt_freq_from_hilo(ntohl(src->freq_max_hi),
- ntohl(src->freq_max_lo)));
-
- dst->gain_min = u2_fxpt_gain_to_double(ntohs(src->gain_min));
- dst->gain_max = u2_fxpt_gain_to_double(ntohs(src->gain_max));
- dst->gain_step_size = u2_fxpt_gain_to_double(ntohs(src->gain_step_size));
- }
-
- bool
- usrp2::impl::dboard_info()
- {
- op_dboard_info_cmd cmd;
- op_dboard_info_reply_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_DBOARD_INFO;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- if (success){
- fill_dboard_info(&d_tx_db_info, &reply.tx_db_info);
- fill_dboard_info(&d_rx_db_info, &reply.rx_db_info);
- }
- return success;
- }
-
-
- bool
- usrp2::impl::sync_to_pps()
- {
- op_generic_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_SYNC_TO_PPS;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- return ntohx(reply.ok) == 1;
- }
-
- bool
- usrp2::impl::sync_every_pps(bool enable)
- {
- op_generic_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_SYNC_EVERY_PPS;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.ok = enable ? 1 : 0;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- return ntohx(reply.ok) == 1;
- }
-
- std::vector<uint32_t>
- usrp2::impl::peek32(uint32_t addr, uint32_t words)
- {
- std::vector<uint32_t> result; // zero sized on error return
- // fprintf(stderr, "usrp2::peek: addr=%08X words=%u\n", addr, words);
-
- if (addr % 4 != 0) {
- fprintf(stderr, "usrp2::peek: addr (=%08X) must be 32-bit word aligned\n", addr);
- return result;
- }
-
- if (words == 0)
- return result;
-
- op_peek_cmd cmd;
- op_generic_t *reply;
-
- int wlen = sizeof(uint32_t);
- int rlen = sizeof(op_generic_t);
- size_t bytes = words*wlen;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_PEEK;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- cmd.op.addr = htonl(addr);
- cmd.op.bytes = htonl(bytes);
-
- reply = (op_generic_t *)malloc(rlen+bytes);
- pending_reply p(cmd.op.rid, reply, rlen+bytes);
- if (transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT)) {
- uint32_t nwords = (reply->len-rlen)/sizeof(uint32_t);
- uint32_t *data = (uint32_t *)(reply+rlen/wlen);
- for (unsigned int i = 0; i < nwords; i++)
- result.push_back(ntohl(data[i]));
- }
-
- free(reply);
- return result;
- }
-
- bool
- usrp2::impl::poke32(uint32_t addr, const std::vector<uint32_t> &data)
- {
- if (addr % 4 != 0) {
- fprintf(stderr, "usrp2::poke32: addr (=%08X) must be 32-bit word aligned\n", addr);
- return false;
- }
-
- int plen = sizeof(op_poke_cmd);
- int wlen = sizeof(uint32_t);
- int max_words = (MAX_SUBPKT_LEN-plen)/wlen;
- int words = data.size();
-
- if (words > max_words) {
- fprintf(stderr, "usrp2::poke32: write size (=%u) exceeds maximum of %u words\n",
- words, max_words);
- return false;
- }
-
- //fprintf(stderr, "usrp2::poke32: addr=%08X words=%u\n", addr, words);
-
- if (words == 0)
- return true; // NOP
-
- op_poke_cmd *cmd;
- op_generic_t *eop;
-
- // Allocate, clear, and initialize command packet
- int bytes = words*wlen;
- int l = plen+bytes+sizeof(*eop); // op_poke_cmd+data+eop
- cmd = (op_poke_cmd *)malloc(l);
- //fprintf(stderr, "cmd=%p l=%i\n", cmd, l);
- memset(cmd, 0, l);
- init_etf_hdrs(&cmd->h, d_addr, 0, CONTROL_CHAN, -1);
- cmd->op.opcode = OP_POKE;
- cmd->op.len = sizeof(cmd->op)+bytes;
- cmd->op.rid = d_next_rid++;
- cmd->op.addr = htonl(addr);
-
- // Copy data from vector into packet space
- uint32_t *dest = (uint32_t *)((uint8_t *)cmd+plen);
- for (int i = 0; i < words; i++) {
- //fprintf(stderr, "%03i@%p\n", i, dest);
- *dest++ = htonl(data[i]);
- }
-
- // Write end-of-packet subpacket
- eop = (op_generic_t *)dest;
- eop->opcode = OP_EOP;
- eop->len = sizeof(*eop);
- //fprintf(stderr, "eop=%p len=%i\n", eop, eop->len);
-
- // Send command to device and retrieve reply
- bool ok = false;
- op_generic_t reply;
- pending_reply p(cmd->op.rid, &reply, sizeof(reply));
- if (transmit_cmd_and_wait(cmd, l, &p, DEF_CMD_TIMEOUT))
- ok = (ntohx(reply.ok) == 1);
-
- free(cmd);
- return ok;
- }
-
- bool
- usrp2::impl::reset_db()
- {
- op_generic_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_RESET_DB;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool usrp2::impl::set_gpio_ddr(int bank, uint16_t value, uint16_t mask)
- {
- if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) {
- fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n");
- return false;
- }
-
- op_gpio_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_GPIO_SET_DDR;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.bank = static_cast<uint8_t>(bank);
- cmd.op.value = htons(value);
- cmd.op.mask = htons(mask);
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool usrp2::impl::set_gpio_sels(int bank, std::string sels)
- {
- if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) {
- fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n");
- return false;
- }
-
- if (sels.size() != 16) {
- fprintf(stderr, "set_gpio_sels: sels must be exactly 16 bytes\n");
- return false;
- }
-
- op_gpio_set_sels_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_GPIO_SET_SELS;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.bank = static_cast<uint8_t>(bank);
- memcpy(&cmd.op.sels, sels.c_str(), 16);
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool usrp2::impl::write_gpio(int bank, uint16_t value, uint16_t mask)
- {
- if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) {
- fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n");
- return false;
- }
-
- op_gpio_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_GPIO_WRITE;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.bank = static_cast<uint8_t>(bank);
- cmd.op.value = htons(value);
- cmd.op.mask = htons(mask);
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
- bool usrp2::impl::read_gpio(int bank, uint16_t *value)
- {
- if (bank != GPIO_TX_BANK && bank != GPIO_RX_BANK) {
- fprintf(stderr, "set_gpio_ddr: bank must be one of GPIO_RX_BANK or GPIO_TX_BANK\n");
- return false;
- }
-
- op_gpio_cmd cmd;
- op_gpio_read_reply_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_GPIO_READ;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.bank = static_cast<uint8_t>(bank);
- cmd.op.value = 0; // not used
- cmd.op.mask = 0; // not used
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- if (success && (value != NULL))
- *value = ntohs(reply.value);
-
- return success;
- }
-
- bool usrp2::impl::enable_gpio_streaming(int bank, int enable)
- {
- if (bank != GPIO_RX_BANK) {
- fprintf(stderr, "enable_gpio_streaming: only RX streaming is currently implemented\n");
- return false;
- }
-
- if ((enable & ~0x03) != 0) {
- fprintf(stderr, "enable_gpio_streaming: invalid enable format\n");
- return false;
- }
-
- op_gpio_cmd cmd;
- op_generic_t reply;
-
- memset(&cmd, 0, sizeof(cmd));
- init_etf_hdrs(&cmd.h, d_addr, 0, CONTROL_CHAN, -1);
- cmd.op.opcode = OP_GPIO_STREAM;
- cmd.op.len = sizeof(cmd.op);
- cmd.op.rid = d_next_rid++;
- cmd.op.bank = static_cast<uint8_t>(bank);
- cmd.op.value = htons((uint16_t)enable);
- cmd.op.mask = 0; // not used
- cmd.eop.opcode = OP_EOP;
- cmd.eop.len = sizeof(cmd.eop);
-
- pending_reply p(cmd.op.rid, &reply, sizeof(reply));
- if (!transmit_cmd_and_wait(&cmd, sizeof(cmd), &p, DEF_CMD_TIMEOUT))
- return false;
-
- bool success = (ntohx(reply.ok) == 1);
- return success;
- }
-
-} // namespace usrp2
diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h
deleted file mode 100644
index eee26358ea..0000000000
--- a/usrp2/host/lib/usrp2_impl.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2009,2010 Free Software Foundation, Inc.
- *
- * 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_IMPL_H
-#define INCLUDED_USRP2_IMPL_H
-
-#include <usrp2/usrp2.h>
-#include <usrp2/data_handler.h>
-#include <usrp2_eth_packet.h>
-#include <gruel/thread.h>
-#include <boost/scoped_ptr.hpp>
-#include "control.h"
-#include "ring.h"
-#include <string>
-
-#define MAX_SUBPKT_LEN 252
-
-namespace usrp2 {
-
- class eth_buffer;
- class pktfilter;
- class usrp2_thread;
- class usrp2_tune_result;
- class pending_reply;
- class ring;
-
- //! High-level d'board info
- struct db_info {
- int dbid;
- double freq_min; // Hz
- double freq_max; // Hz
- double gain_min; // dB
- double gain_max; // dB
- double gain_step_size; // dB
-
- db_info() : dbid(-1), freq_min(0), freq_max(0),
- gain_min(0), gain_max(0), gain_step_size(0) {}
- };
-
- class usrp2::impl : private data_handler
- {
- static const size_t NRIDS = 256;
- static const size_t NCHANS = 32;
-
- eth_buffer *d_eth_buf;
- std::string d_interface_name;
- pktfilter *d_pf;
- std::string d_addr; // FIXME: use u2_mac_addr_t instead
-
- boost::thread_group d_rx_tg;
- volatile bool d_bg_running; // TODO: multistate if needed
-
- int d_rx_seqno;
- int d_tx_seqno;
- int d_next_rid;
- unsigned int d_num_rx_frames;
- unsigned int d_num_rx_missing;
- unsigned int d_num_rx_overruns;
- unsigned int d_num_rx_bytes;
-
- unsigned int d_num_enqueued;
- gruel::mutex d_enqueued_mutex;
- gruel::condition_variable d_bg_pending_cond;
-
- // all pending_replies are stack allocated, thus no possibility of leaking these
- pending_reply *d_pending_replies[NRIDS]; // indexed by 8-bit reply id
-
- std::vector<ring_sptr> d_channel_rings; // indexed by 5-bit channel number
- gruel::mutex d_channel_rings_mutex;
-
- db_info d_tx_db_info;
- db_info d_rx_db_info;
-
- int d_tx_interp; // shadow tx interp
- int d_rx_decim; // shadow rx decim
-
- bool d_dont_enqueue;
-
- void inc_enqueued() {
- gruel::scoped_lock l(d_enqueued_mutex);
- d_num_enqueued++;
- }
-
- void dec_enqueued() {
- gruel::scoped_lock l(d_enqueued_mutex);
- if (--d_num_enqueued == 0)
- d_bg_pending_cond.notify_one();
- }
-
- static bool parse_mac_addr(const std::string &s, u2_mac_addr_t *p);
- void init_et_hdrs(u2_eth_packet_t *p, const std::string &dst);
- void init_etf_hdrs(u2_eth_packet_t *p, const std::string &dst,
- int word0_flags, int chan, uint32_t timestamp);
- void start_bg();
- void stop_bg();
- void init_config_rx_v2_cmd(op_config_rx_v2_cmd *cmd);
- void init_config_tx_v2_cmd(op_config_tx_v2_cmd *cmd);
- bool transmit_cmd_and_wait(void *cmd, size_t len, pending_reply *p, double secs=0.0);
- bool transmit_cmd(void *cmd, size_t len);
- virtual data_handler::result operator()(const void *base, size_t len);
- data_handler::result handle_control_packet(const void *base, size_t len);
- data_handler::result handle_data_packet(const void *base, size_t len);
- bool dboard_info();
- bool reset_db();
-
- public:
- impl(const std::string &ifc, props *p, size_t rx_bufsize);
- ~impl();
-
- std::string mac_addr() const { return d_addr; } // FIXME: convert from u2_mac_addr_t
- std::string interface_name() const { return d_interface_name; }
-
- // Rx
-
- bool set_rx_antenna(int ant);
- bool set_rx_gain(double gain);
- double rx_gain_min() { return d_rx_db_info.gain_min; }
- double rx_gain_max() { return d_rx_db_info.gain_max; }
- double rx_gain_db_per_step() { return d_rx_db_info.gain_step_size; }
- bool set_rx_lo_offset(double frequency);
- bool set_rx_center_freq(double frequency, tune_result *result);
- double rx_freq_min() { return d_rx_db_info.freq_min; }
- double rx_freq_max() { return d_rx_db_info.freq_max; }
- bool set_rx_decim(int decimation_factor);
- int rx_decim() { return d_rx_decim; }
- bool set_rx_scale_iq(int scale_i, int scale_q);
- bool set_gpio_ddr(int bank, uint16_t value, uint16_t mask);
- bool set_gpio_sels(int bank, std::string src);
- bool enable_gpio_streaming(int bank, int enable);
- bool write_gpio(int bank, uint16_t value, uint16_t mask);
- bool read_gpio(int bank, uint16_t *value);
- bool start_rx_streaming(unsigned int channel, unsigned int items_per_frame);
- bool start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time);
- bool sync_and_start_rx_streaming_at(unsigned int channel, unsigned int items_per_frame, unsigned int time);
- bool rx_samples(unsigned int channel, rx_sample_handler *handler);
- bool flush_rx_samples(unsigned int channel);
- bool stop_rx_streaming(unsigned int channel);
- unsigned int rx_overruns() const { return d_num_rx_overruns; }
- unsigned int rx_missing() const { return d_num_rx_missing; }
-
- // Tx
-
- bool set_tx_antenna(int ant);
- bool set_tx_gain(double gain);
- double tx_gain_min() { return d_tx_db_info.gain_min; }
- double tx_gain_max() { return d_tx_db_info.gain_max; }
- double tx_gain_db_per_step() { return d_tx_db_info.gain_step_size; }
- bool set_tx_lo_offset(double frequency);
- bool set_tx_center_freq(double frequency, tune_result *result);
- double tx_freq_min() { return d_tx_db_info.freq_min; }
- double tx_freq_max() { return d_tx_db_info.freq_max; }
- bool set_tx_interp(int interpolation_factor);
- int tx_interp() { return d_tx_interp; }
- void default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q);
- bool set_tx_scale_iq(int scale_i, int scale_q);
-
- bool tx_32fc(unsigned int channel,
- const std::complex<float> *samples,
- size_t nsamples,
- const tx_metadata *metadata);
-
- bool tx_16sc(unsigned int channel,
- const std::complex<int16_t> *samples,
- size_t nsamples,
- const tx_metadata *metadata);
-
- bool tx_raw(unsigned int channel,
- const uint32_t *items,
- size_t nitems,
- const tx_metadata *metadata);
-
- // misc
-
- bool config_mimo(int flags);
- bool fpga_master_clock_freq(long *freq);
- bool adc_rate(long *rate);
- bool dac_rate(long *rate);
- bool tx_daughterboard_id(int *dbid);
- bool rx_daughterboard_id(int *dbid);
-
- // low level
-
- bool burn_mac_addr(const std::string &new_addr);
- bool sync_to_pps();
- bool sync_every_pps(bool enable);
- std::vector<uint32_t> peek32(uint32_t addr, uint32_t words);
- bool poke32(uint32_t addr, const std::vector<uint32_t> &data);
-
- // Receive thread, need to be public for boost::bind
- void bg_loop();
- };
-
-} // namespace usrp2
-
-#endif /* INCLUDED_USRP2_IMPL_H */
diff --git a/usrp2/host/lib/usrp2_socket_opener.cc b/usrp2/host/lib/usrp2_socket_opener.cc
deleted file mode 100644
index 27d3935e47..0000000000
--- a/usrp2/host/lib/usrp2_socket_opener.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * 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/>.
- */
-
-/*!
- * setuid root program that opens a socket using (PF_PACKET, SOCK_RAW,
- * htons(0xBEEF)), and sends the resulting file descriptor by way of
- * of the file descriptor specified as the first command line argument.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#elif defined(HAVE_NETINET_IN_H)
-#include <netinet/in.h>
-#endif
-
-
-ssize_t
-write_fd(int fd, const void *ptr, size_t nbytes, int sendfd)
-{
- struct msghdr msg;
- struct iovec iov[1];
-
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- union {
- struct cmsghdr cm;
- char control[CMSG_SPACE(sizeof(int))];
- } control_un;
- struct cmsghdr *cmptr;
-
- msg.msg_control = control_un.control;
- msg.msg_controllen = sizeof(control_un.control);
-
- cmptr = CMSG_FIRSTHDR(&msg);
- cmptr->cmsg_len = CMSG_LEN(sizeof(int));
- cmptr->cmsg_level = SOL_SOCKET;
- cmptr->cmsg_type = SCM_RIGHTS;
- *((int *) CMSG_DATA(cmptr)) = sendfd;
-#else
- msg.msg_accrights = (char *) &sendfd;
- msg.msg_accrightslen = sizeof(int);
-#endif
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
-
- iov[0].iov_base = const_cast<void *>(ptr);
- iov[0].iov_len = nbytes;
- msg.msg_iov = iov;
- msg.msg_iovlen = 1;
-
- return sendmsg(fd, &msg, 0);
-}
-
-bool
-reset_eids()
-{
- if (setgid(getgid()) < 0){
- perror("setguid");
- return false;
- }
-
- if (setuid(getuid()) < 0){
- perror("setuid");
- return false;
- }
-
- return true;
-}
-
-
-static void
-usage()
-{
- fprintf(stderr, "usage: usrp2_socket_opener file-descriptor\n");
- exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
- if (argc != 2)
- usage();
-
- char *endptr;
- int unix_domain_fd = strtol(argv[1], &endptr, 0);
- if (*endptr != 0)
- usage();
-
- // FIXME get client credentials from unix_domain_fd using SCM_CREDENTIALS
-
- // open the raw socket
- int socket_fd = socket(PF_PACKET, SOCK_RAW, htons(0xBEEF));
- if (socket_fd == -1){
- perror("socket(PF_PACKET, SOCK_RAW, htons(0xBEEF))");
- // printf("errno = %d\n", errno);
- if (errno == EACCES || errno == ESPIPE){
- fprintf(stderr, "usrp2_socket_opener must be setuid root to open the socket using SOCK_RAW.\n");
- fprintf(stderr, "Running as root, please execute: \n");
- fprintf(stderr, " # chown root:usrp usrp2_socket_opener\n");
- fprintf(stderr, " # chmod 04750 usrp2_socket_opener\n");
- }
- exit(2);
- }
-
- // drop privs
- if (!reset_eids()){
- fprintf(stderr, "Can't drop root permissions\n");
- exit(3);
- }
-
- if (write_fd(unix_domain_fd, "", 1, socket_fd) != 1){
- perror("write_fd");
- exit(4);
- }
-
- return 0;
-}