commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r5753 - in gnuradio/branches/features/inband-usb: pmt/


From: gnychis
Subject: [Commit-gnuradio] r5753 - in gnuradio/branches/features/inband-usb: pmt/src/lib usrp/host/apps usrp/host/lib/inband
Date: Fri, 8 Jun 2007 21:17:58 -0600 (MDT)

Author: gnychis
Date: 2007-06-08 21:17:57 -0600 (Fri, 08 Jun 2007)
New Revision: 5753

Added:
   gnuradio/branches/features/inband-usb/usrp/host/apps/test_usrp_inband_rx.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.h
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.lo
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.h
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.h
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx_stub.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx_stub.h
Removed:
   
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc
   
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h
Modified:
   gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.cc
   gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.h
   gnuradio/branches/features/inband-usb/usrp/host/apps/Makefile.am
   gnuradio/branches/features/inband-usb/usrp/host/apps/test_usrp_inband_tx.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
   
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
   
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h
   
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
   
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h
Log:
Merging -r5644:5752 from branches/developers/gnychis/inband


Modified: gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.cc
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.cc    2007-06-09 
02:55:25 UTC (rev 5752)
+++ gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.cc    2007-06-09 
03:17:57 UTC (rev 5753)
@@ -938,6 +938,12 @@
 }
 
 pmt_t
