commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r5612 - gnuradio/branches/features/inband-usb/usrp/hos


From: gnychis
Subject: [Commit-gnuradio] r5612 - gnuradio/branches/features/inband-usb/usrp/host/lib/inband
Date: Sat, 2 Jun 2007 17:41:17 -0600 (MDT)

Author: gnychis
Date: 2007-06-02 17:41:17 -0600 (Sat, 02 Jun 2007)
New Revision: 5612

Added:
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.h
   
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/test_usrp_inband.cc
   gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh
   
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
   
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/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_inband_usb_packet.h
   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_server.mbh
Log:
Merging from -r5227:5611 branches/developers/gnychis/inband


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-02 22:43:26 UTC (rev 5611)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/Makefile.am      
2007-06-02 23:41:17 UTC (rev 5612)
@@ -27,41 +27,52 @@
 TESTS = test_inband
 
 EXTRA_DIST =                           \
-       usrp_server.mbh                 
+       usrp_server.mbh         \
+       usrp_interface.mbh 
 
+
 lib_LTLIBRARIES =                      \
-       libusrp_inband.la               \
-       libusrp_inband-qa.la                    
+       libusrp_inband.la                       \
+       libusrp_inband-qa.la
 
 
 # ------------------------------------------------------------------------
 # 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
        $(COMPILE_MBH) usrp_server.mbh usrp_server_mbh.cc
 
+usrp_interface_mbh.cc : usrp_interface.mbh
+       $(COMPILE_MBH) usrp_interface.mbh usrp_interface_mbh.cc
+
 libusrp_inband_la_SOURCES =            \
        $(BUILT_SOURCES)                \
-       usrp_server.cc
+       usrp_server.cc                  \
+       usrp_usb_interface.cc   \
+       usrp_usb_interface_stub.cc
 
 libusrp_inband_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
 
 libusrp_inband_la_LIBADD =             \
        $(MBLOCK_LA)                    \
+       $(USRP_LA)                              \
        -lstdc++
 
-
 include_HEADERS =                      \
-       usrp_server.h                   
+       usrp_server.h                           \
+       usrp_usb_interface.h \
+       usrp_inband_usb_packet.h \      
+       usrp_usb_interface_stub.h
 
 noinst_HEADERS =                       \
        qa_inband.h                     \
        qa_inband_packet_prims.h        \
        qa_inband_usrp_server.h         \
-       usrp_inband_usb_packet.h        
+       fake_usrp.h                                                             
 
 
 # ------------------------------------------------------------------------
@@ -70,7 +81,8 @@
 libusrp_inband_qa_la_SOURCES =         \
        qa_inband.cc                    \
        qa_inband_packet_prims.cc       \
-       qa_inband_usrp_server.cc        
+       qa_inband_usrp_server.cc        \
+       fake_usrp.cc
 
 # magic flags
 libusrp_inband_qa_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version
@@ -79,17 +91,21 @@
 libusrp_inband_qa_la_LIBADD =          \
        libusrp_inband.la               \
        $(CPPUNIT_LIBS)                 \
+       $(USRP_LA)                                      \
        -lstdc++
 
 # ------------------------------------------------------------------------
 
 noinst_PROGRAMS =                      \
-       test_inband
+       test_inband                                     \
+       test_usrp_inband
 
 test_inband_SOURCES = test_inband.cc
 test_inband_LDADD   = libusrp_inband-qa.la
 
+test_usrp_inband_SOURCES = test_usrp_inband.cc
+test_usrp_inband_LDADD = libusrp_inband-qa.la
 
+
 MOSTLYCLEANFILES = \
        $(BUILT_SOURCES) *~ *.pyc
-

Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc 
(from rev 5611, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/fake_usrp.cc)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc     
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.cc     
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,135 @@
+/* -*- 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 <fake_usrp.h>
+#include <iostream>
+#include <usrp_inband_usb_packet.h>
+#include <mb_class_registry.h>
+#include <vector>
+
+typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit 
easy
+
+fake_usrp::fake_usrp()
+{
+  std::cout << "[fake_usrp] Initializing...\n";
+}
+
+fake_usrp::~fake_usrp() {}
+
+long
+fake_usrp::write_bus(transport_pkt *pkts, long n_bytes)
+{
+  std::cout << "[fake_usrp] Bytes over bus: " << n_bytes << "\n";
+
+  // I'm assuming that a control packet cannot exist in a burst of data 
packets,
+  // therefore i read only the first packet's channel in the current burst
+  if(pkts[0].chan() == 0x1f) {
+    return control_block(pkts, n_bytes);
+  } else {
+    return data_block(pkts, n_bytes);
+  }
+
+}
+
+long
+fake_usrp::data_block(transport_pkt *pkts, long n_bytes)
+{
+  std::cout << "[fake_usrp] Entering data block\n";
+
+  // Infer the number of packets from the byte count to do logical tests
+  long n_pkts = static_cast<long>(std::ceil(n_bytes / 
(double)transport_pkt::max_pkt_size()));
+  
+  std::cout << "[fake_usrp] Number of packets: " << n_pkts << "\n";
+
+  // The first packet should have the start of burst, and the last packet 
should have end of burst
+  if(pkts[0].start_of_burst() && pkts[n_pkts-1].end_of_burst()) {
+    std::cout << "[fake_usrp] Correct burst flags set\n";
+  } else {
+    std::cout << "[fake_usrp] Incorrect burst flags set!\n";
+    return 0;
+  }
+
+  // All other flags should be set to 0 (e.g., overrun should not be set yet) 
on ALL packets
+  for(int i=0; i < n_pkts; i++) {
+    if(pkts[i].overrun()) {
+      std::cout << "[fake_usrp] Incorrect set of overrun flag on transmit\n";
+      return 0;
+    } else if(pkts[i].underrun()) {
+      std::cout << "[fake_usrp] Incorrect set of underrun flag on transmit\n";
+      return 0;
+    } else if(pkts[i].dropped()) {
+      std::cout << "[fake_usrp] Incorrect set of drop flag on transmit\n";
+      return 0;
+    } 
+  }
+  std::cout << "[fake_usrp] Correct overrun, underrun, and drop flags on 
transmit (initialized to 0)\n";
+  
+  // The first packet should have a timestamp, other packets should have "NOW"
+  if(pkts[0].timestamp() != 0xffffffff) {
+    std::cout << "[fake_usrp] Correct timestamp on first packet\n";
+  } else {
+    std::cout << "[fake_usrp] Initial packet should not have the 0xffffffff 
timestamp\n";
+    return 0;
+  }
+
+  // Check that all of the other packets include the NOW timestamp
+  int check_stamps=1;
+  for(int i=1; i < n_pkts; i++)           // start at 1 to skip the first 
packet
+    if(pkts[i].timestamp() != 0xffffffff) 
+      check_stamps=0;
+
+  if(check_stamps) {
+    std::cout << "[fake_usrp] Correct NOW timestamps (0xffffffff) on 
intermediate burst packets\n";
+  } else {
+    std::cout << "[fake_usrp] Incorrect timestamps on intermediate burst 
packets\n";
+    return 0;
+  }
+
+  // Since we are being transparent about samples, we do not ensure the 
payload is correct, however
+  // it should be the case that if there are >1 packets, all packets except 
the last packet should
+  // have a full payload size
+  if(n_pkts > 1) {
+    int check_size=1;
+    for(int i=0; i < n_pkts-1; i++)
+      if(pkts[i].payload_len() != transport_pkt::max_payload())
+        check_size=0;
+
+    if(check_size) {
+      std::cout << "[fake_usrp] Correct payload size sanity check on 
packets\n";
+    } else {
+      std::cout << "[fake_usrp] Failed payload size sanity check\n";
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+long
+fake_usrp::control_block(transport_pkt *pkts, long n_bytes)
+{
+  std::cout << "[fake_usrp] Entering control block\n";
+
+  return 1;
+}

Copied: gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.h 
(from rev 5611, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/fake_usrp.h)
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.h      
                        (rev 0)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/fake_usrp.h      
2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,43 @@
+/* -*- 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_FAKE_USRP_H
+#define INCLUDED_FAKE_USRP_H
+
+#include <usrp_inband_usb_packet.h>
+typedef usrp_inband_usb_packet transport_pkt;
+
+/*!
+ * \brief Implements a fake USRP for testing without hardware
+ */
+class fake_usrp
+{
+ public:
+  fake_usrp();
+  ~fake_usrp();
+  long write_bus(transport_pkt *pkts, long n_bytes);
+
+ protected:
+  long data_block(transport_pkt *pkts, long n_bytes);
+  long control_block(transport_pkt *pkts, long n_bytes);
+};
+
+#endif /* INCLUDED_FAKE_USRP_H */
+

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-02 22:43:26 UTC (rev 5611)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.cc
 2007-06-02 23:41:17 UTC (rev 5612)
