From 9d1423b9506c89a51a10b6119d01ce9a82a13b0c Mon Sep 17 00:00:00 2001
From: eb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Date: Wed, 30 Apr 2008 03:52:31 +0000
Subject: Merged features/inband-usb -r6431:8293 into trunk.

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@8295 221aa14e-8319-0410-a670-987f0aec2ac5
---
 usrp/host/lib/inband/Makefile.am               |   7 +-
 usrp/host/lib/inband/fake_usrp.cc              | 135 -------
 usrp/host/lib/inband/fake_usrp.h               |  43 ---
 usrp/host/lib/inband/qa_inband_usrp_server.cc  | 239 ++++++++++--
 usrp/host/lib/inband/qa_inband_usrp_server.h   |   2 +
 usrp/host/lib/inband/test_usrp_inband.cc       | 298 --------------
 usrp/host/lib/inband/usrp_inband_usb_packet.cc | 235 +++++++-----
 usrp/host/lib/inband/usrp_inband_usb_packet.h  |   5 +
 usrp/host/lib/inband/usrp_rx.cc                |  63 ++-
 usrp/host/lib/inband/usrp_rx.h                 |   6 +-
 usrp/host/lib/inband/usrp_rx_stub.cc           | 181 +++++----
 usrp/host/lib/inband/usrp_rx_stub.h            |  12 +-
 usrp/host/lib/inband/usrp_server.cc            | 512 +++++++++++++++++++++++--
 usrp/host/lib/inband/usrp_server.h             |  12 +
 usrp/host/lib/inband/usrp_server.mbh           |   2 +-
 usrp/host/lib/inband/usrp_tx.cc                |  14 +-
 usrp/host/lib/inband/usrp_tx_stub.cc           |   6 +-
 usrp/host/lib/inband/usrp_usb_interface.cc     | 114 ++++--
 usrp/host/lib/inband/usrp_usb_interface.h      |   4 +-
 usrp/host/lib/legacy/fusb_linux.cc             |  26 +-
 20 files changed, 1154 insertions(+), 762 deletions(-)
 delete mode 100644 usrp/host/lib/inband/fake_usrp.cc
 delete mode 100644 usrp/host/lib/inband/fake_usrp.h
 delete mode 100644 usrp/host/lib/inband/test_usrp_inband.cc

(limited to 'usrp/host/lib')

diff --git a/usrp/host/lib/inband/Makefile.am b/usrp/host/lib/inband/Makefile.am
index 77d1f6699d..a41ac18b84 100644
--- a/usrp/host/lib/inband/Makefile.am
+++ b/usrp/host/lib/inband/Makefile.am
@@ -76,7 +76,6 @@ include_HEADERS =			\
 	usrp_usb_interface.h
 
 noinst_HEADERS =      			\
-	fake_usrp.h			\
 	qa_inband.h			\
 	qa_inband_packet_prims.h	\
 	qa_inband_usrp_server.h		\
@@ -109,14 +108,10 @@ libusrp_inband_qa_la_LIBADD =    	\
 # ------------------------------------------------------------------------
 
 noinst_PROGRAMS =			\
-	test_inband			\
-	test_usrp_inband
+	test_inband
 
 test_inband_SOURCES = test_inband.cc
 test_inband_LDADD   = libusrp_inband-qa.la
 
-test_usrp_inband_SOURCES = test_usrp_inband.cc
-test_usrp_inband_LDADD = libusrp_inband-qa.la
-
 MOSTLYCLEANFILES = \
 	$(BUILT_SOURCES) *~ *.pyc
diff --git a/usrp/host/lib/inband/fake_usrp.cc b/usrp/host/lib/inband/fake_usrp.cc
deleted file mode 100644
index 8a66d5c18c..0000000000
--- a/usrp/host/lib/inband/fake_usrp.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 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 <fake_usrp.h>
-#include <iostream>
-#include <usrp_inband_usb_packet.h>
-#include <mb_class_registry.h>
-#include <vector>
-
-typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit easy
-
-fake_usrp::fake_usrp()
-{
-  std::cout << "[fake_usrp] Initializing...\n";
-}
-
-fake_usrp::~fake_usrp() {}
-
-long
-fake_usrp::write_bus(transport_pkt *pkts, long n_bytes)
-{
-  std::cout << "[fake_usrp] Bytes over bus: " << n_bytes << "\n";
-
-  // I'm assuming that a control packet cannot exist in a burst of data packets,
-  // therefore i read only the first packet's channel in the current burst
-  if(pkts[0].chan() == 0x1f) {
-    return control_block(pkts, n_bytes);
-  } else {
-    return data_block(pkts, n_bytes);
-  }
-
-}
-
-long
-fake_usrp::data_block(transport_pkt *pkts, long n_bytes)
-{
-  std::cout << "[fake_usrp] Entering data block\n";
-
-  // Infer the number of packets from the byte count to do logical tests
-  long n_pkts = static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size()));
-  
-  std::cout << "[fake_usrp] Number of packets: " << n_pkts << "\n";
-
-  // The first packet should have the start of burst, and the last packet should have end of burst
-  if(pkts[0].start_of_burst() && pkts[n_pkts-1].end_of_burst()) {
-    std::cout << "[fake_usrp] Correct burst flags set\n";
-  } else {
-    std::cout << "[fake_usrp] Incorrect burst flags set!\n";
-    return 0;
-  }
-
-  // All other flags should be set to 0 (e.g., overrun should not be set yet) on ALL packets
-  for(int i=0; i < n_pkts; i++) {
-    if(pkts[i].overrun()) {
-      std::cout << "[fake_usrp] Incorrect set of overrun flag on transmit\n";
-      return 0;
-    } else if(pkts[i].underrun()) {
-      std::cout << "[fake_usrp] Incorrect set of underrun flag on transmit\n";
-      return 0;
-    } else if(pkts[i].dropped()) {
-      std::cout << "[fake_usrp] Incorrect set of drop flag on transmit\n";
-      return 0;
-    } 
-  }
-  std::cout << "[fake_usrp] Correct overrun, underrun, and drop flags on transmit (initialized to 0)\n";
-  
-  // The first packet should have a timestamp, other packets should have "NOW"
-  if(pkts[0].timestamp() != 0xffffffff) {
-    std::cout << "[fake_usrp] Correct timestamp on first packet\n";
-  } else {
-    std::cout << "[fake_usrp] Initial packet should not have the 0xffffffff timestamp\n";
-    return 0;
-  }
-
-  // Check that all of the other packets include the NOW timestamp
-  int check_stamps=1;
-  for(int i=1; i < n_pkts; i++)           // start at 1 to skip the first packet
-    if(pkts[i].timestamp() != 0xffffffff) 
-      check_stamps=0;
-
-  if(check_stamps) {
-    std::cout << "[fake_usrp] Correct NOW timestamps (0xffffffff) on intermediate burst packets\n";
-  } else {
-    std::cout << "[fake_usrp] Incorrect timestamps on intermediate burst packets\n";
-    return 0;
-  }
-
-  // Since we are being transparent about samples, we do not ensure the payload is correct, however
-  // it should be the case that if there are >1 packets, all packets except the last packet should
-  // have a full payload size
-  if(n_pkts > 1) {
-    int check_size=1;
-    for(int i=0; i < n_pkts-1; i++)
-      if(pkts[i].payload_len() != transport_pkt::max_payload())
-        check_size=0;
-
-    if(check_size) {
-      std::cout << "[fake_usrp] Correct payload size sanity check on packets\n";
-    } else {
-      std::cout << "[fake_usrp] Failed payload size sanity check\n";
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
-long
-fake_usrp::control_block(transport_pkt *pkts, long n_bytes)
-{
-  std::cout << "[fake_usrp] Entering control block\n";
-
-  return 1;
-}
diff --git a/usrp/host/lib/inband/fake_usrp.h b/usrp/host/lib/inband/fake_usrp.h
deleted file mode 100644
index 818c5a506d..0000000000
--- a/usrp/host/lib/inband/fake_usrp.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 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_FAKE_USRP_H
-#define INCLUDED_FAKE_USRP_H
-
-#include <usrp_inband_usb_packet.h>
-typedef usrp_inband_usb_packet transport_pkt;
-
-/*!
- * \brief Implements a fake USRP for testing without hardware
- */
-class fake_usrp
-{
- public:
-  fake_usrp();
-  ~fake_usrp();
-  long write_bus(transport_pkt *pkts, long n_bytes);
-
- protected:
-  long data_block(transport_pkt *pkts, long n_bytes);
-  long control_block(transport_pkt *pkts, long n_bytes);
-};
-
-#endif /* INCLUDED_FAKE_USRP_H */
-
diff --git a/usrp/host/lib/inband/qa_inband_usrp_server.cc b/usrp/host/lib/inband/qa_inband_usrp_server.cc
index b01e74e002..e457e8d64c 100644
--- a/usrp/host/lib/inband/qa_inband_usrp_server.cc
+++ b/usrp/host/lib/inband/qa_inband_usrp_server.cc
@@ -46,6 +46,8 @@ typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit e
 
 static bool verbose = false;
 
+static pmt_t s_timeout = pmt_intern("%timeout");
+
 // ----------------------------------------------------------------------------------------------
 
 class qa_alloc_top : public mb_mblock
@@ -903,10 +905,10 @@ class qa_rx_top : public mb_mblock
 
   long d_rx_chan;
 
-  long d_got_response_recv;
+  bool d_got_response_recv;
 
-  long d_nmsg_to_recv;
-  long d_nmsg_recvd;
+  mb_time d_t0;
+  double d_delta_t;
 
  public:
   qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
@@ -927,18 +929,19 @@ qa_rx_top::qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_
     d_got_response_recv(false)
 { 
 
-  d_nmsg_to_recv=12;
-  d_nmsg_recvd=0;
-  
   d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
   d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
 
   // Use the stub with the usrp_server
-  pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"), PMT_T);
+  pmt_t usrp_dict = pmt_make_dict();
+  // Set TX and RX interpolations
+  pmt_dict_set(usrp_dict,
+               pmt_intern("decim-rx"),
+               pmt_from_long(128));
+  pmt_dict_set(usrp_dict, pmt_intern("fake-usrp"), PMT_T);
 
   // Test the TX side
-  define_component("server", "usrp_server", usrp_server_dict);
+  define_component("server", "usrp_server", usrp_dict);
   connect("self", "rx0", "server", "rx0");
   connect("self", "cs", "server", "cs");
 }
@@ -967,17 +970,10 @@ qa_rx_top::run_tests()
              pmt_list2(PMT_NIL, 
                        pmt_from_long(0)));
 
-  // A small sleep is used to ensure, if working properly, a recv
-  // response comes through successfully before the close gets
-  // through
-  usleep(1000);
-
-  d_rx->send(s_cmd_stop_recv_raw_samples, 
-             pmt_list2(PMT_NIL, 
-                       pmt_from_long(0)));
-
-  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
-  
+  // Schedule a small timeout in which we expect to have received at least one
+  // packet worth of samples from the stub
+  d_t0 = mb_time::time();
+  schedule_one_shot_timeout(d_t0 + 0.01, PMT_NIL);
 }
 
 
@@ -992,26 +988,37 @@ qa_rx_top::handle_message(mb_message_sptr msg)
   
   pmt_t expected = pmt_nth(0, data);
   pmt_t status = pmt_nth(1, data);