+pmt_list5(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4, pmt_t x5)
+{
+  return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, pmt_cons(x5, 
PMT_NIL)))));
+}
+
+pmt_t
 pmt_caar(pmt_t pair)
 {
   return (pmt_car(pmt_car(pair)));

Modified: gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.h
===================================================================
--- gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.h     2007-06-09 
02:55:25 UTC (rev 5752)
+++ gnuradio/branches/features/inband-usb/pmt/src/lib/pmt.h     2007-06-09 
03:17:57 UTC (rev 5753)
@@ -598,6 +598,11 @@
  */
 pmt_t pmt_list4(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4);
 
+/*!
+ * \brief Return a list of length 4 containing \p x1, \p x2, \p x3, \p x4, \p 
x5
+ */
+pmt_t pmt_list5(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4, pmt_t x5);
+
 /*
  * ------------------------------------------------------------------------
  *                          read / write

Modified: gnuradio/branches/features/inband-usb/usrp/host/apps/Makefile.am
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/apps/Makefile.am    
2007-06-09 02:55:25 UTC (rev 5752)
+++ gnuradio/branches/features/inband-usb/usrp/host/apps/Makefile.am    
2007-06-09 03:17:57 UTC (rev 5753)
@@ -33,11 +33,14 @@
 noinst_PROGRAMS =                      \
        check_order_quickly             \
        test_usrp_inband_tx             \
+       test_usrp_inband_rx             \
        test_usrp_standard_rx           \
        test_usrp_standard_tx           
 
 noinst_HEADERS =                       \
-       time_stuff.h
+       time_stuff.h                    \
+       ui_nco.h                        \
+       ui_sincos.h                     
 
 noinst_PYTHON =                                \
        burn-db-eeprom                  \
@@ -61,3 +64,6 @@
 test_usrp_inband_tx_SOURCES    = test_usrp_inband_tx.cc time_stuff.c 
ui_sincos.c
 test_usrp_inband_tx_LDADD      = $(USRP_LA)
 
+test_usrp_inband_rx_SOURCES    = test_usrp_inband_rx.cc time_stuff.c 
ui_sincos.c
+test_usrp_inband_rx_LDADD      = $(USRP_LA)
+

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/apps/test_usrp_inband_rx.cc 
(from rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/apps/test_usrp_inband_rx.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/apps/test_usrp_inband_rx.cc 
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/apps/test_usrp_inband_rx.cc 
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,322 @@
+/* -*- 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 2, 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 <mb_mblock.h>
+#include <mb_runtime.h>
+#include <mb_runtime_nop.h>            // QA only
+#include <mb_protocol_class.h>
+#include <mb_exception.h>
+#include <mb_msg_queue.h>
+#include <mb_message.h>
+#include <mb_mblock_impl.h>
+#include <mb_msg_accepter.h>
+#include <mb_class_registry.h>
+#include <pmt.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+
+// Signal set for the USRP server
+static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
+static pmt_t s_cmd_close = pmt_intern("cmd-close");
+static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
+static pmt_t s_cmd_open = pmt_intern("cmd-open");
+static pmt_t s_cmd_start_recv_raw_samples = 
pmt_intern("cmd-start-recv-raw-samples");
+static pmt_t s_cmd_stop_recv_raw_samples = 
pmt_intern("cmd-stop-recv-raw-samples");
+static pmt_t s_cmd_to_control_channel = pmt_intern("cmd-to-control-channel");
+static pmt_t s_cmd_xmit_raw_frame  = pmt_intern("cmd-xmit-raw-frame");
+static pmt_t s_cmd_max_capacity  = pmt_intern("cmd-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_cmd_current_capacity_allocation  = 
pmt_intern("cmd-current-capacity-allocation");
+static pmt_t s_response_allocate_channel = 
pmt_intern("response-allocate-channel");
+static pmt_t s_response_close = pmt_intern("response-close");
+static pmt_t s_response_deallocate_channel = 
pmt_intern("response-deallocate-channel");
+static pmt_t s_response_from_control_channel = 
pmt_intern("response-from-control-channel");
+static pmt_t s_response_open = pmt_intern("response-open");
+static pmt_t s_response_recv_raw_samples = 
pmt_intern("response-recv-raw-samples");
+static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
+static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity");
+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_response_current_capacity_allocation  = 
pmt_intern("response-current-capacity-allocation");
+
+static bool verbose = false;
+
+class test_usrp_rx : public mb_mblock
+{
+  mb_port_sptr         d_rx;
+  mb_port_sptr         d_cs;
+  pmt_t                d_rx_chan;      // returned tx channel handle
+
+  enum state_t {
+    INIT,
+    OPENING_USRP,
+    ALLOCATING_CHANNEL,
+    RECEIVING,
+    CLOSING_CHANNEL,
+    CLOSING_USRP,
+  };
+
+  state_t      d_state;
+
+  std::ofstream d_ofile;
+
+ public:
+  test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t 
user_arg);
+  ~test_usrp_rx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void open_usrp();
+  void close_usrp();
+  void allocate_channel();
+  void send_packets();
+  void enter_receiving();
+  void build_and_send_next_frame();
+  void handle_response_recv_raw_samples(pmt_t invocation_handle);
+  void enter_closing_channel();
+};
+
+test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string 
&instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+  
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  
+  bool fake_usrp_p = true;
+  //bool fake_usrp_p = false;
+
+  // 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("fake-usrp"),
+                            PMT_T);
+
+  define_component("server", "usrp_server", usrp_server_dict);
+
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+
+  d_ofile.open("pdump_rx.dat",std::ios::binary|std::ios::out);
+}
+
+test_usrp_rx::~test_usrp_rx()
+{
+  d_ofile.close();
+}
+
+void
+test_usrp_rx::initial_transition()
+{
+  open_usrp();
+}
+
+void
+test_usrp_rx::handle_message(mb_message_sptr msg)
+{
+  pmt_t        event = msg->signal();
+  pmt_t data = msg->data();
+
+  pmt_t handle = PMT_F;
+  pmt_t status = PMT_F;
+  std::string error_msg;
+  
+  switch(d_state){
+  case OPENING_USRP:
+    if (pmt_eq(event, s_response_open)){
+      status = pmt_nth(1, data);
+      if (pmt_eq(status, PMT_T)){
+        allocate_channel();
+        return;
+      }
+      else {
+        error_msg = "failed to open usrp:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+    
+  case ALLOCATING_CHANNEL:
+    if (pmt_eq(event, s_response_allocate_channel)){
+      status = pmt_nth(1, data);
+      d_rx_chan = pmt_nth(2, data);
+
+      if (pmt_eq(status, PMT_T)){
+        enter_receiving();
+        return;
+      }
+      else {
+        error_msg = "failed to allocate channel:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case RECEIVING:
+    if (pmt_eq(event, s_response_recv_raw_samples)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        handle_response_recv_raw_samples(data);
+        return;
+      }
+      else {
+        error_msg = "bad response-xmit-raw-frame:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case CLOSING_CHANNEL:
+    if (pmt_eq(event, s_response_deallocate_channel)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        close_usrp();
+        return;
+      }
+      else {
+        error_msg = "failed to deallocate channel:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  case CLOSING_USRP:
+    if (pmt_eq(event, s_response_close)){
+      status = pmt_nth(1, data);
+
+      if (pmt_eq(status, PMT_T)){
+        shutdown_all(PMT_T);
+        return;
+      }
+      else {
+        error_msg = "failed to close USRP:";
+        goto bail;
+      }
+    }
+    goto unhandled;
+
+  default:
+    goto unhandled;
+  }
+  return;
+
+ bail:
+  std::cerr << error_msg << data
+           << "status = " << status << std::endl;
+  shutdown_all(PMT_F);
+  return;
+
+ unhandled:
+  std::cout << "test_usrp_inband_rx: unhandled msg: " << msg
+           << "in state "<< d_state << std::endl;
+}
+
+
+void
+test_usrp_rx::open_usrp()
+{
+  pmt_t which_usrp = pmt_from_long(0);
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp));
+  d_state = OPENING_USRP;
+}
+
+void
+test_usrp_rx::close_usrp()
+{
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+  d_state = CLOSING_USRP;
+}
+
+void
+test_usrp_rx::allocate_channel()
+{
+  long capacity = (long) 16e6;
+  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, 
pmt_from_long(capacity)));
+  d_state = ALLOCATING_CHANNEL;
+}
+
+void
+test_usrp_rx::enter_receiving()
+{
+  d_state = RECEIVING;
+
+  d_rx->send(s_cmd_start_recv_raw_samples,
+             pmt_list2(PMT_F,
+                       d_rx_chan));
+}
+
+void
+test_usrp_rx::handle_response_recv_raw_samples(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t v_samples = pmt_nth(2, data);
+  pmt_t timestamp = pmt_nth(3, data);
+  pmt_t properties = pmt_nth(4, data);
+
+  size_t n_bytes;
+  
+  const char *samples = (const char *) pmt_uniform_vector_elements(v_samples, 
n_bytes);
+  d_ofile.write(samples, n_bytes);
+
+  if(verbose)
+    std::cout << ".";
+
+}
+
+void
+test_usrp_rx::enter_closing_channel()
+{
+  d_state = CLOSING_CHANNEL;
+  
+  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_rx);
+
+
+// ----------------------------------------------------------------
+
+int
+main (int argc, char **argv)
+{
+  // handle any command line args here
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_NIL;
+
+  rt->run("top", "test_usrp_rx", PMT_F, &result);
+}

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/apps/test_usrp_inband_tx.cc
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/apps/test_usrp_inband_tx.cc 
2007-06-09 02:55:25 UTC (rev 5752)
+++ gnuradio/branches/features/inband-usb/usrp/host/apps/test_usrp_inband_tx.cc 
2007-06-09 03:17:57 UTC (rev 5753)
@@ -61,6 +61,7 @@
 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");
 
+static bool verbose = false;
 
 class test_usrp_tx : public mb_mblock
 {
@@ -110,8 +111,8 @@
     d_state(INIT), d_nsamples_to_send((long) 40e6),
     d_nsamples_xmitted(0),
     d_nframes_xmitted(0),
-    //d_samples_per_frame((long)(126 * 3.5)),  // non-full packet
-    d_samples_per_frame((long)(126 * 4)),      // full packet
+    d_samples_per_frame((long)(126 * 3.5)),    // non-full packet
+    //d_samples_per_frame((long)(126 * 4)),    // full packet
     d_done_sending(false),
     d_amplitude(16384)
 { 
@@ -120,19 +121,20 @@
   d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
   d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
   
-  //bool fake_usrp_p = true;
-  bool fake_usrp_p = false;
+  bool fake_usrp_p = true;
+  //bool fake_usrp_p = false;
 
   // 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();
+  pmt_t usrp_dict = pmt_make_dict();
 
-  if(fake_usrp_p)
-    pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"),
-                pmt_intern("usrp_usb_interface_stub"));
+  if(fake_usrp_p) {
+    pmt_dict_set(usrp_dict, 
+                 pmt_intern("fake-usrp"),
+                            PMT_T);
+  }
 
-  define_component("server", "usrp_server", usrp_server_dict);
+  define_component("server", "usrp_server", usrp_dict);
 
   connect("self", "tx0", "server", "tx0");
   connect("self", "cs", "server", "cs");
@@ -305,7 +307,7 @@
   // allocate the uniform vector for the samples
   // FIXME perhaps hold on to this between calls
 
-#if 0
+#if 1
   long nsamples_this_frame =
     std::min(d_nsamples_to_send - d_nsamples_xmitted,
             d_samples_per_frame);
@@ -328,17 +330,17 @@
 
   for (int i = 0; i < nsamples_this_frame; i++){
 
-    if (0){
+    if (1){
       gr_complex s;
       d_nco.sincos(&s, 1, d_amplitude);
-      // write 16-bit I & Q
+      // 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);
 
-      // write 16-bit I & Q
+      // write 16-bit i & q
       samples[2*i] =   (int16_t) s.real();
       samples[2*i+1] = (int16_t) s.imag();
     }
@@ -353,6 +355,9 @@
 
   d_nsamples_xmitted += nsamples_this_frame;
   d_nframes_xmitted++;
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
 }
 
 

Modified: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am      
2007-06-09 02:55:25 UTC (rev 5752)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am      
2007-06-09 03:17:57 UTC (rev 5753)
@@ -22,17 +22,17 @@
 
 INCLUDES =     \
        $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \
-       $(USRP_INCLUDES) $(BOOST_CFLAGS) $(CPPUNIT_INCLUDES)
+       $(USRP_INCLUDES) $(BOOST_CFLAGS) $(CPPUNIT_INCLUDES) -I../../apps
 
 TESTS = test_inband
 
 EXTRA_DIST =                           \
-       usrp_server.mbh         \
+       usrp_server.mbh                 \
        usrp_interface.mbh 
 
 
 lib_LTLIBRARIES =                      \
-       libusrp_inband.la                       \
+       libusrp_inband.la               \
        libusrp_inband-qa.la
 
 
@@ -40,7 +40,7 @@
 # Build the inband library
 
 BUILT_SOURCES =                                \
-       usrp_server_mbh.cc      \
+       usrp_server_mbh.cc              \
        usrp_interface_mbh.cc 
 
 usrp_server_mbh.cc : usrp_server.mbh
@@ -51,28 +51,35 @@
 
 libusrp_inband_la_SOURCES =            \
        $(BUILT_SOURCES)                \
+       ../../apps/ui_sincos.c          \
+       usrp_rx.cc                      \
+       usrp_rx_stub.cc                 \
        usrp_server.cc                  \
-       usrp_usb_interface.cc   \
-       usrp_usb_interface_stub.cc
+       usrp_tx.cc                      \
+       usrp_tx_stub.cc                 \
+       usrp_usb_interface.cc           
 
 libusrp_inband_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
 
-libusrp_inband_la_LIBADD =                                     \
-       $(MBLOCK_LA)                                            \
-       $(top_builddir)/usrp/host/lib/legacy/libusrp.la         \
+libusrp_inband_la_LIBADD =             \
+       $(MBLOCK_LA)                    \
+       ../legacy/libusrp.la            \
        -lstdc++
 
 include_HEADERS =                      \
-       usrp_server.h                           \
-       usrp_usb_interface.h \
-       usrp_inband_usb_packet.h \
-       usrp_usb_interface_stub.h
+       usrp_inband_usb_packet.h        \
+       usrp_rx.h                       \
+       usrp_rx_stub.h                  \
+       usrp_server.h                   \
+       usrp_tx.h                       \
+       usrp_tx_stub.h                  \
+       usrp_usb_interface.h            
 
 noinst_HEADERS =                       \
+       fake_usrp.h                     \
        qa_inband.h                     \
        qa_inband_packet_prims.h        \
-       qa_inband_usrp_server.h         \
-       fake_usrp.h                                                             
+       qa_inband_usrp_server.h         
 
 
 # ------------------------------------------------------------------------
@@ -90,13 +97,14 @@
 libusrp_inband_qa_la_LIBADD =          \
        libusrp_inband.la               \
        $(CPPUNIT_LIBS)                 \
-       $(USRP_LA)                                      \
+       ../legacy/libusrp.la            \
+       libusrp_inband.la               \
        -lstdc++
 
 # ------------------------------------------------------------------------
 
 noinst_PROGRAMS =                      \
-       test_inband                                     \
+       test_inband                     \
        test_usrp_inband
 
 test_inband_SOURCES = test_inband.cc

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
 2007-06-09 02:55:25 UTC (rev 5752)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
 2007-06-09 03:17:57 UTC (rev 5753)
@@ -38,27 +38,32 @@
 
 typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit 
easy
 
+static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
+static pmt_t s_cmd_close = pmt_intern("cmd-close");
+static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
 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_cmd_start_recv_raw_samples = 
pmt_intern("cmd-start-recv-raw-samples");
+static pmt_t s_cmd_stop_recv_raw_samples = 
pmt_intern("cmd-stop-recv-raw-samples");
+static pmt_t s_cmd_to_control_channel = pmt_intern("cmd-to-control-channel");
+static pmt_t s_cmd_xmit_raw_frame  = pmt_intern("cmd-xmit-raw-frame");
+static pmt_t s_cmd_max_capacity  = pmt_intern("cmd-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_cmd_current_capacity_allocation  = 
pmt_intern("cmd-current-capacity-allocation");
+static pmt_t s_response_allocate_channel = 
pmt_intern("response-allocate-channel");
 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_from_control_channel = 
pmt_intern("response-from-control-channel");
+static pmt_t s_response_open = pmt_intern("response-open");
+static pmt_t s_response_recv_raw_samples = 
pmt_intern("response-recv-raw-samples");
+static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
 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");
 
+static bool verbose = false;
+
 // 
----------------------------------------------------------------------------------------------
 
 class qa_alloc_top : public mb_mblock
@@ -101,8 +106,7 @@
  
   // Use the stub with the usrp_server
   pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"),
-              pmt_intern("usrp_usb_interface_stub"));
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
 
   // Test the TX side
   define_component("server", "usrp_server", usrp_server_dict);
@@ -118,46 +122,83 @@
 qa_alloc_top::initial_transition()
 {
   // Allocations should fail before open
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_F, pmt_from_long(1)));
-  d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_F, pmt_from_long(1)));
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_F), 
+                       pmt_from_long(1)));
 
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel,PMT_F), 
+                       pmt_from_long(1)));
+
   // Retrieve information about the USRP, then run tests
-  d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
-  d_cs->send(s_cmd_max_capacity, pmt_list1(PMT_T));
-  d_cs->send(s_cmd_ntx_chan, pmt_list1(PMT_T));
-  d_cs->send(s_cmd_nrx_chan, pmt_list1(PMT_T));
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open, PMT_T), 
+             pmt_from_long(0)));
+
+  d_cs->send(s_cmd_max_capacity, 
+             pmt_list1(pmt_list2(s_response_max_capacity, PMT_T)));
+  
+  d_cs->send(s_cmd_ntx_chan, 
+             pmt_list1(pmt_list2(s_response_ntx_chan, PMT_T)));
+  
+  d_cs->send(s_cmd_nrx_chan, 
+             pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T)));
 }
 
 void
 qa_alloc_top::run_tests()
 {
-  // std::cout << "[qa_alloc_top] Starting tests...\n";
+  if(verbose)
+    std::cout << "[qa_alloc_top] Starting tests...\n";
+
   // should be able to allocate 1 byte
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(PMT_T, pmt_from_long(1)));
   
   // should not be able to allocate max capacity after 100 bytes were allocated
-  d_tx->send(s_cmd_allocate_channel, 
pmt_list2(pmt_from_long(usrp_server::RQSTD_CAPACITY_UNAVAIL), 
pmt_from_long(d_max_capacity)));  
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_from_long(usrp_server::RQSTD_CAPACITY_UNAVAIL), 
+                       pmt_from_long(d_max_capacity)));  
   
-  // keep allocating a little more until all of the channels are used and test 
the error response
-  // we start at 1 since we've already allocated 1 channel
+  // keep allocating a little more until all of the channels are used and test
+  // the error response we start at 1 since we've already allocated 1 channel
   for(int i=1; i < d_ntx_chan; i++) {
+
+    if(verbose)
+      std::cout << "[qa_alloc_top] Sent allocation request...\n";
+  
     d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+
     d_nmsgs_to_recv++;
   }
-  d_tx->send(s_cmd_allocate_channel, 
pmt_list2(pmt_from_long(usrp_server::CHANNEL_UNAVAIL), pmt_from_long(1)));
 
+  // No more channels after allocating all of them is expected
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_from_long(usrp_server::CHANNEL_UNAVAIL), 
+                       pmt_from_long(1)));
+
   // test out the same on the RX side
   d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
-  d_rx->send(s_cmd_allocate_channel, 
pmt_list2(pmt_from_long(usrp_server::RQSTD_CAPACITY_UNAVAIL), 
pmt_from_long(d_max_capacity)));  
 
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_from_long(usrp_server::RQSTD_CAPACITY_UNAVAIL), 
+                       pmt_from_long(d_max_capacity)));  
+
   for(int i=1; i < d_nrx_chan; i++) {
+    
     d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+    
     d_nmsgs_to_recv++;
   }
-  d_rx->send(s_cmd_allocate_channel, 
pmt_list2(pmt_from_long(usrp_server::CHANNEL_UNAVAIL), pmt_from_long(1)));
 
-  // when all is said and done, there should be d_ntx_chan+d_ntx_chan bytes 
allocated
-  d_cs->send(s_cmd_current_capacity_allocation, 
pmt_list1(pmt_from_long(d_ntx_chan+d_nrx_chan)));
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_from_long(usrp_server::CHANNEL_UNAVAIL), 
+             pmt_from_long(1)));
+
+  // when all is said and done, there should be d_ntx_chan+d_ntx_chan bytes
+  // allocated
+  d_cs->send(s_cmd_current_capacity_allocation, 
+             pmt_list1(pmt_from_long(d_ntx_chan+d_nrx_chan)));
 }
 
 void
@@ -174,15 +215,21 @@
       
     if(pmt_eq(msg->signal(), s_response_max_capacity)) {
       d_max_capacity = pmt_to_long(pmt_nth(2, data));
-      // std::cout << "[qa_alloc_top] USRP has max capacity of " << 
d_max_capacity << "\n";
+      if(verbose)
+        std::cout << "[qa_alloc_top] USRP has max capacity of " 
+                  << d_max_capacity << "\n";
     }
     else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
       d_ntx_chan = pmt_to_long(pmt_nth(2, data));
-      // std::cout << "[qa_alloc_top] USRP tx channels: " << d_ntx_chan << 
"\n";
+      if(verbose)
+        std::cout << "[qa_alloc_top] USRP tx channels: " 
+                  << d_ntx_chan << "\n";
     }
     else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
       d_nrx_chan = pmt_to_long(pmt_nth(2, data));
-      // std::cout << "[qa_alloc_top] USRP rx channels: " << d_nrx_chan << 
"\n";
+      if(verbose)
+        std::cout << "[qa_alloc_top] USRP rx channels: " 
+                  << d_nrx_chan << "\n";
     }
     else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
       check_message(msg);
@@ -201,19 +248,26 @@
 qa_alloc_top::check_message(mb_message_sptr msg)
 {
   pmt_t data = msg->data();
+  pmt_t event = msg->signal();
 
-  pmt_t expected_result = pmt_nth(0, data);
-  pmt_t result = pmt_nth(1, data);
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
   
   d_nrecvd++;
 
 
-  if(!pmt_eqv(expected_result, result)) {
-    // std::cout << "Got: " << result << " Expected: " << expected_result << 
"\n";
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+    if(verbose)
+      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
     shutdown_all(PMT_F);
     return;
   } else {
-    // std::cout << "[qa_alloc_top] Received expected response for message " 
<< d_nrecvd << "\n";
+    if(verbose)
+      std::cout << "[qa_alloc_top] Received expected response for message " 
+                << d_nrecvd << " (" << event << ")\n";
   }
 
   if(d_nrecvd == d_nmsgs_to_recv)
@@ -264,7 +318,7 @@
   d_ndealloc_recvd=0;
   d_ndealloc_to_recv = 0;
   d_nalloc_recvd=0;
-  d_nalloc_to_recv = 0;
+  d_nalloc_to_recv = 0;   // auto-set
   d_nstatus=0;
   d_nstatus_to_recv = 4;
   
@@ -274,7 +328,7 @@
 
   // Use the stub with the usrp_server
   pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), 
pmt_intern("usrp_usb_interface_stub"));
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
 
   // Test the TX side
   define_component("server", "usrp_server", usrp_server_dict);
@@ -288,27 +342,46 @@
 void
 qa_dealloc_top::initial_transition()
 {
+
+  if(verbose)
+    std::cout << "[qa_dealloc_top] Initializing...\n";
+
   // Retrieve information about the USRP, then run tests
-  d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
-  d_cs->send(s_cmd_max_capacity, pmt_list1(PMT_T));
-  d_cs->send(s_cmd_ntx_chan, pmt_list1(PMT_T));
-  d_cs->send(s_cmd_nrx_chan, pmt_list1(PMT_T));
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_T), 
+             pmt_from_long(0)));
+
+  d_cs->send(s_cmd_max_capacity, 
+             pmt_list1(pmt_list2(s_response_max_capacity,PMT_T)));
+
+  d_cs->send(s_cmd_ntx_chan, 
+             pmt_list1(pmt_list2(s_response_ntx_chan,PMT_T)));
+
+  d_cs->send(s_cmd_nrx_chan, 
+             pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T)));
 }
 
 void
 qa_dealloc_top::allocate_max()
 {
-  // std::cout << "[qa_dealloc_top] Max allocating...\n";
 
   // Keep allocating until we hit the maximum number of channels
   for(int i=0; i < d_ntx_chan; i++) {
-    d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+    d_tx->send(s_cmd_allocate_channel, 
+               pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T),
+               pmt_from_long(1)));  // 1 byte is good enough
+
     d_nalloc_to_recv++;
   }
+
   for(int i=0; i < d_nrx_chan; i++) {
-    d_rx->send(s_cmd_allocate_channel, pmt_list2(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)));
+
     d_nalloc_to_recv++;
   }
+
 }
 
 void
@@ -316,40 +389,103 @@
   
   // Deallocate all of the channels that were allocated from allocate_max()
   for(int i=0; i < (int)d_tx_chans.size(); i++) {
-    d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_T, 
pmt_from_long(d_tx_chans[i])));
+
+    if(verbose)
+      std::cout << "[qa_dealloc_top] Trying to dealloc TX " 
+                << d_tx_chans[i] << std::endl;
+
+    d_tx->send(s_cmd_deallocate_channel, 
+               pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), 
+               pmt_from_long(d_tx_chans[i])));
+
     d_ndealloc_to_recv++;
   }
+
+  // Deallocate the RX side now
   for(int i=0; i < (int)d_rx_chans.size(); i++) {
-    d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_T, 
pmt_from_long(d_rx_chans[i])));
+
+    if(verbose)
+      std::cout << "[qa_dealloc_top] Trying to dealloc RX " 
+                << d_tx_chans[i] << std::endl;
+
+    d_rx->send(s_cmd_deallocate_channel, 
+               pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), 
+               pmt_from_long(d_rx_chans[i])));
+
     d_ndealloc_to_recv++;
   }
 
-  // Should get permission denied errors trying to re-dealloc the channels, as 
we no
-  // longer have permission to them after deallocating
+  // Should get permission denied errors trying to re-dealloc the channels, as
+  // we no longer have permission to them after deallocating
   for(int i=0; i < (int)d_tx_chans.size(); i++) {
-    d_tx->send(s_cmd_deallocate_channel, 
pmt_list2(pmt_from_long(usrp_server::PERMISSION_DENIED), 
pmt_from_long(d_tx_chans[i])));
+
+    d_tx->send(s_cmd_deallocate_channel, 
+               pmt_list2(pmt_list2(s_response_deallocate_channel,
+                             pmt_from_long(usrp_server::PERMISSION_DENIED)), 
+                         pmt_from_long(d_tx_chans[i])));
+
     d_ndealloc_to_recv++;
   }
+
+  // Same for RX
   for(int i=0; i < (int)d_rx_chans.size(); i++) {
-    d_rx->send(s_cmd_deallocate_channel, 
pmt_list2(pmt_from_long(usrp_server::PERMISSION_DENIED), 
pmt_from_long(d_rx_chans[i])));
+
+    d_rx->send(s_cmd_deallocate_channel, 
+               pmt_list2(pmt_list2(s_response_deallocate_channel,
+                             pmt_from_long(usrp_server::PERMISSION_DENIED)), 
+                         pmt_from_long(d_rx_chans[i])));
+  
     d_ndealloc_to_recv++;
   }
 
-  // Try to deallocate a channel that doesn't exist on both sides, the last 
element in the vectors
-  // is the highest channel number, so we take that plus 1
+  // Try to deallocate a channel that doesn't exist on both sides, the last
+  // element in the vectors is the highest channel number, so we take that plus
+  // 1
   d_ndealloc_to_recv+=2;
-  d_tx->send(s_cmd_deallocate_channel, 
pmt_list2(pmt_from_long(usrp_server::CHANNEL_INVALID), 
pmt_from_long(d_rx_chans.back()+1)));
-  d_rx->send(s_cmd_deallocate_channel, 
pmt_list2(pmt_from_long(usrp_server::CHANNEL_INVALID), 
pmt_from_long(d_rx_chans.back()+1)));
+  d_tx->send(s_cmd_deallocate_channel, 
+             pmt_list2(pmt_list2(s_response_deallocate_channel,
+                                 pmt_from_long(usrp_server::CHANNEL_INVALID)), 
+                       pmt_from_long(d_rx_chans.back()+1)));
 
+  d_rx->send(s_cmd_deallocate_channel, 
+             pmt_list2(pmt_list2(s_response_deallocate_channel,
+                                 pmt_from_long(usrp_server::CHANNEL_INVALID)), 
+                       pmt_from_long(d_rx_chans.back()+1)));
 
+
   // The used capacity should be back to 0 now that we've deallocated 
everything
-  d_cs->send(s_cmd_current_capacity_allocation, pmt_list1(PMT_T));
+  d_cs->send(s_cmd_current_capacity_allocation,
+             pmt_list1(pmt_list2(s_response_current_capacity_allocation,
+                                 PMT_T)));
 }
 
 void
 qa_dealloc_top::handle_message(mb_message_sptr msg)
 {
   pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  if(pmt_eq(event, pmt_intern("%shutdown")))
+    return;
+
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+    if(verbose)
+      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
+    shutdown_all(PMT_F);
+    return;
+  } else {
+    if(verbose)
+      std::cout << "[qa_alloc_top] Received expected response for message " 
+                << d_ndealloc_recvd
+      << " (" << event << ")\n";
+  }
+
   if (pmt_eq(msg->port_id(), d_tx->port_symbol())
        || pmt_eq(msg->port_id(), d_rx->port_symbol())) {
     
@@ -357,34 +493,32 @@
       check_allocation(msg);
     }
     
-    if(pmt_eq(msg->signal(), s_response_deallocate_channel)){
-      check_deallocation(msg);
-    }
   }
   
   if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
       
     if(pmt_eq(msg->signal(), s_response_max_capacity)) {
       d_max_capacity = pmt_to_long(pmt_nth(2, data));
-      // std::cout << "[qa_dealloc_top] USRP has max capacity of " << 
d_max_capacity << "\n";
     }
     else if(pmt_eq(msg->signal(), s_response_ntx_chan)) {
       d_ntx_chan = pmt_to_long(pmt_nth(2, data));
-      // std::cout << "[qa_dealloc_top] USRP tx channels: " << d_ntx_chan << 
"\n";
     }
     else if(pmt_eq(msg->signal(), s_response_nrx_chan)) {
       d_nrx_chan = pmt_to_long(pmt_nth(2, data));
-      // std::cout << "[qa_dealloc_top] USRP rx channels: " << d_nrx_chan << 
"\n";
     }
     else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
-      // the final command is a capacity check which should be 0, then we 
shutdown
-      pmt_t expected_result = pmt_nth(0, data);
-      pmt_t result = pmt_nth(1, data);
+      // the final command is a capacity check which should be 0, then we
+      // shutdown
+      pmt_t expected_result = pmt_from_long(0);
+      pmt_t result = pmt_nth(2, data);
 
-      if(pmt_eqv(expected_result, result))
+      if(pmt_eqv(expected_result, result)) {
         shutdown_all(PMT_T);
-      else
+        return;
+      } else {
         shutdown_all(PMT_F);
+        return;
+      }
     }
     
     d_nstatus++;
@@ -394,38 +528,20 @@
   }
 }
 
-void
-qa_dealloc_top::check_deallocation(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
 
-  pmt_t expected_result = pmt_nth(0, data);
-  pmt_t result = pmt_nth(1, data);
-
-  d_ndealloc_recvd++;
-
-  if(!pmt_eqv(expected_result, result)) {
-    // std::cout << "Got: " << result << " Expected: " << expected_result << 
"\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    // std::cout << "[qa_dealloc_top] Received expected deallocation response 
for message " << d_ndealloc_recvd << "\n";
-  }
-}
-
 void
 qa_dealloc_top::check_allocation(mb_message_sptr msg)
 {
   pmt_t data = msg->data();
+  pmt_t event = msg->signal();
 
-  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t expected = pmt_nth(0, data);
   pmt_t status = pmt_nth(1, data);
   pmt_t channel = pmt_nth(2, data);
-  
+
   d_nalloc_recvd++;
 
-  if(pmt_eqv(status, PMT_F)) {
-    // std::cout << "[qa_dealloc_top] Unexpected error response when 
allocating channels\n";
+  if(!pmt_eqv(status, PMT_T)) {
     shutdown_all(PMT_F);
     return;
   } else {
@@ -437,17 +553,20 @@
   }
 
   if(d_nalloc_recvd == d_nalloc_to_recv) {
-    
-    // std::cout << "[qa_dealloc_top] Allocated TX channels: ";
-    for(int i=0; i < (int)d_tx_chans.size(); i++)
-      std::cout << d_tx_chans[i] << " ";
 
-    // std::cout << "\n[qa_dealloc_top] Allocated RX channels: ";
-    for(int i=0; i < (int)d_rx_chans.size(); i++)
-      std::cout << d_rx_chans[i] << " ";
-    // std::cout << "\n";
+    if(verbose) {
+      std::cout << "[qa_dealloc_top] Allocated TX channels: ";
+      for(int i=0; i < (int)d_tx_chans.size(); i++)
+        std::cout << d_tx_chans[i] << " ";
 
-    deallocate_all();   // once we've allocated all of our channels, try to 
dealloc them
+      std::cout << "\n[qa_dealloc_top] Allocated RX channels: ";
+      for(int i=0; i < (int)d_rx_chans.size(); i++)
+        std::cout << d_rx_chans[i] << " ";
+      std::cout << "\n";
+    }
+
+    deallocate_all();   // once we've allocated all of our channels, try to
+                        // dealloc them
   }
 }
 
@@ -486,7 +605,7 @@
 
   // Use the stub with the usrp_server
   pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), 
pmt_intern("usrp_usb_interface_stub"));
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
 
   // Test the TX side
   define_component("server", "usrp_server", usrp_server_dict);
@@ -507,21 +626,29 @@
   // std::cout << "[qa_open_close_top] Starting tests\n";
 
   // A close before an open should fail
-  d_cs->send(s_cmd_close, pmt_list1(PMT_F));
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_F)));
   
   // Perform an open, and a second open which should fail
-  d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
-  d_cs->send(s_cmd_open, pmt_list2(PMT_F, pmt_from_long(0)));
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_T), 
+                       pmt_from_long(0)));
 
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_F), 
+                       pmt_from_long(0)));
+
   // A close should now be successful since the interface is open
-  d_cs->send(s_cmd_close, pmt_list1(PMT_T));
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
 
   // But, a second close should fail
-  d_cs->send(s_cmd_close, pmt_list1(PMT_F));
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_F)));
   
   // Just to be thorough, try an open and close again
-  d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
-  d_cs->send(s_cmd_close, pmt_list1(PMT_T));
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_T), 
+                       pmt_from_long(0)));
+
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
   
 }
 
@@ -545,15 +672,26 @@
 qa_open_close_top::check_cs(mb_message_sptr msg)
 {
   pmt_t data = msg->data();
+  pmt_t event = msg->signal();
 
-  pmt_t expected_result = pmt_nth(0, data);
-  pmt_t result = pmt_nth(1, data);
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
 
-  if(!pmt_eqv(expected_result, result)) {
-    // std::cout << "[qa_open_close_top] FAILED check_cs... Got: " << result 
<< " Expected: " << expected_result << " for event " << msg->signal() << "\n";
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+
+    if(verbose)
+      std::cout << "[qa_open_close_top] FAILED check_cs... Got: " << status
+                << " Expected: " << e_status
+                << " for event " << event << "\n";
+
     shutdown_all(PMT_F);
   } else {
-    // std::cout << "[qa_open_close_top] Received expected CS response for 
message (" << msg->signal() << ")\n";
+    if(verbose)
+      std::cout << "[qa_open_close_top] Received expected CS response (" 
+                << event << ")\n";
   }
 
 }
@@ -595,7 +733,7 @@
   : mb_mblock(runtime, instance_name, user_arg)
 { 
 
-  d_nmsg_to_recv=12;
+  d_nmsg_to_recv=10;
   d_nmsg_recvd=0;
   
   d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
@@ -604,7 +742,7 @@
 
   // Use the stub with the usrp_server
   pmt_t usrp_server_dict = pmt_make_dict();
-  pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), 
pmt_intern("usrp_usb_interface_stub"));
+  pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T);
 
   // Test the TX side
   define_component("server", "usrp_server", usrp_server_dict);
@@ -624,35 +762,76 @@
 void
 qa_tx_top::run_tests()
 {
-  // std::cout << "[qa_tx_top] Starting tests\n";
+  if(verbose)
+   std::cout << "[qa_tx_top] Starting tests\n";
 
   // A transmit before an open should fail
-  d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(PMT_F, pmt_from_long(0), 
pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame, PMT_F), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0),
+                       pmt_from_long(0)));
   
-  // Open, and now try an xmit again which should be successful
-  d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
+  // Now open
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open,PMT_T), 
+                       pmt_from_long(0)));
 
   // Try to transmit on a channel that we have no allocation for
-  d_tx->send(s_cmd_xmit_raw_frame, 
pmt_list4(pmt_from_long(usrp_server::PERMISSION_DENIED), pmt_from_long(0), 
pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame,
+                                 
pmt_from_long(usrp_server::PERMISSION_DENIED)), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
 
-  // Get a channel allocation and send on it, we assume 0 (FIXME) until 
'defer' is implemented for simplicity
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
-  d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(PMT_T, pmt_from_long(0), 
pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
+  // Get a channel allocation and send on it, we assume 0 (FIXME) until 'defer'
+  // is implemented for simplicity
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
 
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame, PMT_T), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
+
   // Close should be successful
-  d_cs->send(s_cmd_close, pmt_list1(PMT_T));
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
 
   // After closing, a new transmit raw frame should fail again
-  d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(PMT_F, pmt_from_long(0), 
pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame, PMT_F), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
 
-  // Reopen and retry before getting an allocation, the first xmit should 
fail, after we allocate it should work again
-  d_cs->send(s_cmd_open, pmt_list2(PMT_T, pmt_from_long(0)));
-  d_tx->send(s_cmd_xmit_raw_frame, 
pmt_list4(pmt_from_long(usrp_server::PERMISSION_DENIED), pmt_from_long(0), 
pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
-  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
-  d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(PMT_T, pmt_from_long(0), 
pmt_make_u32vector(transport_pkt::max_payload()/4, 0), pmt_from_long(0)));
+  // Reopen and retry before getting an allocation, the first xmit should fail,
+  // after we allocate it should work again
+  d_cs->send(s_cmd_open, 
+             pmt_list2(pmt_list2(s_response_open, PMT_T), 
+                       pmt_from_long(0)));
 
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame,
+                                 
pmt_from_long(usrp_server::PERMISSION_DENIED)), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
+
+  d_tx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), 
+                       pmt_from_long(1)));
+
+  d_tx->send(s_cmd_xmit_raw_frame, 
+             pmt_list4(pmt_list2(s_response_xmit_raw_frame,PMT_T), 
+                       pmt_from_long(0), 
+                       pmt_make_u32vector(transport_pkt::max_payload()/4, 0), 
+                       pmt_from_long(0)));
+
   // A final close which should be successful
-  d_cs->send(s_cmd_close, pmt_list1(PMT_T));
+  d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T)));
   
 }
 
@@ -661,21 +840,39 @@
 qa_tx_top::handle_message(mb_message_sptr msg)
 {
   pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  if(pmt_eq(event, pmt_intern("%shutdown")))
+    return;
 
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+    if(verbose)
+      std::cout << "[qa_xmit_top] Got: " << status 
+                << " Expected: " << e_status 
+                << "For signal: " << event << "\n";
+    shutdown_all(PMT_F);
+    return;
+  } else {
+    if(verbose)
+      std::cout << "[qa_xmit_top] Received expected response for message " 
+                << d_nmsg_recvd
+      << " (" << event << ")\n";
+  }
+
   if (pmt_eq(msg->port_id(), d_tx->port_symbol())
        || pmt_eq(msg->port_id(), d_rx->port_symbol())) {
     
     if(pmt_eq(msg->signal(), s_response_allocate_channel)) 
       check_allocation(msg);
     
-    if(pmt_eq(msg->signal(), s_response_xmit_raw_frame)) 
-      check_xmit(msg);
   }
   
-  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
-      check_cs(msg);
-  }
-
   d_nmsg_recvd++;
 
   if(d_nmsg_to_recv == d_nmsg_recvd){
@@ -685,40 +882,16 @@
 }
 
 void
-qa_tx_top::check_deallocation(mb_message_sptr msg)
-{
-  pmt_t data = msg->data();
-
-  pmt_t expected_result = pmt_nth(0, data);
-  pmt_t result = pmt_nth(1, data);
-
-  if(!pmt_eqv(expected_result, result)) {
-    // std::cout << "[qa_tx_top] FAILED check_deallocation... Got: " << result 
<< " Expected: " << expected_result << "\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    // std::cout << "[qa_tx_top] Received expected deallocation response for 
message\n";
-  }
-}
-
-void
 qa_tx_top::check_allocation(mb_message_sptr msg)
 {
   pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t channel = pmt_nth(2, data);
 
-  pmt_t expected_result = pmt_nth(0, data);
-  pmt_t result = pmt_nth(1, data);
-  pmt_t channel = pmt_nth(2, data);
-  
-  if(!pmt_eqv(expected_result, result)) {
-    // std::cout << "[qa_tx_top] FAILED check_allocation... Got: " << result 
<< " Expected: " << expected_result << " for event " << msg->signal() << ")\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    // std::cout << "[qa_tx_top] Received expected allocation response for 
message\n";
-  }
-  
-  if(pmt_eqv(result, PMT_T)) {
+  if(pmt_eqv(status, PMT_T)) {
     // store all of the allocate channel numbers
     if(pmt_eq(msg->port_id(), d_tx->port_symbol()))
       d_tx_chan = pmt_to_long(channel);
@@ -727,47 +900,197 @@
   }
 }
 
+REGISTER_MBLOCK_CLASS(qa_tx_top);
+
+// 
----------------------------------------------------------------------------------------------
+
+class qa_rx_top : public mb_mblock
+{
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+  
+  long d_max_capacity;
+  long d_ntx_chan, d_nrx_chan;
+
+  long d_rx_chan;
+
+  long d_got_response_recv;
+
+  long d_nmsg_to_recv;
+  long d_nmsg_recvd;
+
+ public:
+  qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t 
user_arg);
+  ~qa_rx_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void check_allocation(mb_message_sptr msg);
+  void check_deallocation(mb_message_sptr msg);
+  void check_xmit(mb_message_sptr msg);
+  void check_cs(mb_message_sptr msg);
+  void run_tests();
+};
+
+qa_rx_top::qa_rx_top(mb_runtime *runtime, const std::string &instance_name, 
pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg),
+    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);
+
+  // Test the TX side
+  define_component("server", "usrp_server", usrp_server_dict);
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+}
+
+qa_rx_top::~qa_rx_top(){}
+
 void
-qa_tx_top::check_xmit(mb_message_sptr msg)
+qa_rx_top::initial_transition()
 {
-  pmt_t data = msg->data();
+  run_tests();
+}
 
-  pmt_t expected_result = pmt_nth(0, data);
-  pmt_t result = pmt_nth(1, data);
+void
+qa_rx_top::run_tests()
+{
+  if(verbose)
+    std::cout << "[qa_rx_top] Starting tests\n";
+
+  d_cs->send(s_cmd_open, pmt_list2(pmt_list2(s_response_open,PMT_T), 
pmt_from_long(0)));
+
+  d_rx->send(s_cmd_allocate_channel, 
+             pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), 
+             pmt_from_long(1)));
+
+  d_rx->send(s_cmd_start_recv_raw_samples, 
+             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)));
   
-  if(!pmt_eqv(expected_result, result)) {
-    //std::cout << "[qa_tx_top] FAILED check_xmit... Got: " << result
-    // << " Expected: " << expected_result
-    // << " for event " << msg->signal() << ")\n";
-    shutdown_all(PMT_F);
-    return;
-  } else {
-    // std::cout << "[qa_tx_top] Received expected xmit response for 
message\n";
-  }
 }
 
+
 void
-qa_tx_top::check_cs(mb_message_sptr msg)
+qa_rx_top::handle_message(mb_message_sptr msg)
 {
   pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  if(pmt_eq(event, pmt_intern("%shutdown")))
+    return;
+  
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  
+  // 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(verbose)
+        std::cout << "[qa_rx_top] Received expected response for message " 
+                  << d_nmsg_recvd
+                  << " (" << event << ")\n";
 
-  pmt_t expected_result = pmt_nth(0, data);
-  pmt_t result = pmt_nth(1, data);
+      // All we want is 1 response receive!  Can't guarantee exact numbers
+      d_got_response_recv = true;
+    }
+    return;
+  }
 
-  if(!pmt_eqv(expected_result, result)) {
-    // std::cout << "[qa_tx_top] FAILED check_cs... Got: " << result << " 
Expected: " << expected_result << " for event " << msg->signal() << "\n";
+  pmt_t e_event = pmt_nth(0, expected);
+  pmt_t e_status = pmt_nth(1, expected);
+
+  if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) {
+   if(verbose)
+      std::cout << "Got: " << status << " Expected: " << e_status << "\n";
     shutdown_all(PMT_F);
     return;
   } else {
-    // std::cout << "[qa_tx_top] Received expected CS response for message ("
-    // << msg->signal() << ")\n";
+    if(verbose)
+      std::cout << "[qa_rx_top] Received expected response for message " 
+                << d_nmsg_recvd
+      << " (" << event << ")\n";
   }
 
+  if (pmt_eq(msg->port_id(), d_rx->port_symbol())) {
+    
+    if(pmt_eq(msg->signal(), s_response_allocate_channel)) 
+      check_allocation(msg);
+
+  }
+
+  // We stop when we get a close, we are successful if we
+  // got a response from recv, fail if we never got a recv response
+  if(pmt_eq(msg->signal(), s_response_close)) {
+    
+    if(d_got_response_recv) {
+      shutdown_all(PMT_T);
+      return;
+    }
+    else {
+      shutdown_all(PMT_F);
+      if(verbose)
+        std::cout << "[qa_rx_top] No response message before close\n";
+      return;
+    }
+
+  }
+    
+  
+  d_nmsg_recvd++;
+
 }
 
-REGISTER_MBLOCK_CLASS(qa_tx_top);
 
+void
+qa_rx_top::check_allocation(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+  pmt_t event = msg->signal();
+  
+  pmt_t expected = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t channel = pmt_nth(2, data);
 
+  if(pmt_eqv(status, PMT_T)) {
+    // store all of the allocate channel numbers
+    if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
+      d_rx_chan = pmt_to_long(channel);
+  }
+}
+
+REGISTER_MBLOCK_CLASS(qa_rx_top);
+
+
 // 
----------------------------------------------------------------------------------------------
 
 void 
@@ -793,7 +1116,7 @@
   // std::cout << "\n\n----------------------------\n";
   // std::cout << "    RUNNING ALLOCATION TESTS  \n";
 
-  rt->run("top", "qa_alloc_top", PMT_F, &result);
+  rt->run("qa_alloc_top", "qa_alloc_top", PMT_F, &result);
   
   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
 }
@@ -807,7 +1130,7 @@
   // std::cout << "\n\n----------------------------\n";
   // std::cout << "  RUNNING DEALLOCATION TESTS  \n";
 
-  rt->run("top", "qa_dealloc_top", PMT_F, &result);
+  rt->run("qa_dealloc_top", "qa_dealloc_top", PMT_F, &result);
   
   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
 }
@@ -825,3 +1148,17 @@
   
   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
 }
+
+void
+qa_inband_usrp_server::test_rx()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  // std::cout << "\n\n-----------------\n";
+  // std::cout << "  RUNNING RX TESTS  \n";
+
+  rt->run("top", "qa_rx_top", PMT_F, &result);
+  
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
  2007-06-09 02:55:25 UTC (rev 5752)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
  2007-06-09 03:17:57 UTC (rev 5753)
@@ -32,6 +32,7 @@
   CPPUNIT_TEST(test_chan_allocation);
   CPPUNIT_TEST(test_chan_deallocation);
   CPPUNIT_TEST(test_tx);
+  CPPUNIT_TEST(test_rx);
   CPPUNIT_TEST_SUITE_END();
 
  private:
@@ -39,6 +40,7 @@
   void test_chan_deallocation();
   void test_open_close();
   void test_tx();
+  void test_rx();
 };
 
 #endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh   
    2007-06-09 02:55:25 UTC (rev 5752)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh   
    2007-06-09 03:17:57 UTC (rev 5753)
@@ -27,9 +27,9 @@
 ;; ----------------------------------------------------------------
 
 ;; ----------------------------------------------------------------
-;; tx-channels
+;; usrp-interface-cs
 ;;
-;; Handles a query for the number of tx-channels
+;; Handles interaction between the usrp_sever and the USB interface
 
 (define-protocol-class usrp-interface-cs
 
@@ -39,6 +39,7 @@
    (cmd-usrp-ntx-chan invocation-handle)
    (cmd-usrp-nrx-chan invocation-handle)
    (cmd-usrp-write invocation-handle channel data)
+   (cmd-usrp-start-reading invocation-handle channel)
    )
 
   (:incoming
@@ -46,6 +47,42 @@
    (response-usrp-close invocation-handle status)
    (response-usrp-ntx-chan invocation-handle ntx-chan)
    (response-usrp-nrx-chan invocation-handle nrx-chan)
-   (response-usrp-write invocation-handle channel status)
+   (response-usrp-write invocation-handle status channel)
+   (response-usrp-read invocation-handle status data)
    )
   )
+
+;; ----------------------------------------------------------------
+;; usrp-tx-cs
+;;
+;; Handles interaction between the USB interface and RX interface
+
+(define-protocol-class usrp-tx-cs
+
+  (:outgoing
+   (cmd-usrp-tx-write invocation-handle channel data tx-handle)
+   )
+
+  (:incoming
+   (response-usrp-tx-write invocation-handle status channel)
+   )
+  )
+
+;; ----------------------------------------------------------------
+;; usrp-rx-cs
+;;
+;; Handles interaction between the USB interface and RX interface
+
+(define-protocol-class usrp-rx-cs
+
+  (:outgoing
+   (cmd-usrp-rx-start-reading invocation-handle rx-handle)
+   (cmd-usrp-rx-stop-reading invocation-handle)
+   )
+
+  (:incoming
+   (response-usrp-rx-read invocation-handle status data)
+
+   ;; There is currently no response to a stop reading
+   )
+  )

Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.cc 
(from rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_rx.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.cc       
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.cc       
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,117 @@
+/* -*- 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 2, 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 <usrp_rx.h>
+
+#include <usrp_standard.h>
+#include <iostream>
+#include <vector>
+#include <usb.h>
+#include <mb_class_registry.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include <stdio.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static const bool verbose = false;
+
+static pmt_t s_cmd_usrp_rx_start_reading = 
pmt_intern("cmd-usrp-rx-start-reading");
+static pmt_t s_response_usrp_rx_read = pmt_intern("response-usrp-rx-read");
+
+usrp_rx::usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg)
+  : mb_mblock(rt, instance_name, user_arg)
+{
+  d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL);
+  
+}
+
+usrp_rx::~usrp_rx() 
+{
+}
+
+void 
+usrp_rx::initial_transition()
+{
+  
+}
+
+void
+usrp_rx::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t port_id = msg->port_id();
+  pmt_t data = msg->data(); 
+
+  // 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_eqv(event, s_cmd_usrp_rx_start_reading))
+      read_and_respond(data);
+  }
+}
+
+void
+usrp_rx::read_and_respond(pmt_t data)
+{
+  size_t ignore;
+  bool underrun;
+  unsigned int n_read;
+  unsigned int pkt_size = sizeof(transport_pkt);
+
+  pmt_t invocation_handle = pmt_nth(0, data);
+
+  // Need the handle to the RX port to send responses, this is passed
+  // by the USRP interface m-block
+  d_urx = 
+    boost::any_cast<usrp_standard_rx *>(pmt_any_ref(pmt_nth(1, data)));
+
+  pmt_t v_pkt = pmt_make_u8vector(pkt_size, 0);
+  transport_pkt *pkt = 
+    (transport_pkt *) pmt_u8vector_writeable_elements(v_pkt, ignore);
+
+  if(verbose)
+    std::cout << "[usrp_rx] Waiting for packets..\n";
+
+  // Read by 512 which is packet size and send them back up
+  while(1) {
+    n_read = d_urx->read(pkt, pkt_size, &underrun);
+
+    if(n_read != pkt_size) {
+      std::cerr << "[usrp_rx] Error reading packet, shutting down\n";
+      d_cs->send(s_response_usrp_rx_read, 
+                 pmt_list3(PMT_NIL, PMT_F, PMT_NIL));
+      return;
+    }
+
+    d_cs->send(s_response_usrp_rx_read, 
+               pmt_list3(PMT_NIL, PMT_T, v_pkt));
+    if(verbose)
+      std::cout << "[usrp_rx] Read 1 packet\n";
+  }
+}
+
+REGISTER_MBLOCK_CLASS(usrp_rx);

Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.h 
(from rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_rx.h)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.h        
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.h        
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,50 @@
+/* -*- 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 2, 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_USRP_RX_H
+#define INCLUDED_USRP_RX_H
+
+#include <mb_mblock.h>
+
+class usrp_standard_rx;
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_rx : public mb_mblock
+{
+  mb_port_sptr         d_cs;
+  usrp_standard_rx     *d_urx;
+  
+ public:
+  usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
+  ~usrp_rx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void read_and_respond(pmt_t data);
+  void read_data();
+ 
+};
+  
+
+#endif /* INCLUDED_USRP_RX_H */
+

Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.lo 
(from rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_rx.lo)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.lo       
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx.lo       
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,12 @@
+# usrp_rx.lo - a libtool object file
+# Generated by ltmain.sh - GNU libtool 1.5.22 (1.1220.2.365 2005/12/18 
22:14:06)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object='.libs/usrp_rx.o'
+
+# Name of the non-PIC object.
+non_pic_object=none
+

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.cc 
(from rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_rx_stub.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.cc  
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.cc  
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,158 @@
+/* -*- 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 2, 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 <usrp_rx_stub.h>
+
+#include <iostream>
+#include <vector>
+#include <usb.h>
+#include <mb_class_registry.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include "usrp_standard.h"
+#include <stdio.h>
+#include "ui_nco.h"
+#include <fstream>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static const bool verbose = false;
+
+bool usrp_rx_stop;
+
+static pmt_t s_cmd_usrp_rx_start_reading = 
pmt_intern("cmd-usrp-rx-start-reading");
+static pmt_t s_response_usrp_rx_read = pmt_intern("response-usrp-rx-read");
+
+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_amplitude(16384),
+    d_disk_write(false)
+{
+  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; 
+  d_nco.set_freq(2*M_PI * freq/sample_rate);
+
+  //d_disk_write = true;
+  
+  if(d_disk_write)
+    d_ofile.open("raw_rx.dat",std::ios::binary|std::ios::out);
+  
+  usrp_rx_stop = false;
+}
+
+usrp_rx_stub::~usrp_rx_stub() 
+{
+  if(d_disk_write)
+    d_ofile.close();
+}
+
+void 
+usrp_rx_stub::initial_transition()
+{
+  
+}
+
+void
+usrp_rx_stub::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t port_id = msg->port_id();
+  pmt_t data = msg->data(); 
+
+  // 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(verbose)
+      std::cout << "Got start\n";
+    
+    if(pmt_eqv(event, s_cmd_usrp_rx_start_reading))
+      read_and_respond(data);
+  }
+}
+
+void
+usrp_rx_stub::read_and_respond(pmt_t data)
+{
+
+  while(!usrp_rx_stop) {
+
+    long nsamples_this_frame = d_samples_per_frame;
+
+    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);
+
+    // fill in the complex sinusoid
+
+    for (int i = 0; i < nsamples_this_frame; i++){
+
+      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);
+
+        // 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);
+
+    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));
+
+  }
+  
+  usrp_rx_stop = false;
+
+  if(verbose)
+    std::cout << "[USRP_TX_STUB] Got fake RX stop\n";
+
+}
+
+REGISTER_MBLOCK_CLASS(usrp_rx_stub);

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.h (from 
rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_rx_stub.h)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.h   
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_rx_stub.h   
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,66 @@
+/* -*- 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 2, 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_USRP_RX_STUB_H
+#define INCLUDED_USRP_RX_STUB_H
+
+#include <mb_mblock.h>
+#include <vector>
+#include "usrp_standard.h"
+#include "ui_nco.h"
+#include <fstream>
+
+extern bool usrp_rx_stop;   // used to communicate a 'stop' to the RX stub
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_rx_stub : public mb_mblock
+{
+ public:
+
+  mb_port_sptr d_cs;
+  usrp_standard_rx* d_urx;
+  
+  long         d_samples_per_frame;
+  
+  // for generating sine wave output
+  ui_nco<float,float>  d_nco;
+  double               d_amplitude;
+
+  bool d_disk_write;
+
+  std::ofstream d_ofile;
+  
+ public:
+  usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg);
+  ~usrp_rx_stub();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void read_and_respond(pmt_t data);
+  void read_data();
+ 
+};
+  
+
+#endif /* INCLUDED_USRP_RX_H */
+

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc   
2007-06-09 02:55:25 UTC (rev 5752)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc   
2007-06-09 03:17:57 UTC (rev 5753)
@@ -28,7 +28,6 @@
 #include <mb_class_registry.h>
 #include <vector>
 #include <usrp_usb_interface.h>
-#include <usrp_usb_interface_stub.h>
 
 typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit 
easy
 
@@ -69,11 +68,14 @@
 static pmt_t s_cmd_usrp_write = pmt_intern("cmd-usrp-write");
 static pmt_t s_cmd_usrp_ntx_chan = pmt_intern("cmd-usrp-ntx-chan");
 static pmt_t s_cmd_usrp_nrx_chan = pmt_intern("cmd-usrp-nrx-chan");
+static pmt_t s_cmd_usrp_start_reading = pmt_intern("cmd-usrp-start-reading");
+static pmt_t s_cmd_usrp_stop_reading = pmt_intern("cmd-usrp-stop-reading");
 static pmt_t s_response_usrp_ntx_chan = pmt_intern("response-usrp-ntx-chan");
 static pmt_t s_response_usrp_nrx_chan = pmt_intern("response-usrp-nrx-chan");
 static pmt_t s_response_usrp_open = pmt_intern("response-usrp-open");
 static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close");
 static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write");
+static pmt_t s_response_usrp_read = pmt_intern("response-usrp-read");
 
 
 const static bool verbose = false;
@@ -87,25 +89,13 @@
 }
 
 usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, 
