From eb95f431badf197b249131a3119a92bd5317621b Mon Sep 17 00:00:00 2001
From: Tom Rondeau <trondeau@vt.edu>
Date: Wed, 19 Oct 2011 16:40:14 -0700
Subject: Removed usrp(2) directories.

---
 usrp2/host/lib/usrp2_impl.cc | 1667 ------------------------------------------
 1 file changed, 1667 deletions(-)
 delete mode 100644 usrp2/host/lib/usrp2_impl.cc

(limited to 'usrp2/host/lib/usrp2_impl.cc')

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
-- 
cgit v1.2.3