+
+  // If we get a timeout we shutdown
+  if(pmt_eq(event, s_timeout)) {
+    if(verbose)
+      std::cout << "[qa_rx_top] Got timeout\n";
+    d_rx->send(s_cmd_stop_recv_raw_samples, 
+               pmt_list2(PMT_NIL, 
+                         pmt_from_long(0)));
+
+    d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
+    return;
+  }
   
   // For testing RX, an invocation handle is not generated by the stub,
   // therefore the same approach for testing is not used.  We simply
   // expect all responses to be true.
   if(pmt_eq(event, s_response_recv_raw_samples)) {
-    if(!pmt_eqv(status, PMT_T)) {
-      if(verbose)
-        std::cout << "Got: " << status << " Expected: " << PMT_T << "\n";
-      shutdown_all(PMT_F);
-      return;
-    }
-    else {
+    if(pmt_eqv(status, PMT_T)) {
+
       if(verbose)
         std::cout << "[qa_rx_top] Received expected response for message " 
-                  << d_nmsg_recvd
                   << " (" << event << ")\n";
 
       // All we want is 1 response receive!  Can't guarantee exact numbers
       d_got_response_recv = true;
     }
+    else {
+      if(verbose)
+        std::cout << "Got: " << status << " Expected: " << PMT_T << "\n";
+      shutdown_all(PMT_F);
+    }
     return;
   }
 
@@ -1026,8 +1033,7 @@ qa_rx_top::handle_message(mb_message_sptr msg)
   } else {
     if(verbose)
       std::cout << "[qa_rx_top] Received expected response for message " 
-                << d_nmsg_recvd
-      << " (" << event << ")\n";
+                << " (" << event << ")\n";
   }
 
   if (pmt_eq(msg->port_id(), d_rx->port_symbol())) {
@@ -1051,12 +1057,7 @@ qa_rx_top::handle_message(mb_message_sptr msg)
         std::cout << "[qa_rx_top] No response message before close\n";
       return;
     }
-
   }
-    
-  
-  d_nmsg_recvd++;
-
 }
 
 
@@ -1079,6 +1080,160 @@ qa_rx_top::check_allocation(mb_message_sptr msg)
 
 REGISTER_MBLOCK_CLASS(qa_rx_top);
 
+// ----------------------------------------------------------------------------------------------
+
+class qa_rid_top : public mb_mblock
+{
+  mb_port_sptr d_tx;
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+
+  long d_npongs;
+  long d_tcycles;
+  long d_cycles;
+  long d_max_rid;
+  
+  mb_time d_t0;
+  double d_delta_t;
+
+ public:
+  qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
+  ~qa_rid_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void run_tests();
+  void send_max_pings();
+};
+
+qa_rid_top::qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+  d_npongs = 0;
+  d_tcycles = 3;
+  d_cycles = d_tcycles;
+  d_max_rid = usrp_server::D_MAX_RID;
+  d_delta_t = 0.1;
+
+
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+ 
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_server_dict);
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+}
+
+qa_rid_top::~qa_rid_top(){}
+
+void
+qa_rid_top::initial_transition()
+{
+  run_tests();
+}
+
+void
+qa_rid_top::run_tests()
+{
+  if(verbose)
+    std::cout << "[qa_rid_top] Starting tests...\n";
+  
+  // Retrieve information about the USRP, then run tests
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open, PMT_T), 
+             pmt_from_long(0)));
+
+  // should be able to allocate 1 byte
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+  
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+  
+  // Need to start receiving to read from the USRP to get C/S responses
+  d_rx->send(s_cmd_start_recv_raw_samples, 
+             pmt_list2(PMT_NIL, 
+                       pmt_from_long(0)));
+
+  // Build a subpacket of MAX_RID pings and wait a small amount for all of the
+  // responses and fire off another MAX_RID.  If MAX_RID*2 responses are
+  // received, the RID recycling is working correctly.
+  // Schedule a timer in which we expect to have received all of the responses,
+  // which will send off another MAX_RID worth.
+  send_max_pings();
+  d_t0 = mb_time::time();
+  schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
+}
+
+void
+qa_rid_top::send_max_pings()
+{
+  pmt_t ping = pmt_list2(s_op_ping_fixed,
+                         pmt_list2(pmt_from_long(0),
+                                   pmt_from_long(0)));
+
+  pmt_t sub_packets = PMT_NIL;
+
+  for(int i=0; i<d_max_rid; i++) 
+    sub_packets = pmt_list_add(sub_packets, ping);
+
+  d_tx->send(s_cmd_to_control_channel,
+             pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T),
+                       sub_packets));
+}
+
+void
+qa_rid_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+
+  // If we get a timeout we ensure we got a maximum RID number of responses.
+  if(pmt_eq(event, s_timeout)) {
+    if(verbose)
+      std::cout << "[qa_rid_top] Got timeout, received so far: " 
+                << d_npongs << "\n";
+
+    d_cycles--;
+    
+    if(d_cycles==0 && d_npongs == d_max_rid*d_tcycles) {
+      shutdown_all(PMT_T);
+    }
+    else if(d_cycles==0) {
+
+      std::cout << "[qa_rid_top] d_npongs: " << d_npongs
+                << " expected: " << d_max_rid*d_tcycles
+                << std::endl;
+
+      shutdown_all(PMT_F);
+    }
+    else {
+      send_max_pings();
+      d_t0 = mb_time::time();
+      schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL);
+    }
+
+  }
+  else if(pmt_eq(event, s_response_from_control_channel))
+  {
+    d_npongs++;
+  }
+
+}
+
+REGISTER_MBLOCK_CLASS(qa_rid_top);
+
 
 // ----------------------------------------------------------------------------------------------
 
@@ -1398,3 +1553,17 @@ qa_inband_usrp_server::test_cs()
   
   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
 }
+
+void
+qa_inband_usrp_server::test_rid()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  // std::cout << "\n\n-----------------\n";
+  // std::cout << "  RUNNING RID TESTS  \n";
+
+  rt->run("top", "qa_rid_top", PMT_F, &result);
+  
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
diff --git a/usrp/host/lib/inband/qa_inband_usrp_server.h b/usrp/host/lib/inband/qa_inband_usrp_server.h
index 5db57c3ed4..52a4a0b067 100644
--- a/usrp/host/lib/inband/qa_inband_usrp_server.h
+++ b/usrp/host/lib/inband/qa_inband_usrp_server.h
@@ -34,6 +34,7 @@ class qa_inband_usrp_server : public CppUnit::TestCase {
   CPPUNIT_TEST(test_tx);
   CPPUNIT_TEST(test_rx);
   CPPUNIT_TEST(test_cs);
+  CPPUNIT_TEST(test_rid);
   CPPUNIT_TEST_SUITE_END();
 
  private:
@@ -43,6 +44,7 @@ class qa_inband_usrp_server : public CppUnit::TestCase {
   void test_tx();
   void test_rx();
   void test_cs();
+  void test_rid();
 };
 
 #endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */
diff --git a/usrp/host/lib/inband/test_usrp_inband.cc b/usrp/host/lib/inband/test_usrp_inband.cc
deleted file mode 100644
index 64fbf3a97a..0000000000
--- a/usrp/host/lib/inband/test_usrp_inband.cc
+++ /dev/null
@@ -1,298 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007 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 <stdio.h>
-#include <string.h>
-#include <iostream>
-#include <usrp_inband_usb_packet.h>
-#include <mb_mblock.h>
-#include <mb_runtime.h>
-#include <mb_protocol_class.h>
-#include <mb_class_registry.h>
-#include <pmt.h>
-#include "usrp_standard.h"
-
-typedef usrp_inband_usb_packet transport_pkt; 
-
-// Signal set for the USRP server
-static pmt_t s_cmd_open = pmt_intern("cmd-open");
-static pmt_t s_response_open = pmt_intern("response-open");
-static pmt_t s_cmd_close = pmt_intern("cmd-close");
-static pmt_t s_response_close = pmt_intern("response-close");
-static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
-static pmt_t s_response_allocate_channel = pmt_intern("response-allocate-channel");
-static pmt_t s_send_allocate_channel = pmt_intern("send-allocate-channel");
-static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
-static pmt_t s_response_deallocate_channel = pmt_intern("response-deallocate-channel");
-static pmt_t s_send_deallocate_channel = pmt_intern("send-deallocate-channel");
-static pmt_t s_cmd_max_capacity = pmt_intern("cmd-max-capacity");
-static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity");
-static pmt_t s_cmd_ntx_chan  = pmt_intern("cmd-ntx-chan");
-static pmt_t s_cmd_nrx_chan  = pmt_intern("cmd-nrx-chan");
-static pmt_t s_response_ntx_chan = pmt_intern("response-ntx-chan");
-static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan");
-static pmt_t s_cmd_current_capacity_allocation  = pmt_intern("cmd-current-capacity-allocation");
-static pmt_t s_response_current_capacity_allocation  = pmt_intern("response-current-capacity-allocation");
-static pmt_t s_cmd_xmit_raw_frame  = pmt_intern("cmd-xmit-raw-frame");
-static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
-
-bool loopback_p = false;
-bool counting_p = false;
-bool fake_usrp_p = false;
-char *prog_name;
-
-static void
-set_progname (char *path)
-{
-  char *p = strrchr (path, '/');
-  if (p != 0)
-    prog_name = p+1;
-  else
-    prog_name = path;
-}
-
-static void
-usage()
-{
-  fprintf (stderr, "usage: %s [-l]\n", prog_name);
-  fprintf (stderr, "  [-l] digital loopback in FPGA\n");
-  fprintf (stderr, "  [-c] counting in FPGA\n");
-  fprintf (stderr, "  [-f] fake usrp\n");
-
-  exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
-  int ch;
-
-  set_progname(argv[0]);
-
-  mb_runtime_sptr rt = mb_make_runtime();
-  pmt_t result = PMT_T;
-
-  while ((ch = getopt(argc, argv, "flc")) != EOF) {
-    switch(ch) {
-    
-      case 'l':
-        loopback_p = true;
-        break;
-
-      case 'c':
-        counting_p = true;
-        break;
-      
-      case 'f':
-        fake_usrp_p = true;
-        break;
-
-      default:
-        usage();
-    }
-  }
-
-
-  std::cout << "[test_usrp_inband] Starting...\n";
-
-  rt->run("top", "test_usrp_inband_top", PMT_F, &result);
-}
-
-class test_usrp_inband_top : public mb_mblock
-{
-  mb_port_sptr d_tx;
-  mb_port_sptr d_cs;
-
-  long d_tx_chan;
-
- public:
-  test_usrp_inband_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg);
-  ~test_usrp_inband_top();
-  void initial_transition();
-  void handle_message(mb_message_sptr msg);
-
- protected:
-  void open_usrp();
-  void close_usrp();
-  void check_message(mb_message_sptr msg);
-  void allocate_channel();
-  void send_packets();
-};
-
-test_usrp_inband_top::test_usrp_inband_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg)
-  : mb_mblock(runtime, instance_name, user_arg)
-{ 
-  std::cout << "[TEST_USRP_INBAND_TOP] Initializing...\n";
-  
-  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
-  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
-  
-  // Test the TX side
-
-  // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP
-  pmt_t usrp_server_dict = pmt_make_dict();
-
-  if(fake_usrp_p)
-    pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), pmt_intern("usrp_usb_interface_stub"));
-
-  define_component("server", "usrp_server", usrp_server_dict);
-  connect("self", "tx0", "server", "tx0");
-  connect("self", "cs", "server", "cs");
-}
-
-test_usrp_inband_top::~test_usrp_inband_top()
-{
-}
-
-void
-test_usrp_inband_top::initial_transition()
-{
-  open_usrp();
-}
-
-void
-test_usrp_inband_top::handle_message(mb_message_sptr msg)
-{
-  pmt_t event = msg->signal();		// the "name" of the message
-  pmt_t port_id = msg->port_id();	// which port it came in on
-  pmt_t data = msg->data();
-  pmt_t metadata = msg->metadata();
-  pmt_t status;
-
-  if (pmt_eq(port_id, d_cs->port_symbol())) {	// message came in on our control/status port
-
-    //---------- OPEN RESPONSE ----------//
-    if (pmt_eq(event, s_response_open)) {
-      status = pmt_nth(1, data);
-
-      if(pmt_eq(status, PMT_T)) {
-        std::cout << "[TEST_USRP_INBAND_TOP] Success opening USRP\n";
-      }
-      else {
-        std::cout << "[TEST_USRP_INBAND_TOP] Received error message opening USRP\n";
-        shutdown_all(PMT_F);
-      }
-
-      allocate_channel();
-
-      return;
-    }
-    //--------- CLOSE RESPONSE -----------//
-    else if (pmt_eq(event, s_response_close)) {
-      status = pmt_nth(1, data);
-      
-      if(pmt_eq(status, PMT_T)) {
-        std::cout << "[TEST_USRP_INBAND_TOP] Successfully closed USRP\n";
-      }
-      else {
-        std::cout << "[TEST_USRP_INBAND_TOP] Received error message closing USRP\n";
-        shutdown_all(PMT_F);
-      }
-
-      shutdown_all(PMT_T);
-
-      return;
-    }
-  }
-    
-  if (pmt_eq(port_id, d_tx->port_symbol())) {
-
-    //---------- ALLOCATE RESPONSE ---------//
-    if(pmt_eq(event, s_response_allocate_channel)) {
-      status = pmt_nth(1, data);
-      pmt_t channel = pmt_nth(2, data);
-
-      if(pmt_eq(status, PMT_T)) {
-        d_tx_chan = pmt_to_long(channel);
-        std::cout << "[TEST_USRP_INBAND_TOP] Received allocation on channel " << d_tx_chan << "\n";
-      }
-      else {
-        std::cout << "[TEST_USRP_INBAND_TOP] Error allocating channel\n";
-        shutdown_all(PMT_F);
-      }
-      
-      send_packets();
-
-      return;
-    }
-    //----------- XMIT RESPONSE ------------//
-    else if(pmt_eq(event, s_response_xmit_raw_frame)) {
-      status = pmt_nth(1, data);
-
-      if(pmt_eq(status, PMT_T)) {
-        std::cout << "[TEST_USRP_INBAND_TOP] Transmission successful\n";
-      }
-      else {
-        std::cout << "[TEST_USRP_INBAND_TOP] Failed transmission\n";
-        shutdown_all(PMT_F);
-      }
-
-      close_usrp();
-
-      return;
-    }
-  }
-
-  std::cout << "[TEST_USRP_INBAND_TOP] Received unhandled message: " << event << "\n";
-}
-
-void
-test_usrp_inband_top::allocate_channel()
-{
-  std::cout << "[TEST_USRP_INBAND_TOP] Requesting channel allocation...\n";
-  
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
-}
-
-void
-test_usrp_inband_top::send_packets()
-{
-  std::cout << "[TEST_USRP_INBAND_TOP] Sending single packet..\n";
-  d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(pmt_from_long(1), pmt_from_long(d_tx_chan), pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
-  
-}
-
-void
-test_usrp_inband_top::open_usrp()
-{
-  pmt_t usrp = pmt_from_long(0);
-
-  long rx_mode = 0;
-
-  if(loopback_p)
-    rx_mode |= usrp_standard_rx::FPGA_MODE_LOOPBACK;
-  if(counting_p)
-    rx_mode |= usrp_standard_rx::FPGA_MODE_COUNTING;
-
-  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, usrp));
-}
-
-void
-test_usrp_inband_top::close_usrp()
-{
-  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
-}
-
-REGISTER_MBLOCK_CLASS(test_usrp_inband_top);
diff --git a/usrp/host/lib/inband/usrp_inband_usb_packet.cc b/usrp/host/lib/inband/usrp_inband_usb_packet.cc
index ee4cb22f3f..2f02ecc3ff 100644
--- a/usrp/host/lib/inband/usrp_inband_usb_packet.cc
+++ b/usrp/host/lib/inband/usrp_inband_usb_packet.cc
@@ -30,6 +30,14 @@
 #include <stdio.h>
 #include <string.h>
 