pmt_t user_arg)
-  : mb_mblock(rt, instance_name, user_arg)
+  : mb_mblock(rt, instance_name, user_arg),
+  d_fake_rx(false)
 {
 
-  // Default USRP interface
-  std::string usrp_interface = "usrp_usb_interface";
-
-  // a dictionary is given for usrp server parameters, such as the interface 
to use
+  // Dictionary for arguments to all of the components
   pmt_t usrp_dict = user_arg;
   
-  if (pmt_is_dict(usrp_dict) && pmt_dict_has_key(usrp_dict, 
pmt_intern("usrp-interface"))){
-    usrp_interface =
-      pmt_symbol_to_string(pmt_dict_ref(usrp_dict,
-                                       pmt_intern("usrp-interface"),
-                                       PMT_NIL));
-  }
-
-  if (verbose)
-    std::cout << "[USRP_SERVER] Using interface: " << usrp_interface << "\n";
-
   // control & status port
   d_cs = define_port("cs", "usrp-server-cs", true, mb_port::EXTERNAL); 
   d_cs_usrp = define_port("cs_usrp", "usrp-interface-cs", false, 
mb_port::INTERNAL);   
@@ -115,11 +105,19 @@
   // (if/when we do replicated ports, these will be replaced by a
   //  single replicated port)
   for(int port=0; port < N_PORTS; port++) {
-    d_tx.push_back(define_port("tx"+str(port), "usrp-tx", true, 
mb_port::EXTERNAL));
-    d_rx.push_back(define_port("rx"+str(port), "usrp-rx", true, 
mb_port::EXTERNAL));
+
+    d_tx.push_back(define_port("tx"+str(port), 
+                               "usrp-tx", 
+                               true, 
+                               mb_port::EXTERNAL));
+
+    d_rx.push_back(define_port("rx"+str(port), 
+                               "usrp-rx", 
+                               true, 
+                               mb_port::EXTERNAL));
   }
 
-  define_component("usrp", usrp_interface, PMT_F);
+  define_component("usrp", "usrp_usb_interface", usrp_dict);
   connect("self", "cs_usrp", "usrp", "cs");
 
   d_defer=false;
@@ -131,21 +129,32 @@
 
   // Initialize capacity on each channel to 0 and to no owner
   // Also initialize the USRP standard tx/rx pointers to NULL
-  reset_channels();
-  
+  for(int chan=0; chan < d_ntx_chan; chan++)
+    d_chaninfo_tx.push_back(channel_info());
+
+  for(int chan=0; chan < d_nrx_chan; chan++)
+    d_chaninfo_rx.push_back(channel_info());
+
+  d_rx_chan_mask = 0;
+
+  //d_fake_rx=true;
 }
 
 void
 usrp_server::reset_channels()
 {
+
   for(int chan=0; chan < d_ntx_chan; chan++) {
     d_chaninfo_tx[chan].assigned_capacity = 0;
     d_chaninfo_tx[chan].owner = PMT_NIL;
   }
+
   for(int chan=0; chan < d_nrx_chan; chan++) {
     d_chaninfo_rx[chan].assigned_capacity = 0;
     d_chaninfo_rx[chan].owner = PMT_NIL;
   }
+
+  d_rx_chan_mask = 0;
 }
 
 usrp_server::~usrp_server()