@@ -23,6 +23,7 @@
 #include <config.h>
 #endif
 
+#include <usrp_inband_usb_packet.h>
 #include <qa_inband_usrp_server.h>
 #include <cppunit/TestAssert.h>
 #include <stdio.h>
@@ -33,7 +34,14 @@
 #include <mb_class_registry.h>
 #include <vector>
 #include <iostream>
+#include <pmt.h>
 
+typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit 
easy
+
+static pmt_t s_cmd_open = pmt_intern("cmd-open");
+static pmt_t s_response_open = pmt_intern("response-open");
+static pmt_t s_cmd_close = pmt_intern("cmd-close");
+static pmt_t s_response_close = pmt_intern("response-close");
 static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
 static pmt_t s_response_allocate_channel = 
pmt_intern("response-allocate-channel");
 static pmt_t s_send_allocate_channel = pmt_intern("send-allocate-channel");
@@ -48,8 +56,9 @@
 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");
 
-
 // 
----------------------------------------------------------------------------------------------
 
 class qa_alloc_top : public mb_mblock
@@ -82,16 +91,20 @@
   : mb_mblock(runtime, instance_name, user_arg)
 { 
   d_nrecvd=0;
-  d_nmsgs_to_recv = 7;
+  d_nmsgs_to_recv = 6;
   d_nstatus=0;
-  d_nstatus_to_recv = 3;
+  d_nstatus_to_recv = 50;
   
   d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
   d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
   d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+ 
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), 
pmt_intern("usrp_usb_interface_stub"));
 
   // Test the TX side
-  define_component("server", "usrp_server", PMT_F);
+  define_component("server", "usrp_server", pmt_list1(usrp_server_dict));
   connect("self", "tx0", "server", "tx0");
   connect("self", "rx0", "server", "rx0");
   connect("self", "cs", "server", "cs");
@@ -103,10 +116,15 @@
 void
 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)));
+
   // Retrieve information about the USRP, then run tests
-  d_cs->send(s_cmd_max_capacity, pmt_list1(PMT_F));
-  d_cs->send(s_cmd_ntx_chan, pmt_list1(PMT_F));
-  d_cs->send(s_cmd_nrx_chan, pmt_list1(PMT_F));
+  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));
 }
 
 void
@@ -154,15 +172,15 @@
   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(1, data));
+      d_max_capacity = pmt_to_long(pmt_nth(2, data));
       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(1, data));
+      d_ntx_chan = pmt_to_long(pmt_nth(2, data));
       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(1, data));
+      d_nrx_chan = pmt_to_long(pmt_nth(2, data));
       std::cout << "[qa_alloc_top] USRP rx channels: " << d_nrx_chan << "\n";
     }
     else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) {
@@ -171,6 +189,8 @@
     
     d_nstatus++;
 
+    check_message(msg);
+
     if(d_nstatus==d_nstatus_to_recv)
       run_tests();
   }
@@ -244,14 +264,18 @@
   d_nalloc_recvd=0;
   d_nalloc_to_recv = 0;
   d_nstatus=0;
-  d_nstatus_to_recv = 3;
+  d_nstatus_to_recv = 4;
   
   d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
   d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
   d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
 
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), 
pmt_intern("usrp_usb_interface_stub"));
+
   // Test the TX side
-  define_component("server", "usrp_server", PMT_F);
+  define_component("server", "usrp_server", pmt_list1(usrp_server_dict));
   connect("self", "tx0", "server", "tx0");
   connect("self", "rx0", "server", "rx0");
   connect("self", "cs", "server", "cs");
@@ -263,9 +287,10 @@
 qa_dealloc_top::initial_transition()
 {
   // Retrieve information about the USRP, then run tests
-  d_cs->send(s_cmd_max_capacity, pmt_list1(PMT_F));
-  d_cs->send(s_cmd_ntx_chan, pmt_list1(PMT_F));
-  d_cs->send(s_cmd_nrx_chan, pmt_list1(PMT_F));
+  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));
 }
 
 void