+/*!
+ * \brief Aligns the packet payload on a 32 bit boundary.  This is essential to
+ * all control/status packets so that the inband FPGA code can parse them
+ * easily.
+ *
+ * \returns true if successful or if the packet was already aligned; false if it
+ * cannot be aligned.
+ */
 bool usrp_inband_usb_packet::align32()
 {
   int p_len = payload_len();
@@ -44,18 +52,20 @@ bool usrp_inband_usb_packet::align32()
   if((MAX_PAYLOAD - p_len) < bytes_needed)
     return false;
     
-  p_len += bytes_needed;
-
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = p_len;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(bytes_needed);
 
   return true;
 }
 
+/*!
+ * \brief Adds a ping command to the current control packet.
+ *
+ * The \p rid is the rid to be associated with the ping response and \p ping_val
+ * is currently unused.
+ *
+ * \returns true if adding the ping command was successful, false otherwise
+ * (i.e. no space in the current packet).
+ */
 bool usrp_inband_usb_packet::cs_ping(long rid, long ping_val)
 {
   if(!align32())
@@ -78,17 +88,20 @@ bool usrp_inband_usb_packet::cs_ping(long rid, long ping_val)
   *payload = host_to_usrp_u32(ping);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_PING_LEN;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
 
   return true;
 }
 
-
+/*!
+ * \brief Adds a ping response to the packet.  This is used by the fake USRP
+ * code to generate fake responses for pings.
+ *
+ * The \p rid is the RID to be associated with the response and \p ping_val is
+ * currently unused.
+ *
+ * \returns true if the ping reply was added successfully, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val) 
 {
   if(!align32())
@@ -111,16 +124,20 @@ bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val)
   *payload = host_to_usrp_u32(ping);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_PING_LEN;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_PING_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a write register command to the packet.
+ *
+ * The \p reg_num is the register number for which the value \p val will be
+ * written to.
+ *
+ * \returns true if the command was added to the packet successfully, false
+ * otherwise.
+ */
 bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val)
 {
   if(!align32())
@@ -149,16 +166,19 @@ bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val)
   *payload = host_to_usrp_u32((uint32_t) val);
   
   // Rebuild the header to update the payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_WRITEREG_LEN;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_WRITEREG_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a write register masked command to the packet.
+ *
+ * The \p reg_num is the register number for which the value \p val will be
+ * written, masked by \p mask
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long mask)
 {
   if(!align32())
@@ -190,16 +210,19 @@ bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long ma
   *payload = host_to_usrp_u32((uint32_t) mask);
   
   // Rebuild the header to update the payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_WRITEREGMASKED_LEN;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_WRITEREGMASKED_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a read register message to the packet. 
+ *
+ * The \p rid will be the associated RID returned with the response, and \p
+ * reg_num is the register to be read.
+ * 
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num)
 {
   if(!align32())
@@ -222,16 +245,22 @@ bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num)
   *payload = host_to_usrp_u32(read_reg);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_READREG_LEN;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_READREG_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a read register reply response to the current packet.  This is
+ * used by the fake USRP code to generate fake register read responses for
+ * testing.
+ *
+ * The \p rid is the associated RID to be included in the response, \p reg_num
+ * is the register the read is coming from, and \p reg_val is the value of the
+ * read.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long reg_val)
 {
   if(!align32())
@@ -258,16 +287,19 @@ bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long reg_
   *payload = host_to_usrp_u32((uint32_t) reg_val); 
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_READREGREPLY_LEN;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_READREGREPLY_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds a delay command to the current packet.
+ *
+ * The \p ticks parameter is the number of clock ticks the FPGA should delay
+ * parsing for, which is added to the packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_delay(long ticks)
 {
   if(!align32())
@@ -289,16 +321,16 @@ bool usrp_inband_usb_packet::cs_delay(long ticks)
   *payload = host_to_usrp_u32(delay);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_DELAY_LEN;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_DELAY_LEN);
 
   return true;
 }
 
+/*!
+ * \brief
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len)
 {
   if(!align32())
@@ -328,16 +360,20 @@ bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size
    memcpy(payload, i2c_data, data_len);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + i2c_len;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + i2c_len);
 
   return true;
 }
 
+/*!
+ * \brief Adds an I2C read command to the current packet.
+ *
+ * The \p rid is the associated RID to return with the read response, \p
+ * i2c_addr is the address to read from on the I2C bus, and \p n_bytes is the
+ * number of bytes to be read from the bus.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes)
 {
   if(!align32())
@@ -367,16 +403,20 @@ bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes)
   *payload = host_to_usrp_u32(word1);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_I2CREAD_LEN;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + CS_I2CREAD_LEN);
 
   return true;
 }
 
+/*!
+ * \brief Adds an I2C read reply response to the current packet.  This is used
+ * by the fake USRP code to generate fake I2C responses.
+ *
+ * The \p rid is the RID to be associated with the response, \p i2c_addr is the
+ * address on the I2C bus that the \p i2c_data of \p i2c_data_len was read from.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len)
 {
   if(!align32())
@@ -406,16 +446,16 @@ bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr, uint8_t
   memcpy(payload, i2c_data, i2c_data_len);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + i2c_len;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + i2c_len);
 
   return true;
 }
 
+/*!
+ * \brief Adds a SPI write command to the current packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len)
 {
   if(!align32())
@@ -454,16 +494,16 @@ bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long opt_he
   memcpy(payload, spi_data, spi_data_len);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + spi_len;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + spi_len);
 
   return true;
 }
 
+/*!
+ * \brief Adds a SPI bus read command to the packet.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes)
 {
   if(!align32())
@@ -508,16 +548,17 @@ bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format, lo
   *payload = host_to_usrp_u32(word);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + CS_SPIREAD_LEN;
+  incr_header_len(CS_FIXED_LEN + CS_SPIREAD_LEN);
 
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
-  
   return true;
 }
 
+/*!
+ * \brief Adds an SPI read reply to the current packet.  This is used by the
+ * fake USRP code to generate fake responses for SPI reads.
+ *
+ * \returns true if the command was added to the packet, false otherwise.
+ */
 bool usrp_inband_usb_packet::cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len)
 {
   if(!align32())
@@ -546,30 +587,32 @@ bool usrp_inband_usb_packet::cs_spi_read_reply(long rid, uint8_t *spi_data, long
   memcpy(payload, spi_data, spi_data_len);
 
   // Update payload length
-  int h_flags = flags();
-  int h_chan = chan();
-  int h_tag = tag();
-  int h_payload_len = payload_len() + CS_FIXED_LEN + spi_len;
-
-  set_header(h_flags, h_chan, h_tag, h_payload_len);
+  incr_header_len(CS_FIXED_LEN + spi_len);
 
   return true;
 }
 
-// Takes an offset to the beginning of a subpacket and extracts the
-// length of the subpacket
+/*!
+ * \brief Since all control packets contain subpackets which have the length of
+ * the subpacket at a uniform location in the subpacket, this will return the
+ * subpacket length given a byte offset of the start of the subpacket from the beginning of the packet.
+ *
+ * \returns the length of the subpacket
+ */
 int usrp_inband_usb_packet::cs_len(int payload_offset) {
   uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset)));
   return (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK;
 }
 
-// The following method takes an offset within the packet payload to extract
-// a control/status subpacket and construct a pmt response which includes the
-// proper signal and arguments specified by usrp-low-level-cs.  The USRP
-// server could therefore use this to read subpackets and pass them responses
-// back up to the application.  It's arguable that only reply packets should
-// be parsed here, however we parse others for use in debugging or failure
-// reporting on the transmit side of packets.
+/*!
+ * \brief The following method takes an offset within the packet payload to
+ * extract a control/status subpacket and constructs a pmt response which
+ * includes the proper signal and arguments specified by usrp-low-level-cs.  The
+ * USRP server could therefore use this to read subpackets and pass them
+ * responses back up to the application.  It's arguable that only reply packets
+ * should be parsed here, however we parse others for use in debugging or
+ * failure reporting on the transmit side of packets.
+ */
 pmt_t usrp_inband_usb_packet::read_subpacket(int payload_offset) {
 
   uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset)));