@@ -165,31 +174,38 @@
   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 invocation_handle;
   pmt_t metadata = msg->metadata();
-  pmt_t invocation_handle;
-  pmt_t reply_data;
   pmt_t status;
 
+  long port;
+
+  // shutdown has no invocation handle, this prevents an exception
+  if(!pmt_eq(event, pmt_intern("%shutdown")))
+    invocation_handle = pmt_nth(0, data);
+
   if (verbose){
     std::cout << "[USRP_SERVER] event: " << event << std::endl;
     std::cout << "[USRP_SERVER] port_id: " << port_id << std::endl;
   }
 
-  // It would be nice if this were all table driven, and we could
-  // compute our state transition as f(current_state, port_id, signal)
+  // It would be nice if this were all table driven, and we could compute our
+  // state transition as f(current_state, port_id, signal)
   
   // A message from the USRP CS, which should *only* be responses
   //
   // It is important that this set come before checking messages of any other
   // components.  This is since we always want to listen to the low level USRP
   // server, even if we aren't initialized we are waiting for responses to
-  // become initialized.  Likewise, after the usrp_server is "closed", we
-  // still want to pass responses back from the low level.
+  // become initialized.  Likewise, after the usrp_server is "closed", we still
+  // want to pass responses back from the low level.
+
+  //---------------- USRP RESPONSE ---------------//
   if (pmt_eq(port_id, d_cs_usrp->port_symbol())) { 
-
+    
+    //-------------- USRP OPEN ------------------//
     if(pmt_eq(event, s_response_usrp_open)) {
       // pass the response back over the regular CS port
-      invocation_handle = pmt_nth(0, data);
       pmt_t status = pmt_nth(1, data);
       d_cs->send(s_response_open, pmt_list2(invocation_handle, status));
 
@@ -201,11 +217,11 @@
 
       return;
     }
+    //------------- USRP CLOSE -------------------//
     else if (pmt_eq(event, s_response_usrp_close)) {
-      invocation_handle = pmt_nth(0, data);
       pmt_t status = pmt_nth(1, data);
       d_cs->send(s_response_close, pmt_list2(invocation_handle, status));
-      
+
       if(pmt_eqv(status,PMT_T)) {
         d_opened = false;
         d_defer = false;
@@ -215,36 +231,54 @@
       
       return;
     }
+    //--------------- USRP WRITE --------------//
     else if (pmt_eq(event, s_response_usrp_write)) {
       
-      invocation_handle = pmt_nth(0, data);
-      long channel = pmt_to_long(pmt_nth(1, data));
-      pmt_t status = pmt_nth(2, data);
+      pmt_t status = pmt_nth(1, data);
+      long channel = pmt_to_long(pmt_nth(2, data));
+      long port;
 
       // Find the port through the owner of the channel
-      long port = tx_port_index(d_chaninfo_tx[channel].owner);
-      d_tx[port]->send(s_response_xmit_raw_frame, pmt_list2(invocation_handle, 
status));
+      if((port = tx_port_index(d_chaninfo_tx[channel].owner)) !=-1 )
+        d_tx[port]->send(s_response_xmit_raw_frame, 
+                         pmt_list2(invocation_handle, status));
       return;
     }
+    //--------------- USRP READ ---------------//
+    else if (pmt_eq(event, s_response_usrp_read)) {
 
+      pmt_t status = pmt_nth(1, data);
+
+      if(!pmt_eqv(status, PMT_T)) {
+        std::cerr << "[USRP_SERVER] Error receiving packet\n";
+        return;
+      }
+      else {
+        handle_response_usrp_read(data);
+        return;
+      }
+    }
+
     goto unhandled;
   }
 
   // Checking for defer on all other messages
   if(d_defer) {
     if (verbose)
-      std::cout << "[USRP_SERVER] Received msg while deferring (" << 
msg->signal() << ")\n";
+      std::cout << "[USRP_SERVER] Received msg while deferring (" 
+                << msg->signal() << ")\n";
     d_defer_queue.push(msg);
     return;
   }
 
-  if (pmt_eq(port_id, d_cs->port_symbol())){   // message came in on our 
control/status port
-
+  //--------- CONTROL / STATUS ------------//
+  if (pmt_eq(port_id, d_cs->port_symbol())){
+    
+    //----------- OPEN -----------//
     if (pmt_eq(event, s_cmd_open)){
 
       // Reject if already open
       if(d_opened) {
-        invocation_handle = pmt_nth(0, data);
         d_cs->send(s_response_open, pmt_list2(invocation_handle, PMT_F));
         return;
       }
@@ -256,8 +290,9 @@
       
       return;
     }
+    //---------- CLOSE -----------//
     else if (pmt_eq(event, s_cmd_close)){
-      invocation_handle = pmt_nth(0, data);
+      
       if(!d_opened) { 
         d_cs->send(s_response_close, pmt_list2(invocation_handle, PMT_F));
         return;
@@ -268,95 +303,179 @@
 
       return;
     }
+    //---------- MAX CAPACITY ----------//
     else if (pmt_eq(event, s_cmd_max_capacity)) {
-      invocation_handle = pmt_nth(0, data);
+      
       if(!d_opened) { 
-        d_cs->send(s_response_max_capacity, pmt_list3(invocation_handle, 
PMT_F, pmt_from_long(0)));
+        d_cs->send(s_response_max_capacity, 
+                   pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
         return;
       }
-      reply_data = pmt_list3(invocation_handle, PMT_T, 
pmt_from_long(max_capacity()));
-      d_cs->send(s_response_max_capacity, reply_data);
+
+      d_cs->send(s_response_max_capacity, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(max_capacity())));
       return;
     }
+    //---------- NTX CHAN --------------//
     else if (pmt_eq(event, s_cmd_ntx_chan)) {
-      invocation_handle = pmt_nth(0, data);
+
       if(!d_opened) { 
-        d_cs->send(s_response_ntx_chan, pmt_list3(invocation_handle, PMT_F, 
pmt_from_long(0)));
+        d_cs->send(s_response_ntx_chan, 
+                   pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
         return;
       }
-      reply_data = pmt_list3(invocation_handle, PMT_T, 
pmt_from_long(d_ntx_chan));
-      d_cs->send(s_response_ntx_chan, reply_data);
+
+      d_cs->send(s_response_ntx_chan, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(d_ntx_chan)));
       return;
     }
+    //---------- NRX CHAN -----------//
     else if (pmt_eq(event, s_cmd_nrx_chan)) {
-      invocation_handle = pmt_nth(0, data);
+
       if(!d_opened) { 
-        d_cs->send(s_response_nrx_chan, pmt_list3(invocation_handle, PMT_F, 
pmt_from_long(0)));
+        d_cs->send(s_response_nrx_chan, 
+                   pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
         return;
       }
-      reply_data = pmt_list3(invocation_handle, PMT_T, 
pmt_from_long(d_nrx_chan));
-      d_cs->send(s_response_nrx_chan, reply_data);
+
+      d_cs->send(s_response_nrx_chan, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(d_nrx_chan)));
       return;
-    }
+    }  
+    //--------- ALLOCATION? -----------//
     else if (pmt_eq(event, s_cmd_current_capacity_allocation)) {
-      invocation_handle = pmt_nth(0, data);
+      
       if(!d_opened) { 
-        d_cs->send(s_response_current_capacity_allocation, 
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
+        d_cs->send(s_response_current_capacity_allocation, 
+                   pmt_list3(invocation_handle, 
+                             PMT_F, 
+                             pmt_from_long(0)));
         return;
       }
-      reply_data = pmt_list3(invocation_handle, PMT_T, 
pmt_from_long(current_capacity_allocation()));
-      d_cs->send(s_response_current_capacity_allocation, reply_data);
+      
+      d_cs->send(s_response_current_capacity_allocation, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(current_capacity_allocation())));
       return;
     }
     goto unhandled;
   }
+  
+  //-------------- TX ---------------//
+  if ((port = tx_port_index(port_id)) != -1) {
+    
+    //------------ ALLOCATE (TX) ----------------//
+    if (pmt_eq(event, s_cmd_allocate_channel)){
+      
+      if(!d_opened) { 
+        d_tx[port]->send(s_response_allocate_channel, 
+                          pmt_list3(invocation_handle, 
+                                    PMT_F, 
+                                    pmt_from_long(0)));
+        return;
+      }
+        
+      handle_cmd_allocate_channel(d_tx[port], d_chaninfo_tx, data);
+      return;
+    }
+  
+    //----------- DEALLOCATE (TX) ---------------//
+    if (pmt_eq(event, s_cmd_deallocate_channel)) {
+    
+      if(!d_opened) {
+        d_tx[port]->send(s_response_deallocate_channel, 
+                         pmt_list3(invocation_handle, 
+                                   PMT_F, 
+                                   pmt_from_long(0)));
+        return;
+      }
 
+      handle_cmd_deallocate_channel(d_tx[port], d_chaninfo_tx, data);
+      return;
+    }
+  
+    //-------------- XMIT RAW FRAME -----------------/
+    if (pmt_eq(event, s_cmd_xmit_raw_frame)){
 
-  if (pmt_eq(event, s_cmd_allocate_channel)){
-    if(!d_opened) {    // check the USRP was opened
-      pmt_t invocation_handle = pmt_nth(0, data);
-
-      long port;
-      if((port = tx_port_index(port_id)) != -1) {
-        d_tx[port]->send(s_response_allocate_channel, 
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
-      } else {
-        port = rx_port_index(port_id);
-        d_rx[port]->send(s_response_allocate_channel, 
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
+      if(!d_opened) { 
+        d_tx[port]->send(s_response_xmit_raw_frame, 
+                         pmt_list2(invocation_handle, PMT_F));
+        return;
       }
+      
+      handle_cmd_xmit_raw_frame(d_tx[port], d_chaninfo_tx, data);
       return;
     }
 
-    handle_cmd_allocate_channel(port_id, data);
-    return;
+    goto unhandled;
   }
 
-  if (pmt_eq(event, s_cmd_deallocate_channel)) {
-    if(!d_opened) {    // check the USRP was opened
-      pmt_t invocation_handle = pmt_nth(0, data);
-
-      long port;
-      if((port = tx_port_index(port_id)) != -1) {
-        d_tx[port]->send(s_response_allocate_channel, 
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
-      } else {
-        port = rx_port_index(port_id);
-        d_rx[port]->send(s_response_allocate_channel, 
pmt_list3(invocation_handle, PMT_F, pmt_from_long(0)));
+  //-------------- RX ---------------//
+  if ((port = rx_port_index(port_id)) != -1) {
+    
+    //------------ ALLOCATE (RX) ----------------//
+    if (pmt_eq(event, s_cmd_allocate_channel)) {
+      
+      if(!d_opened) { 
+        d_rx[port]->send(s_response_allocate_channel, 
+                          pmt_list3(invocation_handle, 
+                                    PMT_F, 
+                                    pmt_from_long(0)));
+        return;
       }
+        
+      handle_cmd_allocate_channel(d_rx[port], d_chaninfo_rx, data);
       return;
     }
+  
+    //----------- DEALLOCATE (RX) ---------------//
+    if (pmt_eq(event, s_cmd_deallocate_channel)) {
+    
+      if(!d_opened) {
+        d_rx[port]->send(s_response_deallocate_channel, 
+                         pmt_list3(invocation_handle, 
+                                   PMT_F, 
+                                   pmt_from_long(0)));
+        return;
+      }
 
-    handle_cmd_deallocate_channel(port_id, data);
-    return;
-  }
+      handle_cmd_deallocate_channel(d_rx[port], d_chaninfo_rx, data);
+      return;
+    }
+  
+    //-------------- START RECV ----------------//
+    if (pmt_eq(event, s_cmd_start_recv_raw_samples)) {
     
-  if (pmt_eq(event, s_cmd_xmit_raw_frame)){
-    if(!d_opened) {    // check the USRP was opened
-      pmt_t invocation_handle = pmt_nth(0, data);
-      long port = tx_port_index(port_id);
-      d_tx[port]->send(s_response_xmit_raw_frame, pmt_list2(invocation_handle, 
PMT_F));
+      if(!d_opened) {
+        d_rx[port]->send(s_response_recv_raw_samples,
+                         pmt_list2(invocation_handle, PMT_F));
+        return;
+      }
+
+      handle_cmd_start_recv_raw_samples(d_rx[port], d_chaninfo_rx, data);
       return;
     }
-    handle_cmd_xmit_raw_frame(port_id, data);
-    return;
+    
+    //-------------- STOP RECV ----------------//
+    if (pmt_eq(event, s_cmd_stop_recv_raw_samples)) {
+    
+      if(!d_opened) 
+        return;
+
+      // FIX ME : no response for stopping? even if error? (permissions)
+      handle_cmd_stop_recv_raw_samples(d_rx[port], d_chaninfo_rx, data);
+
+      return;
+    }
+
+    goto unhandled;
   }
 
  unhandled:
@@ -397,190 +516,284 @@
   return capacity;
 }
     
-void usrp_server::handle_cmd_allocate_channel(pmt_t port_id, pmt_t data) {
-
+void 
+usrp_server::handle_cmd_allocate_channel(
+                                mb_port_sptr port, 
+                                std::vector<struct channel_info> &chan_info,
+                                pmt_t data)
+{
   pmt_t invocation_handle = pmt_nth(0, data);
   long rqstd_capacity = pmt_to_long(pmt_nth(1, data));
-  long chan, port;
-  pmt_t reply_data;
+  long chan;
 
-  // If it's a TX port, allocate on a free channel, else check if it's a RX 
port
-  // and allocate.
-  if((port = tx_port_index(port_id)) != -1) {
+  // Check capacity exists
+  if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) {
 
-    // Check capacity exists
-    if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) {
-      reply_data = pmt_list3(invocation_handle, 
pmt_from_long(RQSTD_CAPACITY_UNAVAIL), PMT_NIL);  // no capacity available
-      d_tx[port]->send(s_response_allocate_channel, reply_data);
-      return;
-    }
+    // no capacity available
+    port->send(s_response_allocate_channel, 
+               pmt_list3(invocation_handle, 
+                         pmt_from_long(RQSTD_CAPACITY_UNAVAIL), 
+                         PMT_NIL));
+    return;
+  }
 
-    // Find a free channel, assign the capacity and respond
-    for(chan=0; chan < d_ntx_chan; chan++) {
-      if(d_chaninfo_tx[chan].owner == PMT_NIL) {
-        d_chaninfo_tx[chan].owner = port_id;
-        d_chaninfo_tx[chan].assigned_capacity = rqstd_capacity;
-        reply_data = pmt_list3(invocation_handle, PMT_T, pmt_from_long(chan));
-        d_tx[port]->send(s_response_allocate_channel, reply_data);
-        return;
-      }
-    }
+  // Find a free channel, assign the capacity and respond
+  for(chan=0; chan < (long)chan_info.size(); chan++) {
 
-    if (verbose)
-      std::cout << "[USRP_SERVER] Couldnt find a TX chan\n";
+    if(verbose)
+      std::cout << "[USRP_SERVER] Checking chan: " << chan
+                << " owner " << chan_info[chan].owner
+                << " size " << chan_info.size()
+                << std::endl;
 
-    reply_data = pmt_list3(invocation_handle, pmt_from_long(CHANNEL_UNAVAIL), 
PMT_NIL);  // no free TX chan found
-    d_tx[port]->send(s_response_allocate_channel, reply_data);
-    return;
-  }
+    if(chan_info[chan].owner == PMT_NIL) {
   
-  // Repeat the same process on the RX side if the port was not determined to 
be TX
-  if((port = rx_port_index(port_id)) != -1) {
-    
-    if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) {
-      reply_data = pmt_list3(invocation_handle, 
pmt_from_long(RQSTD_CAPACITY_UNAVAIL), PMT_NIL);  // no capacity available
-      d_rx[port]->send(s_response_allocate_channel, reply_data);
+      chan_info[chan].owner = port->port_symbol();
+      chan_info[chan].assigned_capacity = rqstd_capacity;
+      
+      port->send(s_response_allocate_channel, 
+                 pmt_list3(invocation_handle, 
+                           PMT_T, 
+                           pmt_from_long(chan)));
+
+      if(verbose)
+        std::cout << "[USRP_SERVER] Assigning channel: " << chan 
+                  << " to " << chan_info[chan].owner
+                  << std::endl;
       return;
     }
+  
+  }
 
-    for(chan=0; chan < d_nrx_chan; chan++) {
-      if(d_chaninfo_rx[chan].owner == PMT_NIL) {
-        d_chaninfo_rx[chan].owner = port_id;
-        d_chaninfo_rx[chan].assigned_capacity = rqstd_capacity;
-        reply_data = pmt_list3(invocation_handle, PMT_T, pmt_from_long(chan));
-        d_rx[port]->send(s_response_allocate_channel, reply_data);
-        return;
-      }
-    }
+  if (verbose)
+    std::cout << "[USRP_SERVER] Couldnt find a TX chan\n";
 
-    if (verbose)
-      std::cout << "[USRP_SERVER] Couldnt find a RX chan\n";
-    reply_data = pmt_list3(invocation_handle, pmt_from_long(CHANNEL_UNAVAIL), 
PMT_NIL);  // no free RX chan found
-    d_rx[port]->send(s_response_allocate_channel, reply_data);
-    return;
-  }
+  // no free TX chan found
+  port->send(s_response_allocate_channel, 
+             pmt_list3(invocation_handle, 
+                       pmt_from_long(CHANNEL_UNAVAIL), 
+                       PMT_NIL));
+  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.
-void usrp_server::handle_cmd_deallocate_channel(pmt_t port_id, pmt_t data) {
+// that the owner of the method invocation is the owner of the port and that 
the
+// channel number is valid.
+void 
+usrp_server::handle_cmd_deallocate_channel(
+                              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));
-  long port;
-  pmt_t reply_data;
+
+  // Ensure the channel is valid and the caller owns the port
+  if(!check_valid(port, channel, chan_info,
+                  pmt_list2(s_response_deallocate_channel, invocation_handle)))
+    return;
   
-  // Check that the channel number is valid, and that the calling port is the 
owner
-  // of the channel, and if so remove the assigned capacity.
-  if((port = tx_port_index(port_id)) != -1) {
-  
-    if(channel >= d_ntx_chan) {
-      reply_data = pmt_list2(invocation_handle, 
pmt_from_long(CHANNEL_INVALID));   // not a legit channel number
-      d_tx[port]->send(s_response_deallocate_channel, reply_data);
-      return;
-    }
+  chan_info[channel].assigned_capacity = 0;
+  chan_info[channel].owner = PMT_NIL;
 
-    if(d_chaninfo_tx[channel].owner != port_id) {
-      reply_data = pmt_list2(invocation_handle, 
pmt_from_long(PERMISSION_DENIED));   // not the owner of the port
-      d_tx[port]->send(s_response_deallocate_channel, reply_data);
-      return;
-    }
+  port->send(s_response_deallocate_channel, 
+             pmt_list2(invocation_handle, 
+                       PMT_T));
+  return;
+}
 
-    d_chaninfo_tx[channel].assigned_capacity = 0;
-    d_chaninfo_tx[channel].owner = PMT_NIL;
+void usrp_server::handle_cmd_xmit_raw_frame(mb_port_sptr port, 
std::vector<struct channel_info> &chan_info, pmt_t data) {
 
-    reply_data = pmt_list2(invocation_handle, PMT_T);
-    d_tx[port]->send(s_response_deallocate_channel, reply_data);
+  size_t n_bytes, psize;
+  long max_payload_len = transport_pkt::max_payload();
+
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long channel = pmt_to_long(pmt_nth(1, data));
+  const void *samples = pmt_uniform_vector_elements(pmt_nth(2, data), n_bytes);
+  long timestamp = pmt_to_long(pmt_nth(3, data));
+  
+  // Ensure the channel is valid and the caller owns the port
+  if(!check_valid(port, channel, chan_info,
+                  pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
     return;
-  }
+  
+  // Determine the number of packets to allocate contiguous memory for
+  // bursting over the USB and get a pointer to the memory to be used in
+  // building the packets
+  long n_packets = 
+    static_cast<long>(std::ceil(n_bytes / (double)max_payload_len));
 
-  // Repeated process on the RX side
-  if((port = rx_port_index(port_id)) != -1) {
+  pmt_t v_packets = pmt_make_u8vector(sizeof(transport_pkt) * n_packets, 0);
+
+  transport_pkt *pkts =
+    (transport_pkt *) pmt_u8vector_writeable_elements(v_packets, psize);
+
+  for(int n=0; n < n_packets; n++) {
+
+    long payload_len = 
+      std::min((long)(n_bytes-(n*max_payload_len)), (long)max_payload_len);
   
-    if(channel >= d_nrx_chan) {
-      reply_data = pmt_list2(invocation_handle, 
pmt_from_long(CHANNEL_INVALID));   // not a legit channel number
-      d_rx[port]->send(s_response_deallocate_channel, reply_data);
-      return;
+    if(n == 0) { // first packet gets start of burst flag and timestamp
+      pkts[n].set_header(pkts[n].FL_START_OF_BURST, channel, 0, payload_len);
+      pkts[n].set_timestamp(timestamp);
+    } else {
+      pkts[n].set_header(0, channel, 0, payload_len);
+      pkts[n].set_timestamp(0xffffffff);
     }
 
-    if(d_chaninfo_rx[channel].owner != port_id) {
-      reply_data = pmt_list2(invocation_handle, 
pmt_from_long(PERMISSION_DENIED));   // not the owner of the port
-      d_rx[port]->send(s_response_deallocate_channel, reply_data);
-      return;
-    }
+    memcpy(pkts[n].payload(), 
+           (uint8_t *)samples+(max_payload_len * n), 
+           payload_len);
+  
+  }
 
-    d_chaninfo_rx[channel].assigned_capacity = 0;
-    d_chaninfo_rx[channel].owner = PMT_NIL;
 
-    reply_data = pmt_list2(invocation_handle, PMT_T);
-    d_rx[port]->send(s_response_deallocate_channel, reply_data);
+  pkts[n_packets-1].set_end_of_burst(); // set the last packet's end of burst
+
+  if (verbose)
+    std::cout << "[USRP_SERVER] Received raw frame invocation: " 
+              << invocation_handle << std::endl;
+    
+  // The actual response to the write will be generated by a
+  // s_response_usrp_write
+  d_cs_usrp->send(s_cmd_usrp_write, 
+                  pmt_list3(invocation_handle, 
+                            pmt_from_long(channel), 
+                            v_packets));
+
+  return;
+}
+
+void
+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));
+
+  // Ensure the channel is valid and the caller owns the port
+  if(!check_valid(port, channel, chan_info,
+                  pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
     return;
+
+  // Already started receiving samples? (another start before a stop)
+  // Check the RX channel bitmask.
+  if(d_rx_chan_mask & (1 << channel)) {
+    port->send(s_response_recv_raw_samples,
+               pmt_list5(invocation_handle,
+                         pmt_from_long(ALREADY_RECV),
+                         PMT_NIL,
+                         PMT_NIL,
+                         PMT_NIL));
+    return;
   }
 
-}
+  // We only need to generate a 'start reading' command down to the
+  // low level interface if no other channel is already reading
+  //
+  // We carry this over the CS interface because the lower level
+  // interface does not care about the channel, we only demux it
+  // at the usrp_server on responses.
+  if(d_rx_chan_mask == 0) {
+    
+    if(verbose)
+      std::cout << "[USRP_SERVER] Sending read request down to start recv\n";
 
-void usrp_server::handle_cmd_xmit_raw_frame(pmt_t port_id, pmt_t data) {
+    d_cs_usrp->send(s_cmd_usrp_start_reading, pmt_list1(invocation_handle));
+  }
 
-  size_t n_bytes, psize;
-  long max_payload_len = transport_pkt::max_payload();
-  pmt_t reply_data;
+  d_rx_chan_mask |= 1<<channel;
+  
+  return;
+}
 
+void
+usrp_server::handle_cmd_stop_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));
-  const void *samples = pmt_uniform_vector_elements(pmt_nth(2, data), n_bytes);
-  long timestamp = pmt_to_long(pmt_nth(3, data));
-  
-  long port;
 
-  // Check that the channel number is valid, and that the caller is the owner
-  // of the channel to send the frame
-  if((port = tx_port_index(port_id)) != -1) {
+  // FIX ME : we have no responses to send an error...
+  // Ensure the channel is valid and the caller owns the port
+  //if(!check_valid(port, channel, chan_info,
+  //                pmt_list2(s_response_xmit_raw_frame, invocation_handle)))
+  //  return;
+
+  // Remove this hosts bit from the receiver mask
+  d_rx_chan_mask &= ~(1<<channel);
+
+  // We only need to generate a 'start reading' command down to the
+  // low level interface if no other channel is already reading
+  //
+  // We carry this over the CS interface because the lower level
+  // interface does not care about the channel, we only demux it
+  // at the usrp_server on responses.
+  if(d_rx_chan_mask == 0) {
+    
+    if(verbose)
+      std::cout << "[USRP_SERVER] Sending stop reading request down\n";
+
+    d_cs_usrp->send(s_cmd_usrp_stop_reading, pmt_list1(invocation_handle));
+  }
   
-    if(channel >= d_ntx_chan) {
-      reply_data = pmt_list2(invocation_handle, 
pmt_from_long(CHANNEL_INVALID));   // not a legit channel number
-      d_tx[port]->send(s_response_xmit_raw_frame, reply_data);
-      return;
-    }
+  return;
+}
 
-    if(d_chaninfo_tx[channel].owner != port_id) {
-      reply_data = pmt_list2(invocation_handle, 
pmt_from_long(PERMISSION_DENIED));   // not the owner of the port
-      d_tx[port]->send(s_response_xmit_raw_frame, reply_data);
-      return;
-    }
+// Read the packet header, determine the port by the channel owner
+void
+usrp_server::handle_response_usrp_read(pmt_t data)
+{
 
-    // Determine the number of packets to allocate contiguous memory for 
bursting over the
-    // USB and get a pointer to the memory to be used in building the packets
-    long n_packets = static_cast<long>(std::ceil(n_bytes / 
(double)max_payload_len));
-    pmt_t v_packets = pmt_make_u8vector(sizeof(transport_pkt) * n_packets, 0);
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t status = pmt_nth(1, data);
+  pmt_t v_pkt = pmt_nth(2, data);
 
-    transport_pkt *pkts =
-      (transport_pkt *) pmt_u8vector_writeable_elements(v_packets, psize);
+  size_t n_bytes;
+  size_t ignore;
 
-    for(int n=0; n < n_packets; n++) {
+  if(verbose)
+    std::cout << "[USRP_SERVER] Received raw samples\n";
 
-      long payload_len = std::min((long)(n_bytes-(n*max_payload_len)), 
(long)max_payload_len);
-    
-      if(n == 0) { // first packet gets start of burst flag and timestamp
-        pkts[n].set_header(pkts[n].FL_START_OF_BURST, channel, 0, payload_len);
-        pkts[n].set_timestamp(timestamp);
-      } else {
-        pkts[n].set_header(0, channel, 0, payload_len);
-        pkts[n].set_timestamp(0xffffffff);
-      }
+  if (d_fake_rx) {
 
-      memcpy(pkts[n].payload(), (uint8_t *)samples+(max_payload_len * n), 
payload_len);
-    }
+    pmt_t pkt = pmt_nth(2, data);
 
-    pkts[n_packets-1].set_end_of_burst();   // set the last packet's end of 
burst
+    d_rx[0]->send(s_response_recv_raw_samples,
+                  pmt_list5(PMT_F,
+                            PMT_T,
+                            pkt,
+                            pmt_from_long(0xffff),
+                            PMT_NIL));
 
-    if (verbose)
-      std::cout << "[USRP_SERVER] Received raw frame invocation: " << 
invocation_handle << std::endl;
+    return;
+  }
 
-    // The actual response to the write will be generated by a 
s_response_usrp_write
-    d_cs_usrp->send(s_cmd_usrp_write, pmt_list3(invocation_handle, 
pmt_from_long(channel), v_packets));
+  // Extract the packet and return appropriately
+  transport_pkt *pkt = (transport_pkt *) 
pmt_u8vector_writeable_elements(v_pkt, n_bytes);
 
-  }
+  // The channel is used to find the port to pass the samples on
+  long channel = pkt->chan();
+  long payload_len = pkt->payload_len();
+  long port;
+
+  if((port = rx_port_index(d_chaninfo_rx[channel].owner)) == -1)
+    return; // Don't know where to send the sample... possibility on abrupt 
close
+  
+  pmt_t v_samples = pmt_make_u8vector(payload_len, 0);
+  uint8_t *samples = pmt_u8vector_writeable_elements(v_samples, ignore);
+  
+  memcpy(samples, pkt->payload(), payload_len);
+
+  d_cs->send(s_response_recv_raw_samples,
+             pmt_list5(invocation_handle,
+                       status,
+                       v_samples,
+                       pmt_from_long(pkt->timestamp()),
+                       PMT_NIL));
+  return;
 }
 
 void
@@ -601,4 +814,46 @@
   return;
 }
 
+bool
+usrp_server::check_valid(mb_port_sptr port,
+                         long channel,
+                         std::vector<struct channel_info> &chan_info,
+                         pmt_t signal_info)
+{
+
+  pmt_t response_signal = pmt_nth(0, signal_info);
+  pmt_t invocation_handle = pmt_nth(1, signal_info);
+
+  // not a valid channel number?
+  if(channel >= chan_info.size()) {
+    port->send(response_signal, 
+               pmt_list2(invocation_handle, 
+                         pmt_from_long(CHANNEL_INVALID)));
+
+    if(verbose)
+      std::cout << "[USRP_SERVER] Invalid channel number for event " 
+                << response_signal << std::endl;
+    return false;
+  }
+  
+  // not the owner of the port?
+  if(chan_info[channel].owner != port->port_symbol()) {
+    port->send(response_signal, 
+               pmt_list2(invocation_handle, 
+                         pmt_from_long(PERMISSION_DENIED)));
+    
+    if(verbose)
+      std::cout << "[USRP_SERVER] Invalid permissions"
+                << " for " << response_signal
+                << " from " << port->port_symbol()
+                << " proper owner is " << chan_info[channel].owner
+                << " on channel " << channel
+                << " invocation " << invocation_handle
+                << std::endl;
+    return false;
+  }
+
+  return true;
+}
+
 REGISTER_MBLOCK_CLASS(usrp_server);

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h    
2007-06-09 02:55:25 UTC (rev 5752)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h    
2007-06-09 03:17:57 UTC (rev 5753)
@@ -24,6 +24,7 @@
 #include <mb_mblock.h>
 #include <vector>
 #include <queue>
+#include <fstream>
 
 /*!
  * \brief Implements the lowest-level mblock usb_interface to the USRP
@@ -35,7 +36,8 @@
     RQSTD_CAPACITY_UNAVAIL = 0,
     CHANNEL_UNAVAIL = 1,
     CHANNEL_INVALID = 2,
-    PERMISSION_DENIED = 3
+    PERMISSION_DENIED = 3,
+    ALREADY_RECV = 4
   };
 
   // our ports
@@ -54,18 +56,28 @@
   long d_nrx_chan;
 
   struct channel_info {
-    long assigned_capacity;  // the capacity currently assignedby the channel
+    long assigned_capacity;   // the capacity currently assignedby the channel
     pmt_t owner;              // port ID of the owner of the channel
+
+    channel_info() {
+      assigned_capacity = 0;
+      owner = PMT_NIL;
+    }
   };
 
-  struct channel_info d_chaninfo_tx[D_MAX_CHANNELS];
-  struct channel_info d_chaninfo_rx[D_MAX_CHANNELS];
+  long d_rx_chan_mask;    // A bitmask representing the channels in the
+                          // receiving state
 
+  std::vector<struct channel_info> d_chaninfo_tx;
+  std::vector<struct channel_info> d_chaninfo_rx;
+
   std::queue<mb_message_sptr> d_defer_queue;
 
   bool d_defer;
   bool d_opened;
 
+  bool d_fake_rx;
+
 public:
   usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg);
   ~usrp_server();
@@ -77,14 +89,18 @@
   static int max_capacity() { return D_USB_CAPACITY; }
 
 private:
-  void handle_cmd_allocate_channel(pmt_t port_id, pmt_t data);
-  void handle_cmd_deallocate_channel(pmt_t port_id, pmt_t data);
-  void handle_cmd_xmit_raw_frame(pmt_t port_id, pmt_t data);
+  void handle_cmd_allocate_channel(mb_port_sptr port, std::vector<struct 
channel_info> &chan_info, pmt_t data);
+  void handle_cmd_deallocate_channel(mb_port_sptr port, std::vector<struct 
channel_info> &chan_info, pmt_t data);
+  void handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struct 
channel_info> &chan_info, pmt_t data);
+  void handle_cmd_start_recv_raw_samples(mb_port_sptr port, std::vector<struct 
channel_info> &chan_info, pmt_t data);
+  void handle_cmd_stop_recv_raw_samples(mb_port_sptr port, std::vector<struct 
channel_info> &chan_info, pmt_t data);
   int rx_port_index(pmt_t port_id);
   int tx_port_index(pmt_t port_id);
   long current_capacity_allocation();
   void recall_defer_queue();
   void reset_channels();
+  void handle_response_usrp_read(pmt_t data);
+  bool check_valid(mb_port_sptr port, long channel, std::vector<struct 
channel_info> &chan_info, pmt_t signal_info);
 };
 
 #endif /* INCLUDED_USRP_SERVER_H */

Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.cc 
(from rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_tx.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.cc       
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.cc       
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,111 @@
+/* -*- 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 2, 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 <usrp_tx.h>
+#include <iostream>
+#include <usb.h>
+#include <mb_class_registry.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include <usrp_standard.h>
+#include <stdio.h>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static const bool verbose = false;
+
+static pmt_t s_cmd_usrp_tx_write = pmt_intern("cmd-usrp-tx-write");
+static pmt_t s_response_usrp_tx_write = pmt_intern("response-usrp-tx-write");
+
+usrp_tx::usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg)
+  : mb_mblock(rt, instance_name, user_arg)
+{
+  d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL);
+  
+}
+
+usrp_tx::~usrp_tx() 
+{
+}
+
+void 
+usrp_tx::initial_transition()
+{
+  
+}
+
+void
+usrp_tx::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t port_id = msg->port_id();
+  pmt_t data = msg->data(); 
+
+  // 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_eqv(event, s_cmd_usrp_tx_write))
+      write(data);
+  }
+}
+
+void
+usrp_tx::write(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t channel = pmt_nth(1, data);
+  pmt_t v_packets = pmt_nth(2, data);
+  d_utx = boost::any_cast<usrp_standard_tx *>(pmt_any_ref(pmt_nth(3, data)));
+
+  size_t n_bytes;
+  bool underrun;  // this will need to go, as it is taken care of in the 
packet headers
+
+  transport_pkt *pkts = (transport_pkt *) 
pmt_u8vector_writeable_elements(v_packets, n_bytes);
+
+  int ret = d_utx->write (pkts, n_bytes, &underrun);
+  
+  if (0 && underrun)
+    fprintf(stderr, "uU");
+
+  if (ret == (int) n_bytes) {
+    if (verbose)
+      std::cout << "[usrp_server] Write of " << n_bytes << " successful\n";
+    // need to respond with the channel so the USRP server knows who to 
forward the result of
+    // the write to by looking up the owner of the channel
+    d_cs->send(s_response_usrp_tx_write,
+              pmt_list3(invocation_handle, PMT_T, channel));
+  }
+  else {
+    if (verbose)
+      std::cout << "[usrp_server] Error writing " << n_bytes << " bytes to USB 
bus\n";
+    d_cs->send(s_response_usrp_tx_write,
+              pmt_list3(invocation_handle, PMT_F, channel));
+  }
+
+  return;
+}
+
+REGISTER_MBLOCK_CLASS(usrp_tx);

Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.h 
(from rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_tx.h)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.h        
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx.h        
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,48 @@
+/* -*- 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 2, 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_USRP_TX_H
+#define INCLUDED_USRP_TX_H
+
+#include <mb_mblock.h>
+
+class usrp_standard_tx;
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_tx : public mb_mblock
+{
+  mb_port_sptr         d_cs;
+  usrp_standard_tx     *d_utx;
+  
+ public:
+  usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg);
+  ~usrp_tx();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void write(pmt_t data);
+};
+  
+
+#endif /* INCLUDED_USRP_TX_H */
+

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx_stub.cc 
(from rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_tx_stub.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx_stub.cc  
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx_stub.cc  
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,109 @@
+/* -*- 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 2, 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 <iostream>
+#include <vector>
+#include <usb.h>
+#include <mb_class_registry.h>
+#include <usrp_tx_stub.h>
+#include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include "usrp_standard.h"
+#include <stdio.h>
+#include <fstream>
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static const bool verbose = false;
+
+static pmt_t s_cmd_usrp_tx_write = pmt_intern("cmd-usrp-tx-write");
+static pmt_t s_response_usrp_tx_write = pmt_intern("response-usrp-tx-write");
+
+usrp_tx_stub::usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, 
pmt_t user_arg)
+  : mb_mblock(rt, instance_name, user_arg),
+    d_disk_write(false)
+{
+  d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL);
+  
+  //d_disk_write=true;
+  
+  if(d_disk_write)
+    d_ofile.open("pdump.dat",std::ios::binary|std::ios::out);
+}
+
+usrp_tx_stub::~usrp_tx_stub() 
+{
+  if(d_disk_write)
+    d_ofile.close();
+}
+
+void 
+usrp_tx_stub::initial_transition()
+{
+  
+}
+
+void
+usrp_tx_stub::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();
+  pmt_t port_id = msg->port_id();
+  pmt_t data = msg->data(); 
+
+  // 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_eqv(event, s_cmd_usrp_tx_write)) 
+      write(data);
+  }
+}
+
+void
+usrp_tx_stub::write(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t channel = pmt_nth(1, data);
+  pmt_t v_packets = pmt_nth(2, data);
+  d_utx = boost::any_cast<usrp_standard_tx *>(pmt_any_ref(pmt_nth(3, data)));
+
+  size_t n_bytes;
+
+  if(d_disk_write) {
+    transport_pkt *pkts = (transport_pkt *) 
pmt_u8vector_writeable_elements(v_packets, n_bytes);
+    long n_packets = static_cast<long>(std::ceil(n_bytes / 
(double)transport_pkt::max_pkt_size()));
+    
+    for(long i=0; i<n_packets; i++)  
+      d_ofile.write((const char*) pkts[i].payload(), pkts[i].payload_len());
+    
+  }
+
+  d_cs->send(s_response_usrp_tx_write,
+       pmt_list3(invocation_handle, PMT_T, channel));
+
+  return;
+}
+
+REGISTER_MBLOCK_CLASS(usrp_tx_stub);

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx_stub.h (from 
rev 5752, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_tx_stub.h)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx_stub.h   
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_tx_stub.h   
2007-06-09 03:17:57 UTC (rev 5753)
@@ -0,0 +1,56 @@
+/* -*- 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 2, 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_USRP_TX_STUB_H
+#define INCLUDED_USRP_TX_STUB_H
+
+#include <mb_mblock.h>
+#include <vector>
+#include "usrp_standard.h"
+#include <fstream>
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_tx_stub : public mb_mblock
+{
+ public:
+
+  mb_port_sptr d_cs;
+  usrp_standard_tx* d_utx;
+  
+  std::ofstream d_ofile;
+
+  bool d_disk_write;
+
+ public:
+  usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg);
+  ~usrp_tx_stub();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void write(pmt_t data);
+ 
+};
+  
+
+#endif /* INCLUDED_USRP_TX_STUB_H */
+

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
    2007-06-09 02:55:25 UTC (rev 5752)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
    2007-06-09 03:17:57 UTC (rev 5753)
@@ -22,12 +22,18 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
+#include <usrp_usb_interface.h>
+
 #include <iostream>
 #include <vector>
 #include <usb.h>
 #include <mb_class_registry.h>
-#include <usrp_usb_interface.h>
 #include <usrp_inband_usb_packet.h>
+#include <fpga_regs_common.h>
+#include "usrp_rx.h"
+#include <usrp_rx_stub.h>
+#include "usrp_tx.h"
 #include "usrp_standard.h"
 #include <stdio.h>
 
@@ -38,19 +44,68 @@
 static pmt_t s_cmd_usrp_write = pmt_intern("cmd-usrp-write");
 static pmt_t s_cmd_usrp_ntx_chan = pmt_intern("cmd-usrp-ntx-chan");
 static pmt_t s_cmd_usrp_nrx_chan = pmt_intern("cmd-usrp-nrx-chan");
+static pmt_t s_cmd_usrp_start_reading = pmt_intern("cmd-usrp-start-reading");
+static pmt_t s_cmd_usrp_stop_reading = pmt_intern("cmd-usrp-stop-reading");
 static pmt_t s_response_usrp_ntx_chan = pmt_intern("response-usrp-ntx-chan");
 static pmt_t s_response_usrp_nrx_chan = pmt_intern("response-usrp-nrx-chan");
 static pmt_t s_response_usrp_open = pmt_intern("response-usrp-open");
 static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close");
 static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write");
+static pmt_t s_response_usrp_read = pmt_intern("response-usrp-read");
 
-static const bool verbose = true;
+// TX and RX signals
+static pmt_t s_cmd_usrp_rx_start_reading = 
pmt_intern("cmd-usrp-rx-start-reading");
+static pmt_t s_response_usrp_rx_read = pmt_intern("response-usrp-rx-read");
+static pmt_t s_cmd_usrp_tx_write = pmt_intern("cmd-usrp-tx-write");
+static pmt_t s_response_usrp_tx_write = pmt_intern("response-usrp-tx-write");
 
+static const bool verbose = false;
+
 // need to take number of TX and RX channels as parameter
 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)
+  : mb_mblock(rt, instance_name, user_arg),
+  d_fpga_debug(false),
+  d_fake_usrp(false)
 {
+  // Dictionary for arguments to all of the components
+  pmt_t usrp_dict = user_arg;
+  
+  // Default TX/RX interface
+  std::string tx_interface = "usrp_tx";
+  std::string rx_interface = "usrp_rx";
+  
+  if (pmt_is_dict(usrp_dict)) {
+
+    // The 'fake-usrp' key enables the TX and RX stubs if PMT_T
+    if(pmt_t fake_usrp = pmt_dict_ref(usrp_dict, 
+                                      pmt_intern("fake-usrp"), 
+                                      PMT_NIL)) {
+      if(pmt_eqv(fake_usrp, PMT_T)) {
+        tx_interface = "usrp_tx_stub";
+        rx_interface = "usrp_rx_stub";
+        d_fake_usrp=true;
+      }
+    }
+
+  }
+  
+  if (verbose) {
+    std::cout << "[USRP_USB_INTERFACE] Using TX interface: " 
+              << tx_interface << "\n";
+
+    std::cout << "[USRP_USB_INTERFACE] Using RX interface: " 
+              << rx_interface << "\n";
+  }
+
   d_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL);      
+  d_rx_cs = define_port("rx_cs", "usrp-rx-cs", false, mb_port::INTERNAL);      
+  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);
+  connect("self", "rx_cs", "rx", "cs");
+  connect("self", "tx_cs", "tx", "cs");
   
   // FIX ME: the code should query the FPGA to retrieve the number of channels 
and such
   d_ntx_chan = 2;
@@ -58,6 +113,9 @@
 
   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() 
@@ -79,34 +137,86 @@
   pmt_t data = msg->data();
   pmt_t invocation_handle;
 
-  // message came in on our control/status port
+  //------------- CONTROL / STATUS -------------//
   if (pmt_eq(port_id, d_cs->port_symbol())) {  
 
+    //------------ OPEN --------------//
     if (pmt_eq(event, s_cmd_usrp_open)){
       handle_cmd_open(data);
       return;
     }
+    //----------- CLOSE -------------//
     else if (pmt_eq(event, s_cmd_usrp_close)) {
       handle_cmd_close(data);
       return;
     }
+    //---------- NTX CHAN ----------//
     else if (pmt_eq(event, s_cmd_usrp_ntx_chan)) {
       invocation_handle = pmt_nth(0, data);
-      d_cs->send(s_response_usrp_ntx_chan, pmt_list2(invocation_handle, 
pmt_from_long(d_ntx_chan)));
+      d_cs->send(s_response_usrp_ntx_chan, 
+                 pmt_list2(invocation_handle, 
+                           pmt_from_long(d_ntx_chan)));
       return;
     }
+    //---------- NRX CHAN ----------//
     else if (pmt_eq(event, s_cmd_usrp_nrx_chan)) {
       invocation_handle = pmt_nth(0, data);
-      d_cs->send(s_response_usrp_nrx_chan, pmt_list2(invocation_handle, 
pmt_from_long(d_nrx_chan)));
+      d_cs->send(s_response_usrp_nrx_chan, 
+                 pmt_list2(invocation_handle, 
+                           pmt_from_long(d_nrx_chan)));
       return;
     }
+    //------------ WRITE -----------//
     else if(pmt_eq(event, s_cmd_usrp_write)) {
       handle_cmd_write(data);
       return;
     }
+    //-------- START READING --------//
+    else if(pmt_eq(event, s_cmd_usrp_start_reading)) {
+      handle_cmd_start_reading(data);
+      return;
+    }
+    //-------- STOP READING --------//
+    else if(pmt_eq(event, s_cmd_usrp_stop_reading)) {
+      handle_cmd_stop_reading(data);
+      return;
+    }
+
     goto unhandled;
   }
 
+  //---------------- RX ------------------//
+  if (pmt_eq(port_id, d_rx_cs->port_symbol())) {       
+
+    // Relay reads back up
+    if(pmt_eq(event, s_response_usrp_rx_read))  {
+      d_cs->send(s_response_usrp_read, data);
+      return;
+    }
+
+    goto unhandled;
+  }
+  
+  //---------------- TX ------------------//
+  if (pmt_eq(port_id, d_tx_cs->port_symbol())) {       
+
+    if(pmt_eq(event, s_response_usrp_tx_write))  {
+
+      pmt_t invocation_handle = pmt_nth(0, data);
+      pmt_t status = pmt_nth(1, data);
+      pmt_t channel = pmt_nth(2, data);
+
+      d_cs->send(s_response_usrp_write,
+                 pmt_list3(invocation_handle,
+                           status,
+                           channel));
+
+      return;
+    }
+
+    goto unhandled;
+  }
+
  unhandled:
   std::cout << "[usrp_usb_interface] unhandled msg: " << msg << std::endl;
 }
@@ -117,14 +227,19 @@
   pmt_t invocation_handle = pmt_nth(0, data);
   long which_usrp = pmt_to_long(pmt_nth(1, data));
   pmt_t reply_data;
+ 
+  if(d_fake_usrp) {
+    d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
+    return;
+  }
 
   if (verbose)
     std::cout << "[USRP_USB_INTERFACE] Handling open request for USRP " << 
which_usrp << "\n";
 
   // Open up a standard RX and TX for communication with the USRP
    
-  std::string rbf = "usrp_inband_usb.rbf";
-  //std::string rbf = "";
+  //std::string rbf = "usrp_inband_usb.rbf";
+  std::string rbf = "";
 
   d_utx = usrp_standard_tx::make(which_usrp,
                                 32,            // 128/32 -> 4MS/s
@@ -181,7 +296,18 @@
     return;
   }
 
-  d_urx->start();
+  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);
+//    }
+  }
   
   if (verbose)
     std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n";
@@ -193,33 +319,52 @@
 usrp_usb_interface::handle_cmd_write(pmt_t data)
 {
   pmt_t invocation_handle = pmt_nth(0, data);
-  long channel = pmt_to_long(pmt_nth(1, data));
-  pmt_t v_packets = pmt_nth(2, data);
+  pmt_t channel = pmt_nth(1, data);
+  pmt_t pkts = pmt_nth(2, data);
+
+  pmt_t tx_handle = pmt_make_any(d_utx);
+
+  d_tx_cs->send(s_cmd_usrp_tx_write, 
+                pmt_list4(invocation_handle, 
+                          channel,
+                          pkts,
+                          tx_handle));
+
+  return;
+}
+
+void
+usrp_usb_interface::handle_cmd_start_reading(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
   
-  size_t n_bytes;
-  bool underrun;  // this will need to go, as it is taken care of in the 
packet headers
-  
-  transport_pkt *pkts = (transport_pkt *) 
pmt_u8vector_writeable_elements(v_packets, n_bytes);
+  if(verbose)
+    std::cout << "[usrp_usb_interface] Starting RX...\n";
 
-  int ret = d_utx->write (pkts, n_bytes, &underrun);
+  if(!d_fake_usrp)
+    d_urx->start();
 
-  if (0 && underrun)
-    fprintf(stderr, "uU");
+  pmt_t rx_handle = pmt_make_any(d_urx);
 
-  if (ret == (int) n_bytes) {
-    if (verbose)
-      std::cout << "[usrp_server] Write of " << n_bytes << " successful\n";
-    // need to respond with the channel so the USRP server knows who to 
forward the result of
-    // the write to by looking up the owner of the channel
-    d_cs->send(s_response_usrp_write,
-              pmt_list3(invocation_handle, pmt_from_long(channel), PMT_T));
+  d_rx_cs->send(s_cmd_usrp_rx_start_reading, pmt_list2(PMT_NIL, rx_handle));
+
+  return;
+}
+
+void
+usrp_usb_interface::handle_cmd_stop_reading(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  
+  if(!d_fake_usrp) {
+    if(verbose)
+      std::cout << "[usrp_usb_interface] Stopping RX...\n";
+    d_urx->stop();
   }
   else {
-    if (verbose)
-      std::cout << "[usrp_server] Error writing " << n_bytes << " bytes to USB 
bus\n";
-    // need to respond with the channel so the USRP server knows who to 
forward the result of
-    // the write to by looking up the owner of the channel
-    d_cs->send(s_response_usrp_write, pmt_list3(invocation_handle, 
pmt_from_long(channel), PMT_F));
+    if(verbose)
+      std::cout << "[usrp_usb_interface] Stopping fake RX...\n";
+    usrp_rx_stop = true;  // extern to communicate with stub to wait
   }
 
   return;
@@ -229,6 +374,11 @@
 usrp_usb_interface::handle_cmd_close(pmt_t data)
 {
   pmt_t invocation_handle = pmt_nth(0, data);
+
+  if(d_fake_usrp) {
+    d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
+    return;
+  }
   
   if (verbose)
     std::cout << "[usrp_usb_interface] Handling close request for USRP\n";

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h 
    2007-06-09 02:55:25 UTC (rev 5752)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h 
    2007-06-09 03:17:57 UTC (rev 5753)
@@ -36,10 +36,16 @@
   usrp_standard_rx* d_urx;
   
   mb_port_sptr d_cs;
+  mb_port_sptr  d_rx_cs;
+  mb_port_sptr  d_tx_cs;
   
   long d_ntx_chan;
   long d_nrx_chan;
 
+  long d_fpga_debug;
+
+  bool d_fake_usrp;
+
  public:
   usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg);
   ~usrp_usb_interface();
@@ -50,6 +56,8 @@
   void handle_cmd_open(pmt_t data);
   void handle_cmd_close(pmt_t data);
   void handle_cmd_write(pmt_t data);
+  void handle_cmd_start_reading(pmt_t data);
+  void handle_cmd_stop_reading(pmt_t data);
  
 };
   

Deleted: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc

Deleted: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h





reply via email to

[Prev in Thread] Current Thread [Next in Thread]