@@ -316,7 +341,7 @@
 
 
   // 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_from_long(0)));
+  d_cs->send(s_cmd_current_capacity_allocation, pmt_list1(PMT_T));
 }
 
 void
@@ -338,15 +363,15 @@
   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(1, data));
+      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(1, data));
+      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(1, data));
+      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)) {
@@ -426,12 +451,335 @@
 
 // 
----------------------------------------------------------------------------------------------
 
+class qa_open_close_top : public mb_mblock
+{
+  mb_port_sptr d_cs;
+  
+  long d_max_capacity;
+
+  long d_nmsg_to_recv;
+  long d_nmsg_recvd;
+
+ public:
+  qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, 
pmt_t user_arg);
+  ~qa_open_close_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void check_cs(mb_message_sptr msg);
+  void run_tests();
+};
+
+qa_open_close_top::qa_open_close_top(mb_runtime *runtime, const std::string 
&instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+
+  d_nmsg_to_recv=7;
+  d_nmsg_recvd=0;
+  
+  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("usrp-interface"), 
pmt_intern("usrp_usb_interface_stub"));
+
+  // Test the TX side
+  define_component("server", "usrp_server", pmt_list1(usrp_server_dict));
+  connect("self", "cs", "server", "cs");
+}
+
+qa_open_close_top::~qa_open_close_top(){}
+
+void
+qa_open_close_top::initial_transition()
+{
+  run_tests();
+}
+
+void
+qa_open_close_top::run_tests()
+{
+  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));
+  
+  // 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)));
+
+  // A close should now be successful since the interface is open
+  d_cs->send(s_cmd_close, pmt_list1(PMT_T));
+
+  // But, a second close should fail
+  d_cs->send(s_cmd_close, pmt_list1(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));
+  
+}
+
+
+void
+qa_open_close_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+
+  if (pmt_eq(msg->port_id(), d_cs->port_symbol())) {
+      check_cs(msg);
+  }
+
+  d_nmsg_recvd++;
+
+  if(d_nmsg_to_recv == d_nmsg_recvd)
+    shutdown_all(PMT_T);
+}
+
+void
+qa_open_close_top::check_cs(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_open_close_top] FAILED check_cs... Got: " << result << " 
Expected: " << expected_result << " for event " << msg->signal() << "\n";
+    shutdown_all(PMT_F);
+  } else {
+    std::cout << "[qa_open_close_top] Received expected CS response for 
message (" << msg->signal() << ")\n";
+  }
+
+}
+
+REGISTER_MBLOCK_CLASS(qa_open_close_top);
+
+// 
----------------------------------------------------------------------------------------------
+
+class qa_tx_top : public mb_mblock
+{
+  mb_port_sptr d_tx;
+  mb_port_sptr d_rx;
+  mb_port_sptr d_cs;
+  
+  long d_max_capacity;
+  long d_ntx_chan, d_nrx_chan;
+
+  long d_tx_chan;
+  long d_rx_chan;
+
+  long d_nmsg_to_recv;
+  long d_nmsg_recvd;
+
+ public:
+  qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t 
user_arg);
+  ~qa_tx_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_tx_top::qa_tx_top(mb_runtime *runtime, const std::string &instance_name, 
pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+
+  d_nmsg_to_recv=12;
+  d_nmsg_recvd=0;
+  
+  d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL);
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+
+  // Use the stub with the usrp_server
+  pmt_t usrp_server_dict = pmt_make_dict();
+  pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), 
pmt_intern("usrp_usb_interface_stub"));
+
+  // Test the TX side
+  define_component("server", "usrp_server", pmt_list1(usrp_server_dict));
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "rx0", "server", "rx0");
+  connect("self", "cs", "server", "cs");
+}
+
+qa_tx_top::~qa_tx_top(){}
+
+void
+qa_tx_top::initial_transition()
+{
+  run_tests();
+}
+
+void
+qa_tx_top::run_tests()
+{
+  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)));
+  
+  // 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)));
+
+  // 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)));
+
+  // 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)));
+
+  // Close should be successful
+  d_cs->send(s_cmd_close, pmt_list1(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)));
+
+  // 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)));
+
+  // A final close which should be successful
+  d_cs->send(s_cmd_close, pmt_list1(PMT_T));
+  
+}
+
+
+void
+qa_tx_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t data = msg->data();
+
+  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)
+    shutdown_all(PMT_T);
+}
+
+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);
+  } 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 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);
+  } else {
+    std::cout << "[qa_tx_top] Received expected allocation response for 
message\n";
+  }
+  
+  if(pmt_eqv(result, 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);
+    if(pmt_eq(msg->port_id(), d_rx->port_symbol()))
+      d_rx_chan = pmt_to_long(channel);
+  }
+}
+
+void
+qa_tx_top::check_xmit(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_xmit... Got: " << result << " 
Expected: " << expected_result << " for event " << msg->signal() << ")\n";
+    shutdown_all(PMT_F);
+  } else {
+    std::cout << "[qa_tx_top] Received expected xmit response for message\n";
+  }
+}
+
+void
+qa_tx_top::check_cs(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_cs... Got: " << result << " 
Expected: " << expected_result << " for event " << msg->signal() << "\n";
+    shutdown_all(PMT_F);
+  } else {
+    std::cout << "[qa_tx_top] Received expected CS response for message (" << 
msg->signal() << ")\n";
+  }
+
+}
+
+REGISTER_MBLOCK_CLASS(qa_tx_top);
+
+
+// 
----------------------------------------------------------------------------------------------
+
 void 
+qa_inband_usrp_server::test_open_close()
+{
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  std::cout << "\n\n----------------------------\n";
+  std::cout << "    RUNNING OPEN/CLOSE TESTS  \n";
+
+  rt->run("top", "qa_open_close_top", PMT_F, &result);
+
+  CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
+}
+
+void 
 qa_inband_usrp_server::test_chan_allocation()
 {
   mb_runtime_sptr rt = mb_make_runtime();
   pmt_t result = PMT_T;
 
+  std::cout << "\n\n----------------------------\n";
+  std::cout << "    RUNNING ALLOCATION TESTS  \n";
+
   rt->run("top", "qa_alloc_top", PMT_F, &result);
   
   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
@@ -443,13 +791,24 @@
   mb_runtime_sptr rt = mb_make_runtime();
   pmt_t result = PMT_T;
 
+  std::cout << "\n\n----------------------------\n";
+  std::cout << "  RUNNING DEALLOCATION TESTS  \n";
+
   rt->run("top", "qa_dealloc_top", PMT_F, &result);
   
   CPPUNIT_ASSERT(pmt_equal(PMT_T, result));
 }
 
 void