diff --git a/usrp/host/lib/inband/usrp_inband_usb_packet.h b/usrp/host/lib/inband/usrp_inband_usb_packet.h
index 8c19b1aeba..8f59d1b656 100644
--- a/usrp/host/lib/inband/usrp_inband_usb_packet.h
+++ b/usrp/host/lib/inband/usrp_inband_usb_packet.h
@@ -31,6 +31,7 @@
 
 static const int USB_PKT_SIZE = 512;   // bytes
 static const int MAX_PAYLOAD = USB_PKT_SIZE-2*sizeof(uint32_t);
+static const int CONTROL_CHAN = 0x1f;
 
 class usrp_inband_usb_packet {
   //
@@ -150,6 +151,10 @@ public:
                        | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT));
     d_word0 = host_to_usrp_u32(word0);
   }
+
+  void incr_header_len(int val) {
+    set_header(flags(), chan(), tag(), payload_len() + val);
+  }
   
   uint32_t timestamp() const {
     return usrp_to_host_u32(d_timestamp);
diff --git a/usrp/host/lib/inband/usrp_rx.cc b/usrp/host/lib/inband/usrp_rx.cc
index caa2d71754..71c042a50e 100644
--- a/usrp/host/lib/inband/usrp_rx.cc
+++ b/usrp/host/lib/inband/usrp_rx.cc
@@ -40,25 +40,30 @@ typedef usrp_inband_usb_packet transport_pkt;
 
 static const bool verbose = false;
 
+bool usrp_rx_stop;
+
 usrp_rx::usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
   : mb_mblock(rt, instance_name, user_arg),
-    d_disk_write(false)
+    d_disk_write(false),
+    d_disk_write_pkt(false)   // if true, writes full packet, else just the payload
 {
   d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
   
-  //d_disk_write=true;
-  
   if(d_disk_write) {
-    d_ofile.open("rx_data.dat",std::ios::binary|std::ios::out);
+    d_ofile0.open("rx_data_chan0.dat",std::ios::binary|std::ios::out);
+    d_ofile1.open("rx_data_chan1.dat",std::ios::binary|std::ios::out);
     d_cs_ofile.open("rx_cs.dat",std::ios::binary|std::ios::out);
   }
+  
+  usrp_rx_stop = false;
 
 }
 
 usrp_rx::~usrp_rx() 
 {
   if(d_disk_write) {
-    d_ofile.close();
+    d_ofile0.close();
+    d_ofile1.close();
     d_cs_ofile.close();
   }
 }
@@ -69,6 +74,12 @@ usrp_rx::initial_transition()
   
 }
 
+/*!
+ * \brief Handles incoming signals to to the m-block, wihch should only ever be
+ * a single message: cmd-usrrp-rx-start-reading.  There is no signal to stop
+ * reading as the m-block goes in to a forever loop to read inband packets from
+ * the bus.
+ */
 void
 usrp_rx::handle_message(mb_message_sptr msg)
 {
@@ -85,6 +96,17 @@ usrp_rx::handle_message(mb_message_sptr msg)
   }
 }
 