-qa_inband_usrp_server::test_fragmentation()
+qa_inband_usrp_server::test_tx()
 {
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  std::cout << "\n\n-----------------\n";
+  std::cout << "  RUNNING TX TESTS  \n";
+
+  rt->run("top", "qa_tx_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-02 22:43:26 UTC (rev 5611)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/qa_inband_usrp_server.h
  2007-06-02 23:41:17 UTC (rev 5612)
@@ -28,15 +28,17 @@
 class qa_inband_usrp_server : public CppUnit::TestCase {
 
   CPPUNIT_TEST_SUITE(qa_inband_usrp_server);
+  CPPUNIT_TEST(test_open_close);
   CPPUNIT_TEST(test_chan_allocation);
   CPPUNIT_TEST(test_chan_deallocation);
-  CPPUNIT_TEST(test_fragmentation);
+  CPPUNIT_TEST(test_tx);
   CPPUNIT_TEST_SUITE_END();
 
  private:
   void test_chan_allocation();
   void test_chan_deallocation();
-  void test_fragmentation();
+  void test_open_close();
+  void test_tx();
 };
 
 #endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/test_usrp_inband.cc 
(from rev 5611, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/test_usrp_inband.cc)
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/test_usrp_inband.cc  
                            (rev 0)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/test_usrp_inband.cc  
    2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,297 @@
+/* -*- 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 <stdio.h>
+#include <iostream>
+#include <usrp_inband_usb_packet.h>
+#include <mb_mblock.h>
+#include <mb_runtime.h>
+#include <mb_protocol_class.h>
+#include <mb_class_registry.h>
+#include <pmt.h>
+#include "usrp_standard.h"
+
+typedef usrp_inband_usb_packet transport_pkt; 
+
+// Signal set for the USRP server
+static pmt_t s_cmd_open = pmt_intern("cmd-open");
+static pmt_t s_response_open = pmt_intern("response-open");
+static pmt_t s_cmd_close = pmt_intern("cmd-close");
+static pmt_t s_response_close = pmt_intern("response-close");
+static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel");
+static pmt_t s_response_allocate_channel = 
pmt_intern("response-allocate-channel");
+static pmt_t s_send_allocate_channel = pmt_intern("send-allocate-channel");
+static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel");
+static pmt_t s_response_deallocate_channel = 
pmt_intern("response-deallocate-channel");
+static pmt_t s_send_deallocate_channel = pmt_intern("send-deallocate-channel");
+static pmt_t s_cmd_max_capacity = pmt_intern("cmd-max-capacity");
+static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity");
+static pmt_t s_cmd_ntx_chan  = pmt_intern("cmd-ntx-chan");
+static pmt_t s_cmd_nrx_chan  = pmt_intern("cmd-nrx-chan");
+static pmt_t s_response_ntx_chan = pmt_intern("response-ntx-chan");
+static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan");
+static pmt_t s_cmd_current_capacity_allocation  = 
pmt_intern("cmd-current-capacity-allocation");
+static pmt_t s_response_current_capacity_allocation  = 
pmt_intern("response-current-capacity-allocation");
+static pmt_t s_cmd_xmit_raw_frame  = pmt_intern("cmd-xmit-raw-frame");
+static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame");
+
+bool loopback_p = false;
+bool counting_p = false;
+bool fake_usrp_p = false;
+char *prog_name;
+
+static void
+set_progname (char *path)
+{
+  char *p = strrchr (path, '/');
+  if (p != 0)
+    prog_name = p+1;
+  else
+    prog_name = path;
+}
+
+static void
+usage()
+{
+  fprintf (stderr, "usage: %s [-l]\n", prog_name);
+  fprintf (stderr, "  [-l] digital loopback in FPGA\n");
+  fprintf (stderr, "  [-c] counting in FPGA\n");
+  fprintf (stderr, "  [-f] fake usrp\n");
+
+  exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+  int ch;
+
+  set_progname(argv[0]);
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  pmt_t result = PMT_T;
+
+  while ((ch = getopt(argc, argv, "flc")) != EOF) {
+    switch(ch) {
+    
+      case 'l':
+        loopback_p = true;
+        break;
+
+      case 'c':
+        counting_p = true;
+        break;
+      
+      case 'f':
+        fake_usrp_p = true;
+        break;
+
+      default:
+        usage();
+    }
+  }
+
+
+  std::cout << "[test_usrp_inband] Starting...\n";
+
+  rt->run("top", "test_usrp_inband_top", PMT_F, &result);
+}
+
+class test_usrp_inband_top : public mb_mblock
+{
+  mb_port_sptr d_tx;
+  mb_port_sptr d_cs;
+
+  long d_tx_chan;
+
+ public:
+  test_usrp_inband_top(mb_runtime *runtime, const std::string &instance_name, 
pmt_t user_arg);
+  ~test_usrp_inband_top();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ protected:
+  void open_usrp();
+  void close_usrp();
+  void check_message(mb_message_sptr msg);
+  void allocate_channel();
+  void send_packets();
+};
+
+test_usrp_inband_top::test_usrp_inband_top(mb_runtime *runtime, const 
std::string &instance_name, pmt_t user_arg)
+  : mb_mblock(runtime, instance_name, user_arg)
+{ 
+  std::cout << "[TEST_USRP_INBAND_TOP] Initializing...\n";
+  
+  d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL);
+  d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL);
+  
+  // Test the TX side
+
+  // Pass a dictionary to usrp_server which specifies which interface to use, 
the stub or USRP
+  pmt_t usrp_server_dict = pmt_make_dict();
+
+  if(fake_usrp_p)
+    pmt_dict_set(usrp_server_dict, pmt_intern("usrp-interface"), 
pmt_intern("usrp_usb_interface_stub"));
+
+  define_component("server", "usrp_server", pmt_list1(usrp_server_dict));
+  connect("self", "tx0", "server", "tx0");
+  connect("self", "cs", "server", "cs");
+}
+
+test_usrp_inband_top::~test_usrp_inband_top()
+{
+}
+
+void
+test_usrp_inband_top::initial_transition()
+{
+  open_usrp();
+}
+
+void
+test_usrp_inband_top::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();         // the "name" of the message
+  pmt_t port_id = msg->port_id();      // which port it came in on
+  pmt_t data = msg->data();
+  pmt_t metadata = msg->metadata();
+  pmt_t status;
+
+  if (pmt_eq(port_id, d_cs->port_symbol())) {  // message came in on our 
control/status port
+
+    //---------- OPEN RESPONSE ----------//
+    if (pmt_eq(event, s_response_open)) {
+      status = pmt_nth(1, data);
+
+      if(pmt_eq(status, PMT_T)) {
+        std::cout << "[TEST_USRP_INBAND_TOP] Success opening USRP\n";
+      }
+      else {
+        std::cout << "[TEST_USRP_INBAND_TOP] Received error message opening 
USRP\n";
+        shutdown_all(PMT_F);
+      }
+
+      allocate_channel();
+
+      return;
+    }
+    //--------- CLOSE RESPONSE -----------//
+    else if (pmt_eq(event, s_response_close)) {
+      status = pmt_nth(1, data);
+      
+      if(pmt_eq(status, PMT_T)) {
+        std::cout << "[TEST_USRP_INBAND_TOP] Successfully closed USRP\n";
+      }
+      else {
+        std::cout << "[TEST_USRP_INBAND_TOP] Received error message closing 
USRP\n";
+        shutdown_all(PMT_F);
+      }
+
+      shutdown_all(PMT_T);
+
+      return;
+    }
+  }
+    
+  if (pmt_eq(port_id, d_tx->port_symbol())) {
+
+    //---------- ALLOCATE RESPONSE ---------//
+    if(pmt_eq(event, s_response_allocate_channel)) {
+      status = pmt_nth(1, data);
+      pmt_t channel = pmt_nth(2, data);
+
+      if(pmt_eq(status, PMT_T)) {
+        d_tx_chan = pmt_to_long(channel);
+        std::cout << "[TEST_USRP_INBAND_TOP] Received allocation on channel " 
<< d_tx_chan << "\n";
+      }
+      else {
+        std::cout << "[TEST_USRP_INBAND_TOP] Error allocating channel\n";
+        shutdown_all(PMT_F);
+      }
+      
+      send_packets();
+
+      return;
+    }
+    //----------- XMIT RESPONSE ------------//
+    else if(pmt_eq(event, s_response_xmit_raw_frame)) {
+      status = pmt_nth(1, data);
+
+      if(pmt_eq(status, PMT_T)) {
+        std::cout << "[TEST_USRP_INBAND_TOP] Transmission successful\n";
+      }
+      else {
+        std::cout << "[TEST_USRP_INBAND_TOP] Failed transmission\n";
+        shutdown_all(PMT_F);
+      }
+
+      close_usrp();
+
+      return;
+    }
+  }
+
+  std::cout << "[TEST_USRP_INBAND_TOP] Received unhandled message: " << event 
<< "\n";
+}
+
+void
+test_usrp_inband_top::allocate_channel()
+{
+  std::cout << "[TEST_USRP_INBAND_TOP] Requesting channel allocation...\n";
+  
+  d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1)));
+}
+
+void
+test_usrp_inband_top::send_packets()
+{
+  std::cout << "[TEST_USRP_INBAND_TOP] Sending single packet..\n";
+  d_tx->send(s_cmd_xmit_raw_frame, pmt_list4(pmt_from_long(1), 
pmt_from_long(d_tx_chan), pmt_make_u32vector(transport_pkt::max_payload()/4, 
0), pmt_from_long(0)));
+  
+}
+
+void
+test_usrp_inband_top::open_usrp()
+{
+  pmt_t usrp = pmt_from_long(0);
+
+  long rx_mode = 0;
+
+  if(loopback_p)
+    rx_mode |= usrp_standard_rx::FPGA_MODE_LOOPBACK;
+  if(counting_p)
+    rx_mode |= usrp_standard_rx::FPGA_MODE_COUNTING;
+
+  d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, usrp));
+}
+
+void
+test_usrp_inband_top::close_usrp()
+{
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+}
+
+REGISTER_MBLOCK_CLASS(test_usrp_inband_top);

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.h
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.h
 2007-06-02 22:43:26 UTC (rev 5611)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_inband_usb_packet.h
 2007-06-02 23:41:17 UTC (rev 5612)
@@ -144,6 +144,10 @@
     return MAX_PAYLOAD;
   }
 
+  static int max_pkt_size() {
+    return USB_PKT_SIZE;
+  }
+
 };
 
 #endif

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh 
(from rev 5611, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_interface.mbh)
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh   
                            (rev 0)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_interface.mbh   
    2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,51 @@
+;; -*- scheme -*- ; not really, but tells emacs how to format this
+;;
+;; 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.
+;;
+
+;; ----------------------------------------------------------------
+;;              This is an mblock header file
+;;
+;; The format is very much a work-in-progress.
+;; It'll be compiled to C++.
+;; ----------------------------------------------------------------
+
+;; ----------------------------------------------------------------
+;; tx-channels
+;;
+;; Handles a query for the number of tx-channels
+
+(define-protocol-class usrp-interface-cs
+
+  (:outgoing
+   (cmd-usrp-open invocation-handle which-usrp)
+   (cmd-usrp-close invocation-handle)
+   (cmd-usrp-ntx-chan invocation-handle)
+   (cmd-usrp-nrx-chan invocation-handle)
+   (cmd-usrp-write invocation-handle channel data n-bytes)
+   )
+
+  (:incoming
+   (response-usrp-open invocation-handle status)
+   (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)
+   )
+  )

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-02 22:43:26 UTC (rev 5611)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.cc   
2007-06-02 23:41:17 UTC (rev 5612)
@@ -27,6 +27,8 @@
 #include <usrp_inband_usb_packet.h>
 #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
 
@@ -61,6 +63,18 @@
 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");
 
+// USRP signal set
+static pmt_t s_cmd_usrp_open = pmt_intern("cmd-usrp-open");
+static pmt_t s_cmd_usrp_close = pmt_intern("cmd-usrp-close");
+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_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 std::string
 str(long x)
 {
@@ -72,10 +86,25 @@
 usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, 
pmt_t user_arg)
   : mb_mblock(rt, instance_name, user_arg)
 {
-  // define our ports
 
+  // Default USRP interface
+  std::string usrp_interface = "usrp_usb_interface";
+
+  // a dictionary is given for usrp server parameters, such as the interface 
to use
+  pmt_t usrp_dict = pmt_nth(0, user_arg);
+  
+  if(!pmt_eqv(usrp_dict, PMT_NIL)) {
+
+    if(pmt_dict_has_key(usrp_dict, pmt_intern("usrp-interface"))) 
+      usrp_interface = pmt_write_string(pmt_dict_ref(usrp_dict, 
pmt_intern("usrp-interface"), PMT_NIL));
+
+  }
+      
+  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);   
 
   // ports
   //
@@ -86,12 +115,25 @@
     d_rx.push_back(define_port("rx"+str(port), "usrp-rx", true, 
mb_port::EXTERNAL));
   }
 
-  // FIXME ... initializing to 2 channels on each for now, eventually we should
-  // query the FPGA to get these values
+  define_component("usrp", usrp_interface, PMT_F);
+  connect("self", "cs_usrp", "usrp", "cs");
+
+  d_defer=false;
+  d_opened=false;
+
+  // FIXME: needs to be returned from open, if we want to use this
+  d_nrx_chan = 2;
   d_ntx_chan = 2;
-  d_nrx_chan = 2;
 
   // Initialize capacity on each channel to 0 and to no owner
+  // Also initialize the USRP standard tx/rx pointers to NULL
+  reset_channels();
+  
+}
+
+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;
@@ -131,64 +173,184 @@
 
   // 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.
+  if (pmt_eq(port_id, d_cs_usrp->port_symbol())) { 
 
-  if (pmt_eq(port_id, d_cs->port_symbol())){   // message came in on our 
control/status port
+    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));
 
-    if (pmt_eq(event, s_cmd_open)){
-      // extract args from data
+      if(pmt_eqv(status,PMT_T)) {
+        d_opened = true;
+        d_defer = false;
+        recall_defer_queue();
+      }
+
+      return;
+    }
+    else if (pmt_eq(event, s_response_usrp_close)) {
       invocation_handle = pmt_nth(0, data);
-      long which_usrp = pmt_to_long(pmt_nth(1, data)); // integer usrp id, 
usually 0
+      pmt_t status = pmt_nth(1, data);
+      d_cs->send(s_response_close, pmt_list2(invocation_handle, status));
       
-      // Do the right thing....
-      // build a reply
+      if(pmt_eqv(status,PMT_T)) {
+        d_opened = false;
+        d_defer = false;
+        reset_channels();
+        recall_defer_queue();
+      }
+      
+      return;
+    }
+    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);
 
-      // if everything OK
-      status = PMT_T;
-      reply_data = pmt_list2(invocation_handle, status);
+      // 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));
+      return;
+    }
 
-      //  ...and send it
-      d_cs->send(s_response_open, reply_data);
+    goto unhandled;
+  }
+
+  // Checking for defer on all other messages
+  if(d_defer) {
+    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
+
+    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;
+      }
+
+      // the parameters are the same to the low level interface, so we just 
pass 'data' along
+      d_cs_usrp->send(s_cmd_usrp_open, data);
+
+      d_defer = true;
+      
       return;
     }
     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;
+      }
+      
+      d_defer = true;
+      d_cs_usrp->send(s_cmd_usrp_close, pmt_list1(invocation_handle));
+
+      return;
     }
     else if (pmt_eq(event, s_cmd_max_capacity)) {
       invocation_handle = pmt_nth(0, data);
-      reply_data = pmt_list2(invocation_handle, pmt_from_long(max_capacity()));
+      if(!d_opened) { 
+        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);
       return;
     }
     else if (pmt_eq(event, s_cmd_ntx_chan)) {
       invocation_handle = pmt_nth(0, data);
-      reply_data = pmt_list2(invocation_handle, pmt_from_long(d_ntx_chan));
+      if(!d_opened) { 
+        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);
+      return;
     }
     else if (pmt_eq(event, s_cmd_nrx_chan)) {
       invocation_handle = pmt_nth(0, data);
-      reply_data = pmt_list2(invocation_handle, pmt_from_long(d_nrx_chan));
+      if(!d_opened) { 
+        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);
+      return;
     }
     else if (pmt_eq(event, s_cmd_current_capacity_allocation)) {
       invocation_handle = pmt_nth(0, data);
-      reply_data = pmt_list2(invocation_handle, 
pmt_from_long(current_capacity_allocation()));
+      if(!d_opened) { 
+        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);
+      return;
     }
     goto unhandled;
   }
 
+
   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)));
+      }
+      return;
+    }
+
     handle_cmd_allocate_channel(port_id, data);
     return;
   }
 
   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)));
+      }
+      return;
+    }
+
     handle_cmd_deallocate_channel(port_id, data);
     return;
   }
     
   if (pmt_eq(event, s_cmd_xmit_raw_frame)){
-    handle_cmd_xmit_raw_frame(data);
+    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));
+      return;
+    }
+    handle_cmd_xmit_raw_frame(port_id, data);
     return;
   }
 
@@ -351,44 +513,84 @@
 
 }
 
-void usrp_server::handle_cmd_xmit_raw_frame(pmt_t data) {
+void usrp_server::handle_cmd_xmit_raw_frame(pmt_t port_id, pmt_t data) {
 
   size_t n_bytes, psize;
   long max_payload_len = transport_pkt::max_payload();
+  pmt_t reply_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;
 
-  // 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);
+  // 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) {
+  
+    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;
+    }
 
-  transport_pkt *pkts =
-    (transport_pkt *) pmt_u8vector_writeable_elements(v_packets, psize);
+    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;
+    }
 
-  for(int n=0; n < n_packets; n++) {
+    // 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);
 
-    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);
+    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(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);
+      }
+
+      memcpy(pkts[n].payload(), (uint8_t *)samples+(max_payload_len * n), 
payload_len);
     }
 
-    memcpy(pkts[n].payload(), (uint8_t *)samples+(max_payload_len * n), 
payload_len);
+    pkts[n_packets-1].set_end_of_burst();   // set the last packet's end of 
burst
+
+    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_list4(invocation_handle, 
pmt_from_long(channel), v_packets, 
pmt_from_long(n_packets*transport_pkt::max_pkt_size())));
+
   }
+}
 
-  pkts[n_packets-1].set_end_of_burst();   // set the last packet's end of burst
+void
+usrp_server::recall_defer_queue()
+{
 
-  // interface with the USRP to send the USB packet, since the memory is
-  // contiguous, this should be a serious of memory copies to the bus, each 
being
-  // USB_PKT_SIZE * MAX_PACKET_BURST bytes worth of data (given a full burst)
+  std::vector<mb_message_sptr> recall;
+
+  while(!d_defer_queue.empty()) {
+    recall.push_back(d_defer_queue.front());
+    d_defer_queue.pop();
+  }
+
+  // Parse the messages that were queued while waiting for an open response
+  for(int i=0; i < (int)recall.size(); i++) 
+    handle_message(recall[i]);
+
+  return;
 }
 
 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-02 22:43:26 UTC (rev 5611)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.h    
2007-06-02 23:41:17 UTC (rev 5612)
@@ -23,14 +23,14 @@
 
 #include <mb_mblock.h>
 #include <vector>
+#include <queue>
 
 /*!
- * \brief Implements the lowest-level mblock interface to the USRP
+ * \brief Implements the lowest-level mblock usb_interface to the USRP
  */
 class usrp_server : public mb_mblock
 {
 public:
-
   enum error_codes {
     RQSTD_CAPACITY_UNAVAIL = 0,
     CHANNEL_UNAVAIL = 1,
@@ -46,6 +46,7 @@
   static const int N_PORTS = 4;
   std::vector<mb_port_sptr> d_tx, d_rx;
   mb_port_sptr d_cs;
+  mb_port_sptr d_cs_usrp;
 
   static const int D_USB_CAPACITY = 32 * 1024 * 1024;
   static const int D_MAX_CHANNELS = 16;
@@ -60,6 +61,11 @@
   struct channel_info d_chaninfo_tx[D_MAX_CHANNELS];
   struct channel_info d_chaninfo_rx[D_MAX_CHANNELS];
 
+  std::queue<mb_message_sptr> d_defer_queue;
+
+  bool d_defer;
+  bool d_opened;
+
 public:
   usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg);
   ~usrp_server();
@@ -73,10 +79,12 @@
 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 data);
+  void handle_cmd_xmit_raw_frame(pmt_t port_id, 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();
 };
 
 #endif /* INCLUDED_USRP_SERVER_H */

Modified: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.mbh
===================================================================
--- gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.mbh  
2007-06-02 22:43:26 UTC (rev 5611)
+++ gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_server.mbh  
2007-06-02 23:41:17 UTC (rev 5612)
@@ -248,9 +248,9 @@
   (:incoming
    (response-open invocation-handle status)
    (response-close invocation-handle status)
-   (response-max-capacity invocation-handle capacity)
-   (response-ntx-chan invocation-handle ntx-chan)
-   (response-nrx-chan invocation-handle nrx-chan)
-   (response-current-capacity-allocation invocation-handle capacity)
+   (response-max-capacity invocation-handle status capacity)
+   (response-ntx-chan invocation-handle status ntx-chan)
+   (response-nrx-chan invocation-handle status nrx-chan)
+   (response-current-capacity-allocation invocation-handle status capacity)
    )
   )

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
 (from rev 5611, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_usb_interface.cc)
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
                            (rev 0)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.cc
    2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,224 @@
+/* -*- 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_usb_interface.h>
+#include <usrp_inband_usb_packet.h>
+#include "usrp_standard.h"
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static pmt_t s_cmd_usrp_open = pmt_intern("cmd-usrp-open");
+static pmt_t s_cmd_usrp_close = pmt_intern("cmd-usrp-close");
+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_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");
+
+// 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)
+{
+  d_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL);      
+  
+  // FIX ME: the code should query the FPGA to retrieve the number of channels 
and such
+  d_ntx_chan = 2;
+  d_nrx_chan = 2;
+
+  d_utx = NULL;
+  d_urx = NULL;
+}
+
+usrp_usb_interface::~usrp_usb_interface() 
+{ 
+
+}
+
+void 
+usrp_usb_interface::initial_transition()
+{
+
+}
+
+void
+usrp_usb_interface::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();         // the "name" of the message
+  pmt_t port_id = msg->port_id();      // which port it came in on
+  pmt_t data = msg->data();
+  pmt_t invocation_handle;
+
+  // message came in on our control/status port
+  if (pmt_eq(port_id, d_cs->port_symbol())) {  
+
+    if (pmt_eq(event, s_cmd_usrp_open)){
+      handle_cmd_open(data);
+      return;
+    }
+    else if (pmt_eq(event, s_cmd_usrp_close)) {
+      handle_cmd_close(data);
+      return;
+    }
+    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)));
+      return;
+    }
+    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)));
+      return;
+    }
+    else if(pmt_eq(event, s_cmd_usrp_write)) {
+      handle_cmd_write(data);
+      return;
+    }
+    goto unhandled;
+  }
+
+ unhandled:
+  std::cout << "[usrp_usb_interface] unhandled msg: " << msg << std::endl;
+}
+
+void
+usrp_usb_interface::handle_cmd_open(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long which_usrp = pmt_to_long(pmt_nth(1, data));
+  pmt_t reply_data;
+
+  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
+   
+  d_utx = usrp_standard_tx::make (which_usrp,
+    16,               // interp = 32.0MB/s
+    d_ntx_chan,                
+    -1,               // mux
+    4096,             // USB block size
+    16);              // number of blocks for async transfers
+
+  if(d_utx==0) {
+    std::cout << "[USRP_USB_INTERFACE] Failed to open TX\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
+  if(!d_utx->set_tx_freq (0,0)) {  // try setting center freq to 0
+    std::cout << "[USRP_USB_INTERFACE] Failed to set center frequency on TX\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
+  d_utx->start();
+
+  std::cout << "[USRP_USB_INTERFACE] Setup TX channel\n";
+
+  d_urx = usrp_standard_rx::make (which_usrp,
+    16,               // interp = 32.0MB/s
+    d_nrx_chan,                
+    -1,               // mux
+    0,                // set blank mode to start
+    4096,             // USB block size
+    16);              // number of blocks for async transfers
+
+  if(!d_urx) {
+    std::cout << "[usrp_server] Failed to open RX\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
+  if(!d_urx->set_rx_freq (0,0)) {  // try setting center freq to 0
+    std::cout << "[usrp_server] Failed to set center frequency on RX\n";
+    reply_data = pmt_list2(invocation_handle, PMT_F);
+    d_cs->send(s_response_usrp_open, reply_data);
+    return;
+  }
+
+  d_urx->start();   // FIXME: currently causing a hang
+  
+  std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n";
+
+  d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
+}
+
+void
+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);
+  long n_bytes = pmt_to_long(pmt_nth(3, data));
+  
+  size_t psize;
+  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, psize);
+
+  int ret = d_utx->write (pkts, n_bytes, &underrun);
+
+  if (ret == n_bytes) {
+    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));
+  }
+  else {
+    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));
+  }
+
+  return;
+}
+
+void
+usrp_usb_interface::handle_cmd_close(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  
+  std::cout << "[usrp_usb_interface] Handling close request for USRP\n";
+
+  delete d_utx;
+
+  delete d_urx;
+
+  d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
+
+  shutdown_all(PMT_T);
+}
+
+
+REGISTER_MBLOCK_CLASS(usrp_usb_interface);

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h 
(from rev 5611, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_usb_interface.h)
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h 
                            (rev 0)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface.h 
    2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,57 @@
+/* -*- 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_USB_INTERFACE_H
+#define INCLUDED_USRP_USB_INTERFACE_H
+
+#include <mb_mblock.h>
+#include <vector>
+#include "usrp_standard.h"
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_usb_interface : public mb_mblock
+{
+ public:
+
+  usrp_standard_tx* d_utx;
+  usrp_standard_rx* d_urx;
+  
+  mb_port_sptr d_cs;
+  
+  long d_ntx_chan;
+  long d_nrx_chan;
+
+ public:
+  usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg);
+  ~usrp_usb_interface();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void handle_cmd_open(pmt_t data);
+  void handle_cmd_close(pmt_t data);
+  void handle_cmd_write(pmt_t data);
+ 
+};
+  
+
+#endif /* INCLUDED_USRP_USB_INTERFACE_H */

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc
 (from rev 5611, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_usb_interface_stub.cc)
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc
                               (rev 0)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.cc
       2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,152 @@
+/* -*- 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_usb_interface_stub.h>
+#include <usrp_inband_usb_packet.h>
+#include "usrp_standard.h"
+
+typedef usrp_inband_usb_packet transport_pkt;
+
+static pmt_t s_cmd_usrp_open = pmt_intern("cmd-usrp-open");
+static pmt_t s_cmd_usrp_close = pmt_intern("cmd-usrp-close");
+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_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");
+
+// need to take number of TX and RX channels as parameter
+usrp_usb_interface_stub::usrp_usb_interface_stub(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-interface-cs", true, mb_port::EXTERNAL);      
+  
+  // FIX ME: the code should query the FPGA to retrieve the number of channels 
and such
+  d_ntx_chan = 2;
+  d_nrx_chan = 2;
+
+  d_utx = NULL;
+  d_urx = NULL;
+}
+
+usrp_usb_interface_stub::~usrp_usb_interface_stub() 
+{ 
+
+}
+
+void 
+usrp_usb_interface_stub::initial_transition()
+{
+
+}
+
+void
+usrp_usb_interface_stub::handle_message(mb_message_sptr msg)
+{
+  pmt_t event = msg->signal();         // the "name" of the message
+  pmt_t port_id = msg->port_id();      // which port it came in on
+  pmt_t data = msg->data();
+  pmt_t invocation_handle;
+
+  // message came in on our control/status port
+  if (pmt_eq(port_id, d_cs->port_symbol())) {  
+
+    if (pmt_eq(event, s_cmd_usrp_open)){
+      handle_cmd_open(data);
+      return;
+    }
+    else if (pmt_eq(event, s_cmd_usrp_close)) {
+      handle_cmd_close(data);
+      return;
+    }
+    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)));
+      return;
+    }
+    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)));
+      return;
+    }
+    else if(pmt_eq(event, s_cmd_usrp_write)) {
+      handle_cmd_write(data);
+      return;
+    }
+    goto unhandled;
+  }
+
+ unhandled:
+  std::cout << "[USRP_USB_INTERFACE_STUB] unhandled msg: " << msg << std::endl;
+}
+
+void
+usrp_usb_interface_stub::handle_cmd_open(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long which_usrp = pmt_to_long(pmt_nth(1, data));
+  pmt_t rx_mode = pmt_nth(2, data);
+  pmt_t reply_data;
+
+  std::cout << "[USRP_USB_INTERFACE_STUB] Handling open request for USRP " << 
which_usrp << "\n";
+
+  usleep(2 * 1000000);  // artificial time to open the interface
+
+  d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
+}
+
+void
+usrp_usb_interface_stub::handle_cmd_write(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  pmt_t channel = pmt_nth(1, data);
+  
+  d_cs->send(s_response_usrp_write, pmt_list3(invocation_handle, channel, 
PMT_T));
+
+  std::cout << "[USRP_USB_INTERFACE_STUB] Successful write\n";
+
+  return;
+}
+
+void
+usrp_usb_interface_stub::handle_cmd_close(pmt_t data)
+{
+  pmt_t invocation_handle = pmt_nth(0, data);
+  
+  std::cout << "[USRP_USB_INTERFACE_STUB] Handling close request for USRP\n";
+
+  d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
+
+  return;
+}
+
+
+REGISTER_MBLOCK_CLASS(usrp_usb_interface_stub);

Copied: 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h
 (from rev 5611, 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_usb_interface_stub.h)
===================================================================
--- 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h
                                (rev 0)
+++ 
gnuradio/branches/features/inband-usb/usrp/host/lib/inband/usrp_usb_interface_stub.h
        2007-06-02 23:41:17 UTC (rev 5612)
@@ -0,0 +1,57 @@
+/* -*- 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_USB_INTERFACE_STUB_H
+#define INCLUDED_USRP_USB_INTERFACE_STUB_H
+
+#include <mb_mblock.h>
+#include <vector>
+#include "usrp_standard.h"
+
+/*!
+ * \brief Implements the low level usb interface to the USRP
+ */
+class usrp_usb_interface_stub : public mb_mblock
+{
+ public:
+
+  usrp_standard_tx* d_utx;
+  usrp_standard_rx* d_urx;
+  
+  mb_port_sptr d_cs;
+  
+  long d_ntx_chan;
+  long d_nrx_chan;
+
+ public:
+  usrp_usb_interface_stub(mb_runtime *rt, const std::string &instance_name, 
pmt_t user_arg);
+  ~usrp_usb_interface_stub();
+  void initial_transition();
+  void handle_message(mb_message_sptr msg);
+
+ private:
+  void handle_cmd_open(pmt_t data);
+  void handle_cmd_close(pmt_t data);
+  void handle_cmd_write(pmt_t data);
+ 
+};
+  
+
+#endif /* INCLUDED_USRP_USB_INTERFACE_STUB_H */





reply via email to

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