+/*!
+ * \brief Performs the actual reading of data from the USB bus, called by
+ * handle_message() when a cmd-usrp-rx-start-reading signal is received.  
+ *
+ * The method enters a forever loop where it continues to read data from the bus
+ * and generate read responses to the higher layer.  Currently, shared memory is
+ * used to exit this loop.
+ *
+ * The \p data parameter is a PMT list which contains only a single element, an
+ * invocation handle which will be returned with all read respones.
+ */
 void
 usrp_rx::read_and_respond(pmt_t data)
 {
@@ -104,7 +126,7 @@ usrp_rx::read_and_respond(pmt_t data)
     std::cout << "[usrp_rx] Waiting for packets..\n";
 
   // Read by 512 which is packet size and send them back up
-  while(1) {
+  while(!usrp_rx_stop) {
 
     pmt_t v_pkt = pmt_make_u8vector(pkt_size, 0);
     transport_pkt *pkt = 
@@ -124,19 +146,38 @@ usrp_rx::read_and_respond(pmt_t data)
 
     d_cs->send(s_response_usrp_rx_read, 
                pmt_list3(PMT_NIL, PMT_T, v_pkt));
-    if(verbose)
+    if(verbose && 0)
       std::cout << "[usrp_rx] Read 1 packet\n";
     
     if(d_disk_write) {
-      if(pkt->chan() == 0x1f)
+      if(pkt->chan() == CONTROL_CHAN)
         d_cs_ofile.write((const char *)pkt, transport_pkt::max_pkt_size());
-      else
-        d_ofile.write((const char *)pkt, transport_pkt::max_pkt_size());
+      else {
+        if(d_disk_write_pkt) {
+          if(pkt->chan() == 0)
+            d_ofile0.write((const char *)pkt, transport_pkt::max_pkt_size());
+          else if(pkt->chan() == 1)
+            d_ofile1.write((const char *)pkt, transport_pkt::max_pkt_size());
+        } else {
+          if(pkt->chan() == 0)
+            d_ofile0.write((const char *)pkt->payload(), transport_pkt::max_payload());
+          else if(pkt->chan() == 1)
+            d_ofile1.write((const char *)pkt->payload(), transport_pkt::max_payload());
+        }
+      }
 
       d_cs_ofile.flush();
-      d_ofile.flush();
+      d_ofile0.flush();
+      d_ofile1.flush();
     }
   }
+  
+  usrp_rx_stop = false;
+
+  if(verbose) {
+    std::cout << "[USRP_RX] Stopping...\n";
+    fflush(stdout);
+  }
 }
 
 REGISTER_MBLOCK_CLASS(usrp_rx);
diff --git a/usrp/host/lib/inband/usrp_rx.h b/usrp/host/lib/inband/usrp_rx.h
index e1a90a7813..10104bd665 100644
--- a/usrp/host/lib/inband/usrp_rx.h
+++ b/usrp/host/lib/inband/usrp_rx.h
@@ -26,6 +26,8 @@
 
 class usrp_standard_rx;
 
+extern bool usrp_rx_stop;   // used to communicate a 'stop' to the RX stub
+
 /*!
  * \brief Implements the low level usb interface to the USRP
  */
@@ -35,7 +37,9 @@ class usrp_rx : public mb_mblock
   usrp_standard_rx     *d_urx;
   
   bool d_disk_write;
-  std::ofstream d_ofile;
+  bool d_disk_write_pkt;
+  std::ofstream d_ofile0;
+  std::ofstream d_ofile1;
   std::ofstream d_cs_ofile;
   
  public:
diff --git a/usrp/host/lib/inband/usrp_rx_stub.cc b/usrp/host/lib/inband/usrp_rx_stub.cc
index 4bdb106b18..1c96b7a7ac 100644
--- a/usrp/host/lib/inband/usrp_rx_stub.cc
+++ b/usrp/host/lib/inband/usrp_rx_stub.cc
@@ -43,7 +43,7 @@ typedef usrp_inband_usb_packet transport_pkt;
 
 static const bool verbose = false;
 
-bool usrp_rx_stop;
+bool usrp_rx_stop_stub;
 
 // Used for the fake control packet response code to send the responses back up
 // the RX.  The TX stub dumps responses in to this queue.
@@ -52,15 +52,32 @@ std::queue<pmt_t> d_cs_queue;
 usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
   : mb_mblock(rt, instance_name, user_arg),
     d_samples_per_frame((long)(126)),
+    d_decim_rx(128),
     d_amplitude(16384),
     d_disk_write(false)
 {
+
+  // Information about the rates are passed all the way from the app in the form
+  // of a dictionary.  We use this to read the RX decimation rate and compute
+  // the approximate number of MS/s as a form of flow control for the stub.
+  pmt_t usrp_dict = user_arg;
+
+  if (pmt_is_dict(usrp_dict)) {
+    // Read the RX decimation rate
+    if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, 
+                                      pmt_intern("decim-rx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(decim_rx, PMT_NIL)) 
+        d_decim_rx = pmt_to_long(decim_rx);
+    }
+  }
+
   d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
   
   // initialize NCO
   double freq = 100e3;
   int interp = 32;			    // 32 -> 4MS/s
-  double sample_rate = 128e6 / interp;	
+  double sample_rate = 64e6 / interp;	
   d_nco.set_freq(2*M_PI * freq/sample_rate);
 
   //d_disk_write = true;
@@ -68,7 +85,7 @@ usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt
   if(d_disk_write)
     d_ofile.open("raw_rx.dat",std::ios::binary|std::ios::out);
   
-  usrp_rx_stop = false;
+  usrp_rx_stop_stub = false;
 }
 
 usrp_rx_stub::~usrp_rx_stub() 
@@ -80,7 +97,6 @@ usrp_rx_stub::~usrp_rx_stub()
 void 
 usrp_rx_stub::initial_transition()
 {
-  
 }
 
 void
@@ -90,94 +106,121 @@ usrp_rx_stub::handle_message(mb_message_sptr msg)
   pmt_t port_id = msg->port_id();
   pmt_t data = msg->data(); 
 
+  if (pmt_eq(msg->signal(), s_timeout)
+      && !pmt_eq(msg->data(), s_done)) {
+  
+    if(!usrp_rx_stop_stub) 
+      read_and_respond();
+    else {  // requested to stop
+      cancel_timeout(msg->metadata());
+      usrp_rx_stop_stub=false;
+      if(verbose)
+        std::cout << "[USRP_RX_STUB] Stopping RX stub\n";
+    }
+
+  }
+
   // Theoretically only have 1 message to ever expect, but
   // want to make sure its at least what we want
-  if(pmt_eq(port_id, d_cs->port_symbol())) {
+  if(pmt_eq(port_id, d_cs->port_symbol())
+      && pmt_eqv(event, s_cmd_usrp_rx_start_reading)) {
 
     if(verbose)
-      std::cout << "[USRP_RX_STUB] Starting...\n";
+      std::cout << "[USRP_RX_STUB] Starting with decim @ " 
+                << d_decim_rx << std::endl;
     
-    if(pmt_eqv(event, s_cmd_usrp_rx_start_reading))
-      read_and_respond(data);
+      start_packet_timer();
   }
 }
 
+// Setup a periodic timer which will drive packet generation
 void
-usrp_rx_stub::read_and_respond(pmt_t data)
+usrp_rx_stub::start_packet_timer()
 {
+  d_t0 = mb_time::time();   // current time
+
+  // Calculate the inter-packet arrival time.  
+  double samples_per_sec = (64.0/(double)d_decim_rx)*1000000.0;
+  double frames_per_sec = samples_per_sec / (double)d_samples_per_frame;
+  double frame_rate = 1.0 / frames_per_sec;
+
+  if(verbose) {
+    std::cout << "[USRP_RX_STUB] Scheduling periodic packet generator\n";
+    std::cout << "\tsamples_per_sec: " << samples_per_sec << std::endl;
+    std::cout << "\tframes_per_sec: " << frames_per_sec << std::endl;
+    std::cout << "\tframe_rate: " << frame_rate << std::endl;
+  }
 
-  while(!usrp_rx_stop) {
+  schedule_periodic_timeout(d_t0 + frame_rate, mb_time(frame_rate), PMT_T);
+}
 
-    long nsamples_this_frame = d_samples_per_frame;
+void
+usrp_rx_stub::read_and_respond()
+{
 
-    size_t nshorts = 2 * nsamples_this_frame;	// 16-bit I & Q
-    long channel = 0;
-    long n_bytes = nshorts*2;
-    pmt_t uvec = pmt_make_s16vector(nshorts, 0);
-    size_t ignore;
-    int16_t *samples = pmt_s16vector_writeable_elements(uvec, ignore);
+  long nsamples_this_frame = d_samples_per_frame;
 
-    // fill in the complex sinusoid
+  size_t nshorts = 2 * nsamples_this_frame;	// 16-bit I & Q
+  long channel = 0;
+  long n_bytes = nshorts*2;
+  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
+  size_t ignore;
+  int16_t *samples = pmt_s16vector_writeable_elements(uvec, ignore);
 
-    for (int i = 0; i < nsamples_this_frame; i++){
+  // fill in the complex sinusoid
 
-      if (1){
-        gr_complex s;
-        d_nco.sincos(&s, 1, d_amplitude);
-        // write 16-bit i & q
-        samples[2*i] =   (int16_t) s.real();
-        samples[2*i+1] = (int16_t) s.imag();
-      }
-      else {
-        gr_complex s(d_amplitude, d_amplitude);
+  for (int i = 0; i < nsamples_this_frame; i++){
 
-        // write 16-bit i & q
-        samples[2*i] =   (int16_t) s.real();
-        samples[2*i+1] = (int16_t) s.imag();
-      }
+    if (1){
+      gr_complex s;
+      d_nco.sincos(&s, 1, d_amplitude);
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
     }
-    
-    if(d_disk_write)
-      d_ofile.write((const char *)samples, n_bytes);
-  
-    pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
-    transport_pkt *pkt =
-      (transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
+    else {
+      gr_complex s(d_amplitude, d_amplitude);
 
-    pkt->set_header(0, channel, 0, n_bytes);
-    pkt->set_timestamp(0xffffffff);
-    memcpy(pkt->payload(), samples, n_bytes);
-    
-    d_cs->send(s_response_usrp_rx_read, pmt_list3(PMT_NIL, PMT_T, v_pkt));
-
-    // Now lets check the shared CS queue between the TX and RX stub.  Each
-    // element in a queue is a list where the first element is an invocation
-    // handle and the second element is a PMT u8 vect representation of the
-    // CS packet response which can just be passed transparently.
-    while(!d_cs_queue.empty()) {
-      
-      pmt_t cs_pkt = d_cs_queue.front();
-      d_cs_queue.pop();
-
-      pmt_t invocation_handle = pmt_nth(0, cs_pkt);
-      pmt_t v_pkt = pmt_nth(1, cs_pkt);
-
-      d_cs->send(s_response_usrp_rx_read,   
-                 pmt_list3(invocation_handle, 
-                           PMT_T, 
-                           v_pkt));  // Take the front CS pkt
-
-      
-      if(verbose)
-        std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n";
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
     }
-
   }
   
-  usrp_rx_stop = false;
+  if(d_disk_write)
+    d_ofile.write((const char *)samples, n_bytes);
+
+  pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0);
+  transport_pkt *pkt =
+    (transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
+
+  pkt->set_header(0, channel, 0, n_bytes);
+  pkt->set_timestamp(0xffffffff);
+  memcpy(pkt->payload(), samples, n_bytes);
+  
+  d_cs->send(s_response_usrp_rx_read, pmt_list3(PMT_NIL, PMT_T, v_pkt));
 
-  if(verbose)
-    std::cout << "[USRP_RX_STUB] Got fake RX stop\n";
+  // Now lets check the shared CS queue between the TX and RX stub.  Each
+  // element in a queue is a list where the first element is an invocation
+  // handle and the second element is a PMT u8 vect representation of the
+  // CS packet response which can just be passed transparently.
+  while(!d_cs_queue.empty()) {
+    
+    pmt_t cs_pkt = d_cs_queue.front();
+    d_cs_queue.pop();
+
+    pmt_t invocation_handle = pmt_nth(0, cs_pkt);
+    pmt_t v_pkt = pmt_nth(1, cs_pkt);
+
+    d_cs->send(s_response_usrp_rx_read,   
+               pmt_list3(invocation_handle, 
+                         PMT_T, 
+                         v_pkt));  // Take the front CS pkt
+
+    
+    if(verbose)
+      std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n";
+  }
 
 }
 
diff --git a/usrp/host/lib/inband/usrp_rx_stub.h b/usrp/host/lib/inband/usrp_rx_stub.h
index 5a75bf00ac..9cf308a992 100644
--- a/usrp/host/lib/inband/usrp_rx_stub.h
+++ b/usrp/host/lib/inband/usrp_rx_stub.h
@@ -31,9 +31,12 @@
 
 typedef usrp_inband_usb_packet transport_pkt;
 
-extern bool usrp_rx_stop;   // used to communicate a 'stop' to the RX stub
+extern bool usrp_rx_stop_stub;   // used to communicate a 'stop' to the RX stub
 extern std::queue<pmt_t> d_cs_queue;
 
+static pmt_t s_timeout = pmt_intern("%timeout");
+static pmt_t s_done = pmt_intern("done");
+
 /*!
  * \brief Implements the low level usb interface to the USRP
  */
@@ -45,6 +48,10 @@ class usrp_rx_stub : public mb_mblock
   usrp_standard_rx* d_urx;
   
   long		d_samples_per_frame;
+  long    d_decim_rx;
+
+  mb_time d_t0;
+  double d_delta_t;
   
   // for generating sine wave output
   ui_nco<float,float>	d_nco;
@@ -61,8 +68,9 @@ class usrp_rx_stub : public mb_mblock
   void handle_message(mb_message_sptr msg);
 
  private:
-  void read_and_respond(pmt_t data);
+  void read_and_respond();
   void read_data();
+  void start_packet_timer();
  
 };
   
diff --git a/usrp/host/lib/inband/usrp_server.cc b/usrp/host/lib/inband/usrp_server.cc
index 1948a43b29..6a3643e568 100644
--- a/usrp/host/lib/inband/usrp_server.cc
+++ b/usrp/host/lib/inband/usrp_server.cc
@@ -29,6 +29,8 @@
 #include <vector>
 #include <usrp_usb_interface.h>
 #include <string.h>
+#include <fpga_regs_common.h>
+#include <fpga_regs_standard.h>
 
 #include <symbols_usrp_server_cs.h>
 #include <symbols_usrp_channel.h>
@@ -53,13 +55,42 @@ str(long x)
 
 usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
   : mb_mblock(rt, instance_name, user_arg),
+  d_fpga_debug(false),
+  d_interp_tx(128),     // these should match the lower level defaults (rx also)
+  d_decim_rx(128),
   d_fake_rx(false)
 {
   if(verbose)
     std::cout << "[USRP_SERVER] Initializing...\n";
 
   // Dictionary for arguments to all of the components
-  pmt_t usrp_dict = user_arg;
+  d_usrp_dict = user_arg;
+  
+  if (pmt_is_dict(d_usrp_dict)) {
+
+    if(pmt_t fpga_debug = pmt_dict_ref(d_usrp_dict, 
+                                      pmt_intern("fpga-debug"), 
+                                      PMT_NIL)) {
+      if(pmt_eqv(fpga_debug, PMT_T)) 
+        d_fpga_debug=true;
+    }
+    
+    // Read the TX interpolations
+    if(pmt_t interp_tx = pmt_dict_ref(d_usrp_dict, 
+                                      pmt_intern("interp-tx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(interp_tx, PMT_NIL)) 
+        d_interp_tx = pmt_to_long(interp_tx);
+    }
+    
+    // Read the RX decimation rate
+    if(pmt_t decim_rx = pmt_dict_ref(d_usrp_dict, 
+                                      pmt_intern("decim-rx"), 
+                                      PMT_NIL)) {
+      if(!pmt_eqv(decim_rx, PMT_NIL)) 
+        d_decim_rx = pmt_to_long(decim_rx);
+    }
+  }
   
   // control & status port
   d_cs = define_port("cs", "usrp-server-cs", true, mb_port::EXTERNAL);	
@@ -82,7 +113,7 @@ usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t
                                mb_port::EXTERNAL));
   }
 
-  define_component("usrp", "usrp_usb_interface", usrp_dict);
+  define_component("usrp", "usrp_usb_interface", d_usrp_dict);
   connect("self", "cs_usrp", "usrp", "cs");
 
   d_defer=false;
@@ -108,6 +139,10 @@ usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t
   //d_fake_rx=true;
 }
 
+/*!
+ * \brief resets the assigned capacity and owners of each RX and TX channel from
+ * allocations.
+ */
 void
 usrp_server::reset_channels()
 {
@@ -136,6 +171,11 @@ usrp_server::initial_transition()
   // the initial transition
 }
 
+/*!
+ * \brief Reads all incoming messages to USRP server from the TX, RX, and the CS
+ * ports.  This drives the state of USRP server and dispatches based on the
+ * message.
+ */
 void
 usrp_server::handle_message(mb_message_sptr msg)
 {
@@ -178,6 +218,9 @@ usrp_server::handle_message(mb_message_sptr msg)
       pmt_t status = pmt_nth(1, data);
       d_cs->send(s_response_open, pmt_list2(invocation_handle, status));
 
+      //reset_all_registers();
+      //initialize_registers();
+
       if(pmt_eqv(status,PMT_T)) {
         d_opened = true;
         d_defer = false;
@@ -209,7 +252,7 @@ usrp_server::handle_message(mb_message_sptr msg)
 
       // Do not report back responses if they were generated from a
       // command packet
-      if(channel == 0x1f)
+      if(channel == CONTROL_CHAN)
         return;
 
       // Find the port through the owner of the channel
@@ -470,7 +513,14 @@ usrp_server::handle_message(mb_message_sptr msg)
   std::cout << "[USRP_SERVER] unhandled msg: " << msg << std::endl;
 }
 
-// Return -1 if it is not an RX port, or an index
+/*!
+ * \brief Takes a port_symbol() as parameter \p port_id and is used to determine
+ * if the port is a TX port, or to find an index in the d_tx vector which stores
+ * the port.
+ *
+ * \returns -1 if \p port_id is not in the d_tx vector (i.e., it's not a TX
+ * port), otherwise returns an index in the d_tx vector which stores the port.
+ */
 int usrp_server::tx_port_index(pmt_t port_id) {
 
   for(int i=0; i < (int) d_tx.size(); i++) 
@@ -480,7 +530,14 @@ int usrp_server::tx_port_index(pmt_t port_id) {
   return -1;
 }
 
-// Return -1 if it is not an RX port, or an index
+/*!
+ * \brief Takes a port_symbol() as parameter \p port_id and is used to determine
+ * if the port is an RX port, or to find an index in the d_rx vector which
+ * stores the port.
+ *
+ * \returns -1 if \p port_id is not in the d_rx vector (i.e., it's not an RX
+ * port), otherwise returns an index in the d_rx vector which stores the port.
+ */
 int usrp_server::rx_port_index(pmt_t port_id) {
   
   for(int i=0; i < (int) d_rx.size(); i++) 
@@ -490,8 +547,12 @@ int usrp_server::rx_port_index(pmt_t port_id) {
   return -1;
 }
 
-// Go through all TX and RX channels, sum up the assigned capacity
-// and return it
+/*!
+ * \brief Determines the current total capacity allocated by all RX and TX
+ * channels.
+ *
+ * \returns the total allocated capacity
+ */
 long usrp_server::current_capacity_allocation() {
   long capacity = 0;
 
@@ -504,6 +565,14 @@ long usrp_server::current_capacity_allocation() {
   return capacity;
 }
     
+
+/*!
+ * \brief Called by the handle_message() method if the incoming message to
+ * usrp_server is to allocate a channel (cmd-allocate-channel).  The method
+ * checks if the requested capacity exists and if so it will reserve it for the
+ * caller on the channel that is returned via a response-allocate-channel
+ * signal.
+ */
 void 
 usrp_server::handle_cmd_allocate_channel(
                                 mb_port_sptr port, 
@@ -564,9 +633,13 @@ usrp_server::handle_cmd_allocate_channel(
   return;
 }
 
-// Check the port type and deallocate assigned capacity based on this, ensuring
-// that the owner of the method invocation is the owner of the port and that the
-// channel number is valid.
+/*!
+ * \brief Called by the handle_message() method if the incoming message to
+ * usrp_server is to deallocate a channel (cmd-deallocate-channel).  The method
+ * ensures that the sender of the signal owns the channel and that the channel
+ * number is valid.  A response-deallocate-channel signal is sent back with the
+ * result of the deallocation.
+ */
 void 
 usrp_server::handle_cmd_deallocate_channel(
                               mb_port_sptr port, 
@@ -591,8 +664,26 @@ usrp_server::handle_cmd_deallocate_channel(
   return;
 }
 
-void usrp_server::handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data) {
-
+/*!
+ * \brief Called by the handle_message() method if the incoming message to
+ * usrp_server is to transmit a frame (cmd-xmit-raw-frame).  The method
+ * allocates enough memory to support a burst of packets which contain the frame
+ * over the bus of the frame, sets the packet headers, and sends a signal to the
+ * lower block for the data (packets) to be written to the bus.  
+ *
+ * The \p port the command was sent on and the channel info (\p chan_info) of
+ * the channel the frame is to be transmitted on are passed to ensure that the
+ * caller owns the channel.
+ *
+ * The \p data parameter is in the format of a cmd-xmit-raw-frame signal.
+ *
+ * The properties
+ */
+void usrp_server::handle_cmd_xmit_raw_frame(
+                              mb_port_sptr port, 
+                              std::vector<struct channel_info> &chan_info, 
+                              pmt_t data) 
+{
   size_t n_bytes, psize;
   long max_payload_len = transport_pkt::max_payload();
 
@@ -667,7 +758,8 @@ void usrp_server::handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struc
               << invocation_handle << std::endl;
     
   // The actual response to the write will be generated by a
-  // s_response_usrp_write
+  // s_response_usrp_write since we cannot determine whether to transmit was
+  // successful until we hear from the lower layers.
   d_cs_usrp->send(s_cmd_usrp_write, 
                   pmt_list3(invocation_handle, 
                             pmt_from_long(channel), 
@@ -676,7 +768,29 @@ void usrp_server::handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struc
   return;
 }
 
-void usrp_server::handle_cmd_to_control_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data) 
+/*!
+ * \brief Called by the handle_message() method to parse incoming control/status
+ * signals (cmd-to-control-channel).  
+ * 
+ * The \p port the command was sent on and the channel info (\p chan_info) of
+ * the channel are passed to ensure that the caller owns the channel.
+ *
+ * The \p data parameter is in the format of a PMT list, where each element
+ * follows the format of a control/status signal (i.e. op-ping-fixed).
+ *
+ * The method will parse all of the C/S commands included in \p data and place
+ * the commands in to a lower level packet sent to the control channel.  The
+ * method will pack as many commands as possible in t oa single packet, and once
+ * it is fill generate as many lower level packets as needed.
+ *
+ * Anything that needs to be returned to the sender of the signal (i.e. the
+ * value of a register) will be generated by the parse_control_pkt() method as
+ * the responses to the commands are read back from the USRP.
+ */
+void usrp_server::handle_cmd_to_control_channel(
+                            mb_port_sptr port, 
+                            std::vector<struct channel_info> &chan_info, 
+                            pmt_t data) 
 {
 
   pmt_t invocation_handle = pmt_nth(0, data);
@@ -687,7 +801,10 @@ void usrp_server::handle_cmd_to_control_channel(mb_port_sptr port, std::vector<s
 
   size_t psize;
   long payload_len = 0;
-  long channel = 0x1f;
+  long channel = CONTROL_CHAN;
+
+  if(verbose)
+    std::cout << "[USRP_SERVER] Handling " << n_subpkts << " commands\n";
 
   // The design of the following code is optimized for simplicity, not
   // performance.  To performance optimize this code, the total size in bytes
@@ -990,8 +1107,22 @@ void usrp_server::handle_cmd_to_control_channel(mb_port_sptr port, std::vector<s
   return;
 }
 
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is a
+ * command to start reading samples from the USRP (cmd-start-recv-raw-samples).  
+ *
+ * The \p port the command was sent on and the channel info (\p chan_info) of
+ * the channel are passed to ensure that the caller owns the channel.
+ *
+ * The \p data parameter should be in the format of a cmd-start-recv-raw-samples
+ * command where the first element in the list is an invocation handle, and the
+ * second is the channel the signal generator wants to receive the samples on.
+ */
 void
-usrp_server::handle_cmd_start_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data)
+usrp_server::handle_cmd_start_recv_raw_samples(
+                                  mb_port_sptr port, 
+                                  std::vector<struct channel_info> &chan_info, 
+                                  pmt_t data)
 {
   pmt_t invocation_handle = pmt_nth(0, data);
   long channel = pmt_to_long(pmt_nth(1, data));
@@ -1032,6 +1163,18 @@ usrp_server::handle_cmd_start_recv_raw_samples(mb_port_sptr port, std::vector<st
   return;
 }
 
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * stop receiving samples from the USRP (cmd-stop-recv-raw-samples).
+ *
+ * The \p port the command was sent on and the channel info (\p chan_info) of
+ * the channel are passed to ensure that the caller owns the channel.
+ *
+ * The \p data parameter should be in the format of a cmd-stop-recv-raw-samples
+ * command where the first element in the list is an invocation handle, and the
+ * second is the channel the signal generator wants to stop receiving the
+ * samples from.
+ */
 void
 usrp_server::handle_cmd_stop_recv_raw_samples(
                         mb_port_sptr port, 
@@ -1067,7 +1210,22 @@ usrp_server::handle_cmd_stop_recv_raw_samples(
   return;
 }
 
-// Read the packet header, determine the port by the channel owner
+/*!
+ * \brief Called by the handle_message() method when an incoming signal is
+ * generated to USRP server that contains raw samples from the USRP.  This
+ * method generates the response-recv-raw-samples signals that are the result of
+ * a cmd-start-recv-raw-samples signal.
+ *
+ * The raw lower-level packet is extracted from \p data, where the format for \p
+ * data is a PMT list.  The PMT \p data list should contain an invocation handle
+ * as the first element, the status of the lower-level read as the second
+ * element, and a uniform vector representation of the packets as the third
+ * element.  
+ *
+ * The packet contains a channel field that the samples are destined to, and the
+ * method determines where to send the samples based on this channel since each
+ * channel has an associated port which allocated it.
+ */
 void
 usrp_server::handle_response_usrp_read(pmt_t data)
 {
@@ -1106,7 +1264,7 @@ usrp_server::handle_response_usrp_read(pmt_t data)
     return;
   
   // If the packet is a C/S packet, parse it separately
-  if(channel == 0x1f) {
+  if(channel == CONTROL_CHAN) {
     parse_control_pkt(invocation_handle, pkt);
     return;
   }
@@ -1137,14 +1295,28 @@ usrp_server::handle_response_usrp_read(pmt_t data)
                  PMT_T);
 
   d_rx[port]->send(s_response_recv_raw_samples,
-                   pmt_list5(invocation_handle,
+                   pmt_list6(invocation_handle,
                              status,
                              v_samples,
                              pmt_from_long(pkt->timestamp()),
+                             pmt_from_long(channel),
                              properties));
   return;
 }
 
+/*!
+ * \brief Called by handle_response_usrp_read() when the incoming packet has a
+ * channel of CONTROL_CHAN.  This means that the incoming packet contains a
+ * response for a command sent to the control channel, which this method will
+ * parse.
+ *
+ * The \p pkt parameter is a pointer to the full packet (transport_pkt) in
+ * memory.
+ *
+ * Given that all commands sent to the control channel that require responses
+ * will carry an RID (request ID), the method will use the RID passed back with
+ * the response to determine which port the response should be sent on.
+ */
 void
 usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
 {
@@ -1190,6 +1362,9 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
         return;
 
       pmt_t owner = d_rids[srid].owner;
+      
+      // Return the RID
+      d_rids[srid].owner = PMT_NIL;
 
       // FIXME: should be 1 response for all subpackets here ?
       if((port = tx_port_index(owner)) != -1)
@@ -1225,6 +1400,9 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
         return;
       
       pmt_t owner = d_rids[srid].owner;
+      
+      // Return the RID
+      d_rids[srid].owner = PMT_NIL;
 
       // FIXME: should be 1 response for all subpackets here ?
       if((port = tx_port_index(owner)) != -1)
@@ -1261,6 +1439,9 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
         return;
 
       pmt_t owner = d_rids[srid].owner;
+      
+      // Return the RID
+      d_rids[srid].owner = PMT_NIL;
 
       if((port = tx_port_index(owner)) != -1)
         d_tx[port]->send(s_response_from_control_channel,
@@ -1294,6 +1475,9 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
         return;
 
       pmt_t owner = d_rids[srid].owner;
+      
+      // Return the RID
+      d_rids[srid].owner = PMT_NIL;
 
       if((port = tx_port_index(owner)) != -1)
         d_tx[port]->send(s_response_from_control_channel,
@@ -1317,6 +1501,10 @@ usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt)
   }
 }
 
+/*!
+ * \brief Used to recall all incoming signals that were deferred when USRP
+ * server was in the initialization state.
+ */
 void
 usrp_server::recall_defer_queue()
 {
@@ -1335,6 +1523,25 @@ usrp_server::recall_defer_queue()
   return;
 }
 
+/*!
+ * \brief Commonly called by any method which handles outgoing frames or control
+ * packets to the USRP to check if the port on which the signal was sent owns
+ * the channel the outgoing packet will be associated with.   This helps ensure
+ * that applications do not send data on other application's ports.
+ *
+ * The \p port parameter is the port symbol that the caller wishes to determine
+ * owns the channel specified by \p chan_info.  
+ *
+ * The \p signal_info parameter is a PMT list containing two elements: the
+ * response signal to use if the permissions are invalid, and the invocation
+ * handle that was passed.  This allows the method to generate detailed failure
+ * responses to signals without having to return some sort of structured
+ * information which the caller must then parse and interpret to determine the
+ * failure type.
+ *
+ * \returns true if \p port owns the channel specified by \p chan_info, false
+ * otherwise.
+ */
 bool
 usrp_server::check_valid(mb_port_sptr port,
                          long channel,
@@ -1346,7 +1553,7 @@ usrp_server::check_valid(mb_port_sptr port,
   pmt_t invocation_handle = pmt_nth(1, signal_info);
 
   // not a valid channel number?
-  if(channel >= (long)chan_info.size() && channel != 0x1f) {
+  if(channel >= (long)chan_info.size() && channel != CONTROL_CHAN) {
     port->send(response_signal, 
                pmt_list2(invocation_handle, 
                          s_err_channel_invalid));
@@ -1377,8 +1584,12 @@ usrp_server::check_valid(mb_port_sptr port,
   return true;
 }
 
-// Goes through the vector of RIDs and retreieves an
-// available one for use
+/*!
+ * \brief Finds the next available RID for internal USRP server use with control
+ * and status packets.
+ *
+ * \returns the next valid RID or -1 if no more RIDs are available.
+ */
 long
 usrp_server::next_rid()
 {
@@ -1386,7 +1597,264 @@ usrp_server::next_rid()
     if(pmt_eqv(d_rids[i].owner, PMT_NIL))
       return i;
 
+  if(verbose)
+    std::cout << "[USRP_SERVER] No RIDs left\n";
   return -1;
 }
 
+/*!
+ * \brief Called by handle_message() when USRP server gets a response that the
+ * USRP was opened successfully to initialize the registers using the new
+ * register read/write control packets.
+ */
+void
+usrp_server::initialize_registers()
+{
+  // We use handle_cmd_to_control_channel() to create the register writes using
+  // PMT_NIL as the response port to tell usrp_server not to pass the response
+  // up to any application.
+  if(verbose)
+    std::cout << "[USRP_SERVER] Initializing registers...\n";
+
+  // RX mode to normal (0)
+  set_register(FR_MODE, 0);
+
+  // FPGA debugging?
+  if(d_fpga_debug) {
+    set_register(FR_DEBUG_EN, 1);
+    // FIXME: need to figure out exact register writes to control daughterboard
+    // pins that need to be written to
+  } else {
+    set_register(FR_DEBUG_EN, 0);
+  }
+
+  // Set the transmit sample rate divisor, which is 4-1
+  set_register(FR_TX_SAMPLE_RATE_DIV, 3);
+
+  // Dboard IO buffer and register settings
+  set_register(FR_OE_0, (0xffff << 16) | 0x0000);
+  set_register(FR_IO_0, (0xffff << 16) | 0x0000);
+  set_register(FR_OE_1, (0xffff << 16) | 0x0000);
+  set_register(FR_IO_1, (0xffff << 16) | 0x0000);
+  set_register(FR_OE_2, (0xffff << 16) | 0x0000);
+  set_register(FR_IO_2, (0xffff << 16) | 0x0000);
+  set_register(FR_OE_3, (0xffff << 16) | 0x0000);
+  set_register(FR_IO_3, (0xffff << 16) | 0x0000);
+
+  // zero Tx side Auto Transmit/Receive regs
+  set_register(FR_ATR_MASK_0, 0); 
+  set_register(FR_ATR_TXVAL_0, 0);
+  set_register(FR_ATR_RXVAL_0, 0);
+  set_register(FR_ATR_MASK_1, 0); 
+  set_register(FR_ATR_TXVAL_1, 0);
+  set_register(FR_ATR_RXVAL_1, 0);
+  set_register(FR_ATR_MASK_2, 0);
+  set_register(FR_ATR_TXVAL_2, 0);
+  set_register(FR_ATR_RXVAL_2, 0);
+  set_register(FR_ATR_MASK_3, 0);
+  set_register(FR_ATR_TXVAL_3, 0);
+  set_register(FR_ATR_RXVAL_3, 0);
+
+  // Configure TX mux, this is a hacked value
+  set_register(FR_TX_MUX, 0x00000081);
+
+  // Set the interpolation rate, which is the rate divided by 4, minus 1
+  set_register(FR_INTERP_RATE, (d_interp_tx/4)-1);
+
+  // Apparently this register changes again
+  set_register(FR_TX_MUX, 0x00000981);
+
+  // Set the receive sample rate divisor, which is 2-1
+  set_register(FR_RX_SAMPLE_RATE_DIV, 1);
+
+  // DC offset
+  set_register(FR_DC_OFFSET_CL_EN, 0x0000000f);
+
+  // Reset the DC correction offsets
+  set_register(FR_ADC_OFFSET_0, 0);
+  set_register(FR_ADC_OFFSET_1, 0);
+
+  // Some hard-coded RX configuration
+  set_register(FR_RX_FORMAT, 0x00000300);
+  set_register(FR_RX_MUX, 1);
+
+  // RX decimation rate is divided by two, then subtract 1
+  set_register(FR_DECIM_RATE, (d_decim_rx/2)-1);
+
+  // More hard coding
+  set_register(FR_RX_MUX, 0x000e4e41);
+
+  // Resetting RX registers
+  set_register(FR_RX_PHASE_0, 0);
+  set_register(FR_RX_PHASE_1, 0);
+  set_register(FR_RX_PHASE_2, 0);
+  set_register(FR_RX_PHASE_3, 0);
+  set_register(FR_RX_FREQ_0, 0x28000000);
+  set_register(FR_RX_FREQ_1, 0);
+  set_register(FR_RX_FREQ_2, 0);
+  set_register(FR_RX_FREQ_3, 0);
+
+  // Enable debug bus
+  set_register(FR_DEBUG_EN, 0xf);
+  set_register(FR_OE_0, -1);
+  set_register(FR_OE_1, -1);
+  set_register(FR_OE_2, -1);
+  set_register(FR_OE_3, -1);
+
+  // DEBUGGING
+  //check_register_initialization();
+}
+
+// FIXME: used for debugging to determine if all the registers are actually
+// being set correctly
+void
+usrp_server::check_register_initialization()
+{
+  // RX mode to normal (0)
+  read_register(FR_MODE);
+
+  // FPGA debugging?
+  if(d_fpga_debug) {
+    read_register(FR_DEBUG_EN);
+    // FIXME: need to figure out exact register writes to control daughterboard
+    // pins that need to be written to
+  } else {
+    read_register(FR_DEBUG_EN);
+  }
+
+  // Set the transmit sample rate divisor, which is 4-1
+  read_register(FR_TX_SAMPLE_RATE_DIV);
+
+  // Dboard IO buffer and register settings
+  read_register(FR_OE_0);
+  read_register(FR_IO_0);
+  read_register(FR_OE_1);
+  read_register(FR_IO_1);
+  read_register(FR_OE_2);
+  read_register(FR_IO_2);
+  read_register(FR_OE_3);
+  read_register(FR_IO_3);
+
+  // zero Tx side Auto Transmit/Receive regs
+  read_register(FR_ATR_MASK_0); 
+  read_register(FR_ATR_TXVAL_0);
+  read_register(FR_ATR_RXVAL_0);
+  read_register(FR_ATR_MASK_1); 
+  read_register(FR_ATR_TXVAL_1);
+  read_register(FR_ATR_RXVAL_1);
+  read_register(FR_ATR_MASK_2);
+  read_register(FR_ATR_TXVAL_2);
+  read_register(FR_ATR_RXVAL_2);
+  read_register(FR_ATR_MASK_3);
+  read_register(FR_ATR_TXVAL_3);
+  read_register(FR_ATR_RXVAL_3);
+
+  // Configure TX mux, this is a hacked value
+  read_register(FR_TX_MUX);
+
+  // Set the interpolation rate, which is the rate divided by 4, minus 1
+  read_register(FR_INTERP_RATE);
+
+  // Apparently this register changes again
+  read_register(FR_TX_MUX);
+
+  // Set the receive sample rate divisor, which is 2-1
+  read_register(FR_RX_SAMPLE_RATE_DIV);
+
+  // DC offset
+  read_register(FR_DC_OFFSET_CL_EN);
+
+  // Reset the DC correction offsets
+  read_register(FR_ADC_OFFSET_0);
+  read_register(FR_ADC_OFFSET_1);
+
+  // Some hard-coded RX configuration
+  read_register(FR_RX_FORMAT);
+  read_register(FR_RX_MUX);
+
+  // RX decimation rate is divided by two, then subtract 1
+  read_register(FR_DECIM_RATE);
+
+  // More hard coding
+  read_register(FR_RX_MUX);
+
+  // Resetting RX registers
+  read_register(FR_RX_PHASE_0);
+  read_register(FR_RX_PHASE_1);
+  read_register(FR_RX_PHASE_2);
+  read_register(FR_RX_PHASE_3);
+  read_register(FR_RX_FREQ_0);
+  read_register(FR_RX_FREQ_1);
+  read_register(FR_RX_FREQ_2);
+  read_register(FR_RX_FREQ_3);
+}
+
+/*!
+ * \brief Used to generate FPGA register write commands to reset all of the FPGA
+ * registers to a value of 0.
+ */
+void
+usrp_server::reset_all_registers()
+{
+  for(int i=0; i<64; i++)
+    set_register(i, 0);
+}
+
+/*!
+ * \brief Used internally by USRP server to generate a control/status packet
+ * which contains a register write.
+ *
+ * The \p reg parameter is the register number that the value \p val will be
+ * written to.
+ */
+void
+usrp_server::set_register(long reg, long val)
+{
+  size_t psize;
+  long payload_len = 0;
+
+  pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
+  transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writeable_elements(v_packet, psize);
+  
+  pkt->set_header(0, CONTROL_CHAN, 0, payload_len);
+  pkt->set_timestamp(0xffffffff);
+
+  pkt->cs_write_reg(reg, val);
+
+  d_cs_usrp->send(s_cmd_usrp_write, 
+                  pmt_list3(PMT_NIL, 
+                            pmt_from_long(CONTROL_CHAN), 
+                            v_packet));
+}
+
+/*!
+ * \brief Used internally by USRP server to generate a control/status packet
+ * which contains a register read.  This is important to use internally so that
+ * USRP server can bypass the use of RIDs with register reads, as they are not
+ * needed and it would use up the finite number of RIDs available for use for
+ * applications to receive responses.
+ *
+ * The \p reg parameter is the register number that the value should be read
+ * from.
+ */
+void
+usrp_server::read_register(long reg)
+{
+  size_t psize;
+  long payload_len = 0;
+
+  pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0);
+  transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writeable_elements(v_packet, psize);
+  
+  pkt->set_header(0, CONTROL_CHAN, 0, payload_len);
+  pkt->set_timestamp(0xffffffff);
+
+  pkt->cs_read_reg(0, reg);
+
+  d_cs_usrp->send(s_cmd_usrp_write, 
+                  pmt_list3(PMT_NIL, 
+                            pmt_from_long(CONTROL_CHAN), 
+                            v_packet));
+}
+
 REGISTER_MBLOCK_CLASS(usrp_server);
diff --git a/usrp/host/lib/inband/usrp_server.h b/usrp/host/lib/inband/usrp_server.h
index 81dceb1f4f..09c82faac4 100644
--- a/usrp/host/lib/inband/usrp_server.h
+++ b/usrp/host/lib/inband/usrp_server.h
@@ -51,6 +51,13 @@ public:
   long d_ntx_chan;
   long d_nrx_chan;
 
+  pmt_t d_usrp_dict;
+
+  bool d_fpga_debug;
+  
+  long d_interp_tx;
+  long d_decim_rx;
+
   // Keep track of the request IDs
   struct rid_info {
     pmt_t owner;
@@ -114,6 +121,11 @@ private:
   bool check_valid(mb_port_sptr port, long channel, std::vector<struct channel_info> &chan_info, pmt_t signal_info);
   void parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt);
   long next_rid();
+  void initialize_registers();
+  void set_register(long reg, long val);
+  void read_register(long reg);
+  void check_register_initialization();
+  void reset_all_registers();
 };
 
 #endif /* INCLUDED_USRP_SERVER_H */
diff --git a/usrp/host/lib/inband/usrp_server.mbh b/usrp/host/lib/inband/usrp_server.mbh
index 3fd0db139b..ed7943fc37 100644
--- a/usrp/host/lib/inband/usrp_server.mbh
+++ b/usrp/host/lib/inband/usrp_server.mbh
@@ -202,7 +202,7 @@
 
   (:incoming
 
-   (response-recv-raw-samples invocation-handle status samples timestamp properties)
+   (response-recv-raw-samples invocation-handle status samples timestamp channel properties)
 
    ;; samples is a uniform numeric vector.  The contents of the sample
    ;; vector is treated as opaque and is passed from the FPGA
diff --git a/usrp/host/lib/inband/usrp_tx.cc b/usrp/host/lib/inband/usrp_tx.cc
index a7a5e4a894..da87775130 100644
--- a/usrp/host/lib/inband/usrp_tx.cc
+++ b/usrp/host/lib/inband/usrp_tx.cc
@@ -66,6 +66,10 @@ usrp_tx::initial_transition()
   
 }
 
+/*!
+ * \brief Handles incoming signals to to the m-block, wihch should only ever be
+ * a single message: cmd-usrp-tx-write.
+ */
 void
 usrp_tx::handle_message(mb_message_sptr msg)
 {
@@ -82,6 +86,14 @@ usrp_tx::handle_message(mb_message_sptr msg)
   }
 }
 
+/*!
+ * \brief Performs the actual writing of data to the USB bus, called by
+ * handle_message() when a cmd-usrp-tx-write signal is received.
+ *
+ * The \p data parameter is a PMT list which contains three mandatory elements,
+ * in the following order: an invocation handle, a channel, and a uniform vector
+ * of memory which contains the packets to be written to the bus.
+ */
 void
 usrp_tx::write(pmt_t data)
 {
@@ -121,7 +133,7 @@ usrp_tx::write(pmt_t data)
   for(int i=0; i < n_packets; i++) {
     
     if(d_disk_write) {
-      if(pkts[i].chan() == 0x1f)
+      if(pkts[i].chan() == CONTROL_CHAN)
         d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
       else
         d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
diff --git a/usrp/host/lib/inband/usrp_tx_stub.cc b/usrp/host/lib/inband/usrp_tx_stub.cc
index 7a9876322f..6cff3b4eef 100644
--- a/usrp/host/lib/inband/usrp_tx_stub.cc
+++ b/usrp/host/lib/inband/usrp_tx_stub.cc
@@ -103,7 +103,7 @@ usrp_tx_stub::write(pmt_t data)
   for(long i=0; i<n_packets; i++) {
 
     if(d_disk_write) {
-      if(pkts[i].chan() == 0x1f)
+      if(pkts[i].chan() == CONTROL_CHAN)
         d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
       else
         d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size());
@@ -112,7 +112,7 @@ usrp_tx_stub::write(pmt_t data)
       d_ofile.flush();
     }
 
-    if(pkts[i].chan() == 0x1f)
+    if(pkts[i].chan() == CONTROL_CHAN)
       parse_cs(invocation_handle, pkts[i]);
   }
 
@@ -140,7 +140,7 @@ usrp_tx_stub::parse_cs(pmt_t invocation_handle, transport_pkt pkt)
   transport_pkt *q_pkt =
     (transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
       
-  q_pkt->set_header(0, 0x1f, 0, 0);
+  q_pkt->set_header(0, CONTROL_CHAN, 0, 0);
   q_pkt->set_timestamp(0xffffffff);
 
   // We dispatch based on the control packet type, however we can extract the
diff --git a/usrp/host/lib/inband/usrp_usb_interface.cc b/usrp/host/lib/inband/usrp_usb_interface.cc
index 269ed2706d..51b6d4646c 100644
--- a/usrp/host/lib/inband/usrp_usb_interface.cc
+++ b/usrp/host/lib/inband/usrp_usb_interface.cc
@@ -47,12 +47,16 @@ static pmt_t s_shutdown = pmt_intern("%shutdown");
 static const bool verbose = false;
 
 
-
-// need to take number of TX and RX channels as parameter
+/*!
+ * \brief Initializes the USB interface m-block.
+ *
+ * The \p user_arg should be a PMT dictionary which can contain optional
+ * arguments for the block, such as the decimatoin and interpolation rate.
+ */
 usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
   : mb_mblock(rt, instance_name, user_arg),
-  d_fpga_debug(false),
   d_fake_usrp(false),
+  d_rx_reading(false),
   d_interp_tx(128),
   d_decim_rx(128),
   d_rf_freq(10e6),
@@ -86,7 +90,7 @@ usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instan
         d_interp_tx = pmt_to_long(interp_tx);
     }
     
-    // Read the RX interpolations
+    // Read the RX decimation rate
     if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, 
                                       pmt_intern("decim-rx"), 
                                       PMT_NIL)) {
@@ -134,8 +138,8 @@ usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instan
   d_tx_cs = define_port("tx_cs", "usrp-tx-cs", false, mb_port::INTERNAL);	
 
   // Connect to TX and RX
-  define_component("tx", tx_interface, PMT_F);
-  define_component("rx", rx_interface, PMT_F);
+  define_component("tx", tx_interface, usrp_dict);
+  define_component("rx", rx_interface, usrp_dict);
   connect("self", "rx_cs", "rx", "cs");
   connect("self", "tx_cs", "tx", "cs");
   
@@ -146,8 +150,6 @@ usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instan
   d_utx = NULL;
   d_urx = NULL;
   
-  d_fpga_debug=true;   // WARNING: DO NOT ENABLE WITH D'BOARDS OTHER THAN BASIC TX/RX
-
 }
 
 usrp_usb_interface::~usrp_usb_interface() 
@@ -161,6 +163,10 @@ usrp_usb_interface::initial_transition()
 
 }
 
+/*!
+ * \brief Handles all incoming signals to the block from the lowest m-blocks
+ * which read/write to the bus, or the higher m-block which is the USRP server.
+ */
 void
 usrp_usb_interface::handle_message(mb_message_sptr msg)
 {
@@ -256,6 +262,13 @@ usrp_usb_interface::handle_message(mb_message_sptr msg)
   std::cout << "[USRP_USB_INTERFACE] unhandled msg: " << msg << std::endl;
 }
 
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * open a USB connection to the USRP (cmd-usrp-open).
+ *
+ * The \p data parameter is a PMT list, where the elements are an invocation
+ * handle and the USRP number.
+ */
 void
 usrp_usb_interface::handle_cmd_open(pmt_t data)
 {
@@ -290,7 +303,7 @@ usrp_usb_interface::handle_cmd_open(pmt_t data)
     return;
   }
 
-  if(!d_utx->set_tx_freq (0,d_rf_freq)) {  // try setting center freq to 0
+  if(!d_utx->set_tx_freq (0,d_rf_freq) || !d_utx->set_tx_freq(1,d_rf_freq)) {  // try setting center freq to 0
     if (verbose)
       std::cout << "[USRP_USB_INTERFACE] Failed to set center frequency on TX\n";
     reply_data = pmt_list2(invocation_handle, PMT_F);
@@ -298,6 +311,14 @@ usrp_usb_interface::handle_cmd_open(pmt_t data)
     return;
   }
 
+  if(!d_utx->set_mux(0xBA98)) {
+    if (verbose)
+      std::cout << "[USRP_USB_INTERFACE] Failed to set TX mux\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
   d_utx->start();
 
   if (verbose)
@@ -321,33 +342,44 @@ usrp_usb_interface::handle_cmd_open(pmt_t data)
     return;
   }
 
-  if(!d_urx->set_rx_freq (0, d_rf_freq)) {
+  if(!d_urx->set_rx_freq (0, -d_rf_freq) || !d_urx->set_rx_freq(1, -d_rf_freq)) {
     if (verbose)
       std::cout << "[usrp_server] Failed to set center frequency on RX\n";
     reply_data = pmt_list2(invocation_handle, PMT_F);
     d_cs->send(s_response_usrp_open, reply_data);
     return;
   }
-
-  if(d_fpga_debug) {
-    d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf);
-    d_utx->_write_oe(0, 0xffff, 0xffff);
-    d_urx->_write_oe(0, 0xffff, 0xffff);
-    d_utx->_write_oe(1, 0xffff, 0xffff);
-    d_urx->_write_oe(1, 0xffff, 0xffff);
-
-//    while(1){
-//      for(int i=0; i<0xffff; i++) 
-//        d_urx->write_io(0, i, 0xffff);
-//    }
-  }
   
+  // Two channels ... this really needs to end up being set correctly by
+  // querying for what dboards are connected
+  if(!d_urx->set_mux(0x32103210)) {
+    if (verbose)
+      std::cout << "[USRP_USB_INTERFACE] Failed to set RX mux\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
   if (verbose)
     std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n";
+    
+//  d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf);
+//  d_utx->_write_oe(0, 0xffff, 0xffff);
+//  d_urx->_write_oe(0, 0xffff, 0xffff);
+//  d_utx->_write_oe(1, 0xffff, 0xffff);
+//  d_urx->_write_oe(1, 0xffff, 0xffff);
 
   d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
 }
 
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * write data to the USB bus (cmd-usrp-write). 
+ *
+ * The \p data parameter is a PMT list containing 3 mandatory elements in the
+ * following order: an invocation handle, channel, and a uniform vector
+ * representation of the packets.
+ */
 void
 usrp_usb_interface::handle_cmd_write(pmt_t data)
 {
@@ -366,6 +398,13 @@ usrp_usb_interface::handle_cmd_write(pmt_t data)
   return;
 }
 
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * start reading data from the USB bus (cmd-usrp-start-reading).
+ *
+ * The \p data parameter is a PMT list with a single element: an invocation
+ * handle which can be returned with the response.
+ */
 void
 usrp_usb_interface::handle_cmd_start_reading(pmt_t data)
 {
@@ -381,9 +420,18 @@ usrp_usb_interface::handle_cmd_start_reading(pmt_t data)
 
   d_rx_cs->send(s_cmd_usrp_rx_start_reading, pmt_list2(PMT_NIL, rx_handle));
 
+  d_rx_reading = true;
+
   return;
 }
 
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * stop reading data from the USB bus (cmd-usrp-stop-reading).
+ *
+ * The \p data parameter is a PMT list with a single element: an invocation
+ * handle which can be returned with the response.
+ */
 void
 usrp_usb_interface::handle_cmd_stop_reading(pmt_t data)
 {
@@ -392,22 +440,40 @@ usrp_usb_interface::handle_cmd_stop_reading(pmt_t data)
   if(!d_fake_usrp) {
     if(verbose)
       std::cout << "[USRP_USB_INTERFACE] Stopping RX...\n";
+    usrp_rx_stop = true;
+
+    // Used to allow a read() being called by a lower layer to complete before
+    // stopping, else there can be partial data left on the bus and can generate
+    // errors.
+    while(usrp_rx_stop) {usleep(1);}
     d_urx->stop();
   }
   else {
     if(verbose)
       std::cout << "[USRP_USB_INTERFACE] Stopping fake RX...\n";
-    usrp_rx_stop = true;  // extern to communicate with stub to wait
+    usrp_rx_stop_stub = true;  // extern to communicate with stub to wait
   }
 
+  d_rx_reading = false;
+
   return;
 }
 
+/*!
+ * \brief Called by the handle_message() method when the incoming signal is to
+ * close the USB connection to the USRP.
+ *
+ * The \p data parameter is a PMT list with a single element: an invocation
+ * handle which can be returned with the response.
+ */
 void
 usrp_usb_interface::handle_cmd_close(pmt_t data)
 {
   pmt_t invocation_handle = pmt_nth(0, data);
 
+  if(d_rx_reading)
+    handle_cmd_stop_reading(PMT_NIL);
+
   if(d_fake_usrp) {
     d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
     return;
diff --git a/usrp/host/lib/inband/usrp_usb_interface.h b/usrp/host/lib/inband/usrp_usb_interface.h
index 8efce2ff66..6c2c157680 100644
--- a/usrp/host/lib/inband/usrp_usb_interface.h
+++ b/usrp/host/lib/inband/usrp_usb_interface.h
@@ -42,10 +42,10 @@ class usrp_usb_interface : public mb_mblock
   long d_ntx_chan;
   long d_nrx_chan;
 
-  long d_fpga_debug;
-
   bool d_fake_usrp;
 
+  bool d_rx_reading;
+
   long d_interp_tx;
   long d_decim_rx;
 
diff --git a/usrp/host/lib/legacy/fusb_linux.cc b/usrp/host/lib/legacy/fusb_linux.cc
index 60687a1499..6dce8d9e04 100644
--- a/usrp/host/lib/legacy/fusb_linux.cc
+++ b/usrp/host/lib/legacy/fusb_linux.cc
@@ -386,14 +386,6 @@ fusb_ephandle_linux::stop ()
 {
   if (!d_started)
     return true;
-  
-  d_devhandle->_cancel_pending_rqsts (this);
-  d_devhandle->_reap (false);
-
-
-  usbdevfs_urb *urb;
-  while ((urb = completed_list_get ()) != 0)
-    free_list_add (urb);
 
   if (d_write_work_in_progress){
     free_list_add (d_write_work_in_progress);
@@ -407,11 +399,19 @@ fusb_ephandle_linux::stop ()
     d_read_buffer_end = 0;
   }
 
-  if (d_free_list.size () != (unsigned) d_nblocks)
-    fprintf (stderr, "d_free_list.size () = %d, d_nblocks = %d\n",
-	     d_free_list.size (), d_nblocks);
-    
-  assert (d_free_list.size () == (unsigned) d_nblocks);
+  d_devhandle->_cancel_pending_rqsts (this);
+  d_devhandle->_reap (false);
+
+  while (1){
+    usbdevfs_urb *urb;
+    while ((urb = completed_list_get ()) != 0)
+      free_list_add (urb);
+
+    if (d_free_list.size () == (unsigned) d_nblocks)
+      break;
+
+    d_devhandle->_reap(true);
+  }
 
   d_started = false;
   return true;
-- 
cgit v1.2.3