Merged r7857:7898 from n4hy/msddLTS into trunk, with modification. Adds gr-msdd6000...
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Fri, 29 Feb 2008 19:26:49 +0000 (19:26 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Fri, 29 Feb 2008 19:26:49 +0000 (19:26 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@7904 221aa14e-8319-0410-a670-987f0aec2ac5

24 files changed:
AUTHORS
config/Makefile.am
config/grc_gr_msdd6000.m4 [new file with mode: 0644]
configure.ac
gr-msdd6000/AUTHORS [new file with mode: 0644]
gr-msdd6000/Makefile.am [new file with mode: 0644]
gr-msdd6000/doc/Softronics_Ltd_msdd6000_BlockDiagram.pdf [new file with mode: 0644]
gr-msdd6000/src/Makefile.am [new file with mode: 0644]
gr-msdd6000/src/lib/Makefile.am [new file with mode: 0644]
gr-msdd6000/src/lib/msdd.i [new file with mode: 0644]
gr-msdd6000/src/lib/msdd_buffer_copy_behaviors.h [new file with mode: 0644]
gr-msdd6000/src/lib/msdd_source_base.cc [new file with mode: 0644]
gr-msdd6000/src/lib/msdd_source_base.h [new file with mode: 0644]
gr-msdd6000/src/lib/msdd_source_c.cc [new file with mode: 0644]
gr-msdd6000/src/lib/msdd_source_c.h [new file with mode: 0644]
gr-msdd6000/src/lib/msdd_source_s.cc [new file with mode: 0644]
gr-msdd6000/src/lib/msdd_source_s.h [new file with mode: 0644]
gr-msdd6000/src/python/Makefile.am [new file with mode: 0644]
gr-msdd6000/src/python/qa_msdd6000.py [new file with mode: 0755]
gr-msdd6000/src/python/run_tests.in [new file with mode: 0644]
gr-msdd6000/src/python/test_tcp.py [new file with mode: 0755]
gr-msdd6000/src/python/test_udp.py [new file with mode: 0755]
gr-msdd6000/src/python_test/test_tcp.py [new file with mode: 0755]
gr-msdd6000/src/python_test/test_udp.py [new file with mode: 0755]

diff --git a/AUTHORS b/AUTHORS
index e030f7b7c1102a7dea3bc638f36e4787119b5875..9c6e4c6c5c2e8742b926952ff8d559e2e558dc6b 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -12,3 +12,4 @@ Joshua Lackey <jl@noether.uoregon.edu>        Original GMSK implementation.
 Johnathan Corgan <jcorgan@corganenterprises.com>  Build system, ongoing stuff, release manager
 Bdale Garbee <bdale@gag.com>           Debian release packages
 Tom Rondeau <trondeau@vt.edu>          Mostly digital waveforms and a little bit of trouble
+Nate Goergen (UMD Student)
index 676183aa563ad0965470c852f81fbe13ec219a6a..be258b71e1066802a5ca8765a2c00808a2e0d8de 100644 (file)
@@ -57,6 +57,7 @@ m4macros = \
        gr_check_usrp.m4 \
        grc_pmt.m4 \
        grc_usrp.m4 \
+       grc_gr_msdd6000.m4 \
        gr_doxygen.m4 \
        gr_fortran.m4 \
        gr_gprof.m4 \
diff --git a/config/grc_gr_msdd6000.m4 b/config/grc_gr_msdd6000.m4
new file mode 100644 (file)
index 0000000..056b084
--- /dev/null
@@ -0,0 +1,38 @@
+dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc.
+dnl 
+dnl This file is part of GNU Radio
+dnl 
+dnl GNU Radio is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl 
+dnl GNU Radio is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl 
+dnl You should have received a copy of the GNU General Public License
+dnl along with GNU Radio; see the file COPYING.  If not, write to
+dnl the Free Software Foundation, Inc., 51 Franklin Street,
+dnl Boston, MA 02110-1301, USA.
+
+AC_DEFUN([GRC_GR_MSDD6000],[
+    GRC_ENABLE([gr-msdd6000])
+
+    AC_CONFIG_FILES([\
+       gr-msdd6000/Makefile \
+       gr-msdd6000/src/Makefile \
+       gr-msdd6000/src/lib/Makefile \
+       gr-msdd6000/src/python/Makefile
+       gr-msdd6000/src/python/run_tests
+    ])
+
+    dnl Don't do gr-msdd6000 if gnuradio-core skipped
+    GRC_CHECK_DEPENDENCY(gr-msdd6000, gnuradio-core)
+
+    GRC_BUILD_CONDITIONAL([gr-msdd6000],[
+        dnl run_tests is created from run_tests.in.  Make it executable.
+       AC_CONFIG_COMMANDS([run_tests_msdd6000], [chmod +x gr-msdd6000/src/python/run_tests])
+    ])
+])
index e47bcc2dd6c4e57cb3f54b073625c201fad0a8bb..f918f9b0d2c72a5828ceda97fdd42267df493001 100644 (file)
@@ -249,6 +249,7 @@ GRC_PMT
 GRC_MBLOCK                     dnl this must come after GRC_PMT
 GRC_USRP
 GRC_GR_USRP                    dnl this must come after GRC_USRP
+GRC_GR_MSDD6000
 GRC_GR_AUDIO_ALSA
 GRC_GR_AUDIO_JACK
 GRC_GR_AUDIO_OSS
diff --git a/gr-msdd6000/AUTHORS b/gr-msdd6000/AUTHORS
new file mode 100644 (file)
index 0000000..683b38b
--- /dev/null
@@ -0,0 +1,3 @@
+Charles Clancy
+Nate Goergen
+n4hy (Bob McGwier)
diff --git a/gr-msdd6000/Makefile.am b/gr-msdd6000/Makefile.am
new file mode 100644 (file)
index 0000000..73f418e
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+SUBDIRS = src
+
diff --git a/gr-msdd6000/doc/Softronics_Ltd_msdd6000_BlockDiagram.pdf b/gr-msdd6000/doc/Softronics_Ltd_msdd6000_BlockDiagram.pdf
new file mode 100644 (file)
index 0000000..34356da
Binary files /dev/null and b/gr-msdd6000/doc/Softronics_Ltd_msdd6000_BlockDiagram.pdf differ
diff --git a/gr-msdd6000/src/Makefile.am b/gr-msdd6000/src/Makefile.am
new file mode 100644 (file)
index 0000000..923b1c2
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Copyright 2004,2005,2006 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+SUBDIRS = lib python
diff --git a/gr-msdd6000/src/lib/Makefile.am b/gr-msdd6000/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..0001890
--- /dev/null
@@ -0,0 +1,117 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 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 GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+
+include $(top_srcdir)/Makefile.common
+
+# Install this stuff so that it ends up as the gnuradio.msdd module
+# This usually ends up at:
+#   ${prefix}/lib/python${python_version}/site-packages/gnuradio
+
+ourpythondir = $(grpythondir)
+ourlibdir    = $(grpyexecdir)
+
+AM_CPPFLAGS =                          \
+       $(STD_DEFINES_AND_INCLUDES)     \
+       $(PYTHON_CPPFLAGS)              \
+       $(WITH_INCLUDES)                \
+       $(CPPUNIT_INCLUDES)
+
+noinst_LTLIBRARIES = libmsdd.la
+
+libmsdd_la_SOURCES =                   \
+       msdd_source_base.cc             \
+       msdd_source_c.cc                \
+       msdd_source_s.cc
+
+# ------------------------------------------------------------------------
+#  This is the swig-ish part of the Makefile.
+#  It builds the msdd module which we'll load into python
+# ------------------------------------------------------------------------
+
+SWIGCPPPYTHONARGS = -fvirtual -python -modern $(PYTHON_CPPFLAGS) \
+       $(STD_DEFINES_AND_INCLUDES) $(WITH_SWIG_INCLUDES) $(WITH_INCLUDES)
+
+ALL_IFILES =                           \
+       $(LOCAL_IFILES)                 \
+       $(NON_LOCAL_IFILES)             
+
+NON_LOCAL_IFILES =                     \
+       $(top_srcdir)/gnuradio-core/src/lib/swig/gnuradio.i
+
+LOCAL_IFILES =                                 \
+       $(top_srcdir)/gr-msdd6000/src/lib/msdd.i                                
+
+
+# These files are built by SWIG.  The first is the C++ glue.
+# # The second is the python wrapper that loads the _msdd shared library
+# # and knows how to call our extensions.
+#
+#
+#
+swig_built_sources =                   \
+       msdd.cc                         \
+       msdd.py 
+
+# This gets msdd.py installed in the right place
+#
+ourpython_PYTHON =                     \
+       msdd.py
+
+
+ourlib_LTLIBRARIES = _msdd.la
+
+# These are the source files that go into the shared library
+_msdd_la_SOURCES =                     \
+       msdd.cc
+
+# magic flag
+_msdd_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version 
+
+# link the library against some comon swig runtime code and the 
+# c++ standard library
+
+_msdd_la_LIBADD =                      \
+       $(GNURADIO_CORE_LA)             \
+       $(PYTHON_LDFLAGS)               \
+       libmsdd.la                      \
+       -lstdc++
+
+msdd.cc msdd.py: msdd.i $(ALL_FILES)
+       $(SWIG) $(SWIGCPPPYTHONARGS) -module msdd -o msdd.cc $(LOCAL_IFILES)
+
+# These headers get installed in ${prefix}/include/gnuradio
+grinclude_HEADERS =                    \
+       msdd_buffer_copy_behaviors.h    \
+       msdd_source_base.h              \
+       msdd_source_c.h                 \
+       msdd_source_s.h                 
+
+# These swig headers get installed in ${prefix}/include/gnuradio/swig
+swiginclude_HEADERS =                  \
+       $(LOCAL_IFILES)
+
+MOSTLYCLEANFILES = $(BUILT_SOURCES) *.pyc *~
+
+# Don't distribute output of swig
+dist-hook:
+       @for file in $(BUILT_SOURCES); do echo $(RM) $(distdir)/$$file; done
+       @for file in $(BUILT_SOURCES); do $(RM) $(distdir)/$$file; done
diff --git a/gr-msdd6000/src/lib/msdd.i b/gr-msdd6000/src/lib/msdd.i
new file mode 100644 (file)
index 0000000..809445c
--- /dev/null
@@ -0,0 +1,254 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+%feature("autodoc", "1");              // generate python docstrings
+
+%include "exception.i"
+%import "gnuradio.i"                           // the common stuff
+
+%{
+
+#include "gnuradio_swig_bug_workaround.h"      // mandatory bug fix
+#include <stdexcept>
+#include "msdd_source_s.h"
+#include "msdd_source_c.h"
+%}
+
+// ================================================================
+//                        abstract classes
+// ================================================================
+
+// ----------------------------------------------------------------
+
+class msdd_source_base : public gr_sync_block {
+
+ protected:
+  msdd_source_base (const std::string &name,
+                   gr_io_signature_sptr output_signature,
+                   int which_board,
+                   msdd_source_base::msdd_command_type_t opp_mode,
+                   const char *src, 
+                   unsigned short port_src
+                   ) throw (std::runtime_error);
+
+  /*!
+   * \brief return number of msdd input bytes required to produce noutput items.
+   */
+  int ninput_bytes_reqd_for_noutput_items (int noutput_items) = 0;
+
+  /*!
+   * \brief number of bytes in a low-level sample
+   */
+  unsigned int sizeof_basic_sample() const;
+
+  /*!
+   * \brief convert between native msdd format and output item format
+   *
+   * \param output_items[out]   stream(s) of output items
+   * \param output_index[in]    starting index in output_items
+   * \param output_items_available[in]  number of empty items available at item[index]
+   * \param output_items_produced[out]  number of items produced by copy
+   * \param msdd_buffer[in]   source buffer
+   * \param msdd_buffer_length[in]  number of bytes available in \p msdd_buffer
+   * \param bytes_read[out]   number of bytes read from \p msdd_buffer
+   *
+   * The copy must consume all bytes available.  That is, \p bytes_read must equal
+   * \p msdd_buffer_length.
+   */
+  virtual void copy_from_msdd_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *msdd_buffer,
+                                     int msdd_buffer_length,
+                                     int &bytes_read) = 0;
+  
+  int readsock(int sockfd, unsigned char* buf, int nbytes);
+  
+  void* make_request_packet(unsigned int& size, unsigned int number_samples);
+  
+ public:
+  //! magic value used on alternate register read interfaces
+  static const int READ_FAILED = -99999;
+
+  ~msdd_source_base ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+
+  bool start();
+  bool stop();
+  
+  /*!
+   * \brief Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which      which D/A [0,3]
+   * \param gain_in_db gain value (linear in dB)
+   *
+   * gain is rounded to closest setting supported by hardware.
+   * Note that DAC 0 and DAC 1 share a gain setting as do DAC 2 and DAC 3.
+   * Setting DAC 0 affects DAC 1 and vice versa.  Same with DAC 2 and DAC 3.
+   *
+   * \returns true iff sucessful.
+   *
+   * \sa pga_min(), pga_max(), pga_db_per_step()
+   */
+  bool set_pga (int which, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain in dB.
+   *
+   * \param which      which D/A [0,3]
+   */
+  double pga (int which) const;
+
+  /*!
+   * \brief Return minimum legal PGA gain in dB.
+   */
+  double pga_min () const;
+
+  /*!
+   * \brief Return maximum legal PGA gain in dB.
+   */
+  double pga_max () const;
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  double pga_db_per_step () const;
+
+  /*!
+   * \brief open a socket specified by the port and ip address info
+   *
+   * Opens a socket, binds to the address, and waits for a connection
+   * over UDP. If any of these fail, the fuction retuns the error and exits.
+   */
+  bool open();
+
+  /*!
+   * \brief Close current socket.
+   *
+   * Shuts down read/write on the socket
+   */
+  bool close();
+  
+  /*!
+   * \brief Set decimator rate.  \p rate must be EVEN and in [8, 256].
+   *
+   * The final complex sample rate across the USB is
+   *   adc_freq () / decim_rate ()
+   */
+  bool set_decim_rate (unsigned int rate);
+
+  /*!
+   * \brief set the center frequency of the digital down converter.
+   *
+   * \p channel must be 0.  \p freq is the center frequency in Hz.
+   * It must be in the range [-FIXME, FIXME].  The frequency specified is
+   * quantized.  Use rx_freq to retrieve the actual value used.
+   */
+  bool set_rx_freq (int channel, double freq);
+
+  void set_verbose (bool verbose);
+
+  // ACCESSORS
+
+  unsigned int decim_rate () const;
+  double rx_freq (int channel) const;
+  int noverruns () const { return d_noverruns; }
+
+  /*!
+   * \brief return the msdd's serial number.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  std::string serial_number();
+  
+  bool set_desired_packet_size (int which, unsigned long packet_size);
+
+  unsigned long desired_packet_size (int which) const;
+
+};
+
+
+// ================================================================
+//      concrete sources
+// ================================================================
+
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(msdd,source_s)
+
+msdd_source_s_sptr
+msdd_make_source_s (int which_board, 
+                   unsigned int decim_rate,
+                   unsigned int fft_points,
+                   double initial_rx_freq,
+                   int opp_mode,
+                   const char *src, 
+                   unsigned short port_src
+                   ) throw (std::runtime_error);
+
+
+class msdd_source_s : public msdd_source_base {
+protected:
+  msdd_source_s (int which_board, 
+                unsigned int decim_rate,
+                unsigned int fft_points,
+                double initial_rx_freq,
+                int opp_mode,
+                const char *src, 
+                unsigned short port_src
+                ) throw (std::runtime_error);
+  
+  virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items);
+  
+public:
+  ~msdd_source_s ();
+};
+
+
+GR_SWIG_BLOCK_MAGIC(msdd,source_c)
+
+msdd_source_c_sptr
+msdd_make_source_c (int which_board, 
+                   int opp_mode,
+                   const char *src, 
+                   unsigned short port_src
+                   ) throw (std::runtime_error);
+
+
+class msdd_source_c : public msdd_source_base {
+protected:
+  msdd_source_c (int which_board, 
+                int opp_mode,
+                const char *src, 
+                unsigned short port_src
+                ) throw (std::runtime_error);
+  
+  virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items);
+  
+public:
+  ~msdd_source_c ();
+};
diff --git a/gr-msdd6000/src/lib/msdd_buffer_copy_behaviors.h b/gr-msdd6000/src/lib/msdd_buffer_copy_behaviors.h
new file mode 100644 (file)
index 0000000..26cf245
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef MSDD_BUFFER_COPY_BEHAVIORS_H_
+#define MSDD_BUFFER_COPY_BEHAVIORS_H_
+
+namespace msdd {
+       
+  class BufferCopyBehavior 
+  {
+  public: 
+    virtual void operator() (gr_vector_void_star &a, const void * b, unsigned int output_index, unsigned int nitems) = 0;
+    virtual ~BufferCopyBehavior() {};
+  };
+         
+  template <class Tin, class Tout> 
+  class BufferCopyBehaviorGeneric : public BufferCopyBehavior {
+    void operator() (gr_vector_void_star &a, const void * b, unsigned int output_index, unsigned int nitems) {
+      Tout     *out(&(reinterpret_cast<Tout *>(a[0]))[output_index]);  // sloppy
+      const Tin        *in(reinterpret_cast<const Tin *>(b)); // equisloppy
+      
+      for (unsigned int i = 0; i < nitems; ++i) {
+       out[i] = in[i];
+      }
+    }
+  };
+  
+  template <class Tin>
+  class BufferCopyBehaviorComplex : public BufferCopyBehavior {
+    void operator() (gr_vector_void_star &a, const void * b, unsigned int output_index, unsigned int nitems) {
+      gr_complex       *out(&(reinterpret_cast<gr_complex *>(a[0]))[output_index]);    // sloppy
+      const Tin        *in(reinterpret_cast<const Tin *>(b)); // equisloppy
+      
+      for (unsigned int i = 0; i < nitems; ++i) {
+       out[i] = gr_complex (in[4*i+1],in[4*i+3]);
+      }
+    }
+  };
+}
+
+#endif /*MSDD_BUFFER_COPY_BEHAVIORS_H_*/
diff --git a/gr-msdd6000/src/lib/msdd_source_base.cc b/gr-msdd6000/src/lib/msdd_source_base.cc
new file mode 100644 (file)
index 0000000..d9cb03e
--- /dev/null
@@ -0,0 +1,817 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+//#define MSDD_DEBUG_TRUE
+//#define MSDD_DEBUG2_TRUE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <msdd_source_base.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <netdb.h>
+#include <omnithread.h>
+#include <stdexcept>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+#ifdef MSDD_DEBUG_TRUE
+#include <iostream>
+#define MSDD_DEBUG(x) std::cout << x << std::endl;
+#else
+#define MSDD_DEBUG(x)
+#endif
+
+
+#ifdef MSDD_DEBUG2_TRUE
+#include <iostream>
+#define MSDD_DEBUG2(x) std::cout << x << std::endl;
+#else
+#define MSDD_DEBUG2(x)
+#endif
+
+#include <iostream>
+
+namespace {
+  const int OUTPUT_MAX((1 << 15)*8);
+  const double PGA_MAX(75);
+  const double PGA_MIN(10);
+  const double PGA_STEP(.5);
+  const double DEFAULT_RX_FREQ(2.417e6);
+  const double DEFAULT_GAIN(32);
+  const msdd_source_base::msdd_fft_mode_t DEFAULT_FFT_MODE(msdd_source_base::MODE_MAG);
+  const msdd_source_base::msdd_fft_points_t DEFAULT_FFT_POINTS(msdd_source_base::S8192);
+  const msdd_source_base::msdd_decimation_t DEFAULT_DECIMATION_RATE(msdd_source_base::D2);
+}
+
+class msdd_source_base::Impl {
+  
+public:
+  Impl(int opp_mode) :
+    d_noverruns (0),
+    d_deci_rate (DEFAULT_DECIMATION_RATE),
+    d_rx_freq ((unsigned long) DEFAULT_RX_FREQ),
+    d_gain(DEFAULT_GAIN),
+    d_verbose (false),
+    d_updated(false),
+    d_msdd_command_type((msdd_command_type_t) opp_mode),
+    d_msdd_fft_mode(DEFAULT_FFT_MODE),
+    d_desired_sample_size(2^15),
+    d_fft_points (DEFAULT_FFT_POINTS)
+  {
+  }
+
+  int            d_noverruns;
+  msdd_decimation_t   d_deci_rate;
+  unsigned long  d_rx_freq;
+  double         d_gain;
+  bool           d_verbose;
+  bool           d_updated;  
+  msdd_command_type_t d_msdd_command_type;
+  msdd_fft_mode_t d_msdd_fft_mode;
+  unsigned long  d_desired_sample_size;
+  
+  int            d_socket;        // handle to socket
+  int            d_socket_rcv;    // handle to socket retuned in the accept call
+  struct in_addr d_ip_src;        // store the source IP address to use
+  unsigned short d_port_src;      // the port number to open for connections to this service
+  sockaddr_in    d_sockaddr_src;  // store the source sockaddr data (formatted IP address and port number) 
+  std::auto_ptr<unsigned char> d_temp_buff;     // hold buffer between calls
+  
+  omni_mutex    d_mutex;
+  msdd_fft_points_t   d_fft_points; 
+  
+  struct msdd_request_fft_packet {
+    msdd_command_type_t command_type;
+    int foo_x20;
+    unsigned int center_freq_mhz;
+    int offset_freq_hz;
+    int gain;
+    msdd_fft_window_type_t window_type;
+    msdd_fft_points_t fft_points;
+    msdd_decimation_t decimation;
+    msdd_fft_mode_t fft_mode;
+    int number_sets;
+  } __attribute__((__packed__));
+  
+  struct msdd_request_iq_packet {
+    msdd_command_type_t command_type;
+    int foo0x18;
+    unsigned int center_freq_mhz;
+    int offset_freq_hz;
+    int gain;
+    int number;
+    msdd_decimation_t decimation;
+    int number_sets;
+  } __attribute__((__packed__));
+
+  void make_request_fft_packet(msdd_request_fft_packet& packet);
+  
+  void make_request_iq_packet(msdd_request_iq_packet& packet, unsigned int number_samples);
+  
+  msdd_request_fft_packet   d_fft_request_packet; // fft request packet
+  msdd_request_iq_packet    d_iq_request_packet; // fft request packet
+};
+
+
+msdd_source_base::msdd_source_base (const std::string &name,
+                                   gr_io_signature_sptr output_signature,
+                                   int which_board,
+                                   int opp_mode,
+                                   const char *src, 
+                                   unsigned short port_src
+                                   ) throw (std::runtime_error)
+  : gr_sync_block (name,
+                  gr_make_io_signature (0, 0, 0),
+                  output_signature),
+    pimpl(new Impl(opp_mode))
+{
+  int ret (0);
+    
+  // Set up the address stucture for the source address and port numbers
+  // Get the source IP address from the host name
+  struct hostent *hsrc (gethostbyname(src));
+    
+  if(hsrc) {   // if the source was provided as a host namex
+    pimpl->d_ip_src = *(struct in_addr*)hsrc->h_addr_list[0];    
+  }
+  else { // assume it was specified as an IP address
+    if((ret=inet_aton(src, &pimpl->d_ip_src)) == 0) {            // format IP address
+      perror("Not a valid source IP address or host name");
+      throw std::runtime_error("can't initialize source socket");
+    }
+  }
+    
+  pimpl->d_port_src = htons(port_src);     // format port number
+  
+  pimpl->d_sockaddr_src.sin_family = AF_INET;
+  pimpl->d_sockaddr_src.sin_addr   = pimpl->d_ip_src;
+  pimpl->d_sockaddr_src.sin_port   = pimpl->d_port_src;
+  
+  pimpl->d_temp_buff.reset(new unsigned char[OUTPUT_MAX + 
+                                            std::max(sizeof(Impl::msdd_request_iq_packet),
+                                                     sizeof(Impl::msdd_request_fft_packet))]);   // allow it to hold up to payload_size bytes
+  
+  set_output_multiple (OUTPUT_MAX / output_signature->sizeof_stream_item (0));
+}
+                                     
+
+bool
+msdd_source_base::open()
+{
+  omni_mutex_lock l(pimpl->d_mutex);   // hold mutex for duration of this function
+  // create socket
+  MSDD_DEBUG2("MSDD: Before socket ")
+  pimpl->d_socket = socket(PF_INET, SOCK_STREAM, 0);
+  if(pimpl->d_socket == -1) {
+    perror("socket open");
+    throw std::runtime_error("can't open socket");
+  }
+
+  // Turn on reuse address
+  int opt_val (1);
+  if(setsockopt(pimpl->d_socket, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(int)) == -1) {
+    perror("SO_REUSEADDR");
+    throw std::runtime_error("can't set socket option SO_REUSEADDR");
+  }
+
+  // Don't wait when shutting down
+  linger lngr;
+  lngr.l_onoff  = 1;
+  lngr.l_linger = 0;
+  if(setsockopt(pimpl->d_socket, SOL_SOCKET, SO_LINGER, (void*)&lngr, sizeof(linger)) == -1) {
+    perror("SO_LINGER");
+    throw std::runtime_error("can't set socket option SO_LINGER");
+  }
+
+  // Set a timeout on the receive function to not block indefinitely
+  // This value can (and probably should) be changed
+  //  timeval timeout;
+  //  timeout.tv_sec = 1;
+  //  timeout.tv_usec = 0;
+  //  if(setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout)) == -1) {
+  //    perror("SO_RCVTIMEO");
+  //    throw std::runtime_error("can't set socket option SO_RCVTIMEO");
+  //  }
+
+  // bind socket to an address and port number to listen on
+  MSDD_DEBUG2("MSDD: Before socket bind to " << pimpl->d_sockaddr_src.sin_port)
+  if(::connect(pimpl->d_socket, (struct sockaddr*)&pimpl->d_sockaddr_src, sizeof(pimpl->d_sockaddr_src)) == -1) {
+    perror("socket bind");
+    throw std::runtime_error("can't bind socket");
+  }
+
+  MSDD_DEBUG2("MSDD: Socket open")
+  pimpl->d_updated = true;
+  return pimpl->d_socket != 0;
+}
+
+/* read n bytes from a socket descriptor */
+int 
+msdd_source_base::readsock(int sockfd, unsigned char* buf, int nbytes) {
+  int nleft (nbytes);
+  int nread (0);
+    
+  while (nleft > 0) {
+    MSDD_DEBUG2("MSDD: Before socket read: " << nleft)
+    if ((nread = ::read(sockfd, buf, nleft)) < 0) {
+      return(nread); /* error, nread < 0 */
+    } else if (nread == 0) {
+      break;
+    }
+            
+    nleft -= nread;
+    buf += nread;
+  }
+  return(nbytes - nleft);
+}
+
+bool
+msdd_source_base::close()
+{
+  omni_mutex_lock l(pimpl->d_mutex);   // hold mutex for duration of this function
+  
+  if (pimpl->d_socket){
+    shutdown(pimpl->d_socket, SHUT_RDWR);
+    pimpl->d_socket = 0;
+  }
+  pimpl->d_updated = true;
+  
+  return true;
+}
+
+msdd_source_base::~msdd_source_base ()
+{
+  msdd_source_base::close();
+}
+
+unsigned int
+msdd_source_base::sizeof_basic_sample() const
+{
+  switch (pimpl->d_msdd_command_type) {
+  case SAMPLES_REALTIME:
+    return 4;
+  case SAMPLES_FFT:
+    switch (pimpl->d_msdd_fft_mode) {
+    case MODE_IQ:
+    case MODE_MAG:
+      return 4;
+    case MODE_MAGDB:
+      return 1;
+    default:
+      assert (false); // bad mode
+    }
+  default:
+    assert (false); // bad mode
+  }
+}
+
+bool
+msdd_source_base::start()
+{
+  return msdd_source_base::open();
+}
+
+bool
+msdd_source_base::stop()
+{
+  return msdd_source_base::close();
+}
+
+void* 
+msdd_source_base::make_request_packet(unsigned int& size, unsigned int number_samples) {
+  switch (pimpl->d_msdd_command_type) {
+  case SAMPLES_REALTIME:
+    pimpl->make_request_iq_packet(pimpl->d_iq_request_packet, number_samples);
+    size = sizeof (pimpl->d_iq_request_packet);
+    return &pimpl->d_iq_request_packet;
+  case SAMPLES_FFT:
+    pimpl->make_request_fft_packet(pimpl->d_fft_request_packet);
+    size = sizeof (pimpl->d_fft_request_packet);
+    return &pimpl->d_fft_request_packet;
+  default:
+    assert (false); // bad mode
+  }
+}
+
+void 
+msdd_source_base::Impl::make_request_fft_packet(msdd_request_fft_packet& packet) 
+{
+  packet.command_type = SAMPLES_FFT;  // FFT samples Command
+  packet.foo_x20 = 0x20;
+  packet.center_freq_mhz = d_rx_freq;
+  packet.offset_freq_hz = 0;
+  packet.gain = (int) d_gain; // gain
+  packet.window_type = WINDOW_HANNING; // magic number
+  packet.fft_points = d_fft_points;
+  packet.decimation = d_deci_rate;
+  packet.fft_mode = MODE_MAGDB;
+  packet.number_sets = 1;
+}
+
+void 
+msdd_source_base::Impl::make_request_iq_packet(msdd_request_iq_packet& packet, unsigned int number_samples) 
+{
+  packet.command_type = SAMPLES_REALTIME;  // FFT samples Command
+  packet.foo0x18 = 0x18; // magic number
+  packet.center_freq_mhz = d_rx_freq;
+  packet.offset_freq_hz = 0;
+  packet.gain = (int) d_gain; // gain
+  packet.number = number_samples * 4;
+  packet.decimation = d_deci_rate;
+  packet.number_sets = 1;
+}
+
+int
+msdd_source_base::work (int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  int output_index (0);
+  int output_items_produced;
+  int bytes_read;
+  
+  unsigned int packet_size;
+  
+  MSDD_DEBUG("MSDD: requested items: " << noutput_items)
+  int noutput_items_desired = std::min (noutput_items, (int) pimpl->d_desired_sample_size);
+  MSDD_DEBUG("MSDD: desired items: " << noutput_items_desired)
+    
+  while (output_index < noutput_items_desired){
+
+    int nbytes = (pimpl->d_msdd_command_type == SAMPLES_REALTIME) ? 
+      ninput_bytes_reqd_for_noutput_items (noutput_items_desired - output_index) :
+      ninput_bytes_reqd_for_noutput_items (msdd_source_base::fft_points());
+    
+    void* request_packet = msdd_source_base::make_request_packet(packet_size, noutput_items_desired);
+    
+    nbytes = std::min (nbytes, OUTPUT_MAX);
+    MSDD_DEBUG2("MSDD: payload sizes: nbytes1: " << nbytes )
+      
+    // send request
+    int result_nbytes = ::write(pimpl->d_socket, request_packet, packet_size);
+    //assert (result_nbytes == sizeof(msdd_request_packet));
+    
+    // receive ack
+    result_nbytes = ::read (pimpl->d_socket, (unsigned char*) request_packet, packet_size);
+    MSDD_DEBUG2("MSDD: response: " << result_nbytes)
+    //assert (result_nbytes == sizeof(msdd_request_packet));
+    
+    // receive payload
+    result_nbytes = msdd_source_base::readsock (pimpl->d_socket, pimpl->d_temp_buff.get(), nbytes);
+    MSDD_DEBUG("MSDD: reading bytes: " << nbytes << " received: " << result_nbytes)
+    if (result_nbytes > (int) nbytes){
+      // fprintf (stderr, "msdd_source: overrun\n");
+      fputs ("uO", stderr);
+      pimpl->d_noverruns++;
+      result_nbytes = nbytes; // truncate
+    }
+    
+    if (result_nbytes < 0)     // We've got a problem.  Usually board unplugged or powered down.
+      return -1;               // Indicate we're done.
+
+    if (result_nbytes != nbytes){      // not really an error, but unexpected
+      fprintf (stderr, "msdd_source: short read.  Expected %d, got %d\n",
+              nbytes, result_nbytes);
+    }
+
+    copy_from_msdd_buffer (output_items,
+                          output_index,
+                          noutput_items_desired - output_index,   // output_items_available
+                          output_items_produced,          // [out]
+                          pimpl->d_temp_buff.get(),                               // usrp_buffer
+                          result_nbytes,
+                          bytes_read);                    // [out]
+    
+    output_index += output_items_produced;
+    
+    if (pimpl->d_msdd_command_type == SAMPLES_FFT) break; 
+  }
+
+  MSDD_DEBUG("MSDD: items produced: " << output_items_produced << " index: " << output_index)
+  
+  //assert(false);
+  return output_index;
+}
+
+
+bool
+msdd_source_base::set_decim_rate (unsigned int rate)
+{
+  bool result (true);
+  switch (rate) {
+  case 1:
+    pimpl->d_deci_rate = D0;
+    break;
+  case 2:
+    pimpl->d_deci_rate = D1;
+    break;      
+  case 4:
+    pimpl->d_deci_rate = D2;
+    break;       
+  case 8:
+    pimpl->d_deci_rate = D3;
+    break;       
+  case 16:
+    pimpl->d_deci_rate = D4;
+    break;
+  case 32:
+    pimpl->d_deci_rate = D5;
+    break;
+  case 64:
+    pimpl->d_deci_rate = D6;
+    break;
+  case 128:
+    pimpl->d_deci_rate = D7;
+    break;
+  case 256:
+    pimpl->d_deci_rate = D8;
+    break;
+  default:
+    result = false;
+  }
+  
+  return result;
+}
+//
+//bool
+//msdd_source_base::set_nchannels (int nchan)
+//{
+//  // return d_usrp->set_nchannels (nchan);
+//     return true;
+//}
+//
+//bool
+//msdd_source_base::set_mux (int mux)
+//{
+//  return d_usrp->set_mux (mux);
+//}
+
+bool
+msdd_source_base::set_rx_freq (int channel, double freq)
+{
+  assert (channel == 0);
+  bool result (false);
+  
+  if (freq >=  30e6 && freq <= 6e9) {
+    pimpl->d_rx_freq = (unsigned long) freq / 1000000;
+    result = true;
+  }
+  
+  return result;
+}
+
+
+unsigned long
+msdd_source_base::set_fft_size (int channel, unsigned long fft_size)
+{
+  assert (channel == 1);
+  
+  switch (fft_size) {
+  case 256:        
+    pimpl->d_fft_points = S256;
+    break;
+  case 512:
+    pimpl->d_fft_points = S512;       
+    break;
+  case 1024:
+    pimpl->d_fft_points = S1024;
+    break;        
+  case 2048:
+    pimpl->d_fft_points = S2048;
+    break;        
+  case 4096:
+    pimpl->d_fft_points = S4096;
+    break;        
+  case 8192:
+    pimpl->d_fft_points = S8192;
+    break;        
+  case 16384:
+    pimpl->d_fft_points = S16384;
+    break;        
+  case 32768:
+    pimpl->d_fft_points = S32768;
+    break;        
+  }
+  
+  return msdd_source_base::fft_points();
+}
+
+//
+//long
+//msdd_source_base::fpga_master_clock_freq() const
+//{
+//  return d_usrp->fpga_master_clock_freq();
+//}
+//
+//long
+//msdd_source_base::converter_rate() const
+//{
+//  // return d_usrp->converter_rate();
+//     return 8;
+//}
+
+unsigned int
+msdd_source_base::decim_rate () const
+{
+  return 1 << pimpl->d_deci_rate;
+}
+//
+//int
+//msdd_source_base::nchannels () const
+//{
+//  return d_usrp->nchannels ();
+//}
+//
+//int
+//msdd_source_base::mux () const
+//{
+//  return d_usrp->mux ();
+//}
+
+double
+msdd_source_base::rx_freq (int channel) const
+{
+  assert (channel == 0);
+  
+  return pimpl->d_rx_freq;
+}
+
+unsigned int
+msdd_source_base::fft_points() const
+{
+  return (1 << pimpl->d_fft_points);
+}
+
+int 
+msdd_source_base::noverruns () const 
+{ 
+  return pimpl->d_noverruns; 
+}
+
+//bool
+//msdd_source_base::set_fpga_mode (int mode)
+//{
+//  return d_usrp->set_fpga_mode (mode);
+//}
+//
+//bool
+//msdd_source_base::set_ddc_phase (int channel, int phase)
+//{
+//  return d_usrp->set_ddc_phase(channel, phase);
+//}
+//
+//bool
+//msdd_source_base::set_dc_offset_cl_enable(int bits, int mask)
+//{
+//  return d_usrp->set_dc_offset_cl_enable(bits, mask);
+//}
+
+void
+msdd_source_base::set_verbose (bool verbose)
+{  
+  pimpl->d_verbose = verbose;
+}
+//
+//bool
+//msdd_source_base::write_aux_dac (int which_dboard, int which_dac, int value)
+//{
+//  return d_usrp->write_aux_dac (which_dboard, which_dac, value);
+//}
+//
+//int
+//msdd_source_base::read_aux_adc (int which_dboard, int which_adc)
+//{
+//  return d_usrp->read_aux_adc (which_dboard, which_adc);
+//}
+//
+//bool
+//msdd_source_base::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
+//{
+//  return d_usrp->write_eeprom (i2c_addr, eeprom_offset, buf);
+//}
+//
+//std::string
+//msdd_source_base::read_eeprom (int i2c_addr, int eeprom_offset, int len)
+//{
+//  return d_usrp->read_eeprom (i2c_addr, eeprom_offset, len);
+//}
+//
+//bool
+//msdd_source_base::write_i2c (int i2c_addr, const std::string buf)
+//{
+//  return d_usrp->write_i2c (i2c_addr, buf);
+//}
+//
+//std::string
+//msdd_source_base::read_i2c (int i2c_addr, int len)
+//{
+//  return d_usrp->read_i2c (i2c_addr, len);
+//}
+//
+bool
+msdd_source_base::set_pga (int which, double gain)
+{
+  if (gain >= PGA_MIN & gain <= PGA_MAX) {
+    pimpl->d_gain = gain;
+    return true;
+  }
+  return false;
+}
+
+double
+msdd_source_base::pga (int which) const
+{
+  return pimpl->d_gain;
+}
+
+double
+msdd_source_base::pga_min () const
+{
+  return PGA_MIN;
+}
+
+double
+msdd_source_base::pga_max () const
+{
+  return PGA_MAX;
+}
+
+double
+msdd_source_base::pga_db_per_step () const
+{
+  return PGA_STEP;
+}
+
+//int
+//msdd_source_base::daughterboard_id (int which) const
+//{
+//  return d_usrp->daughterboard_id (which);
+//}
+//
+//
+//bool
+//msdd_source_base::set_adc_offset (int which, int offset)
+//{
+//  return d_usrp->set_adc_offset (which, offset);
+//}
+//
+//bool
+//msdd_source_base::set_dac_offset (int which, int offset, int offset_pin)
+//{
+//  return d_usrp->set_dac_offset (which, offset, offset_pin);
+//}
+//
+//bool
+//msdd_source_base::set_adc_buffer_bypass (int which, bool bypass)
+//{
+//  return d_usrp->set_adc_buffer_bypass (which, bypass);
+//}
+
+std::string
+msdd_source_base::serial_number()
+{
+  return "SoftTronics MSDD 6000";
+}
+//
+//bool
+//msdd_source_base::_write_oe (int which_dboard, int value, int mask)
+//{
+//  return d_usrp->_write_oe (which_dboard, value, mask);
+//}
+//
+//bool
+//msdd_source_base::write_io (int which_dboard, int value, int mask)
+//{
+//  return d_usrp->write_io (which_dboard, value, mask);
+//}
+//
+//int
+//msdd_source_base::read_io (int which_dboard)
+//{
+//  return d_usrp->read_io (which_dboard);
+//}
+//
+//
+//
+//
+//// internal routines...
+//
+//bool
+//msdd_source_base::_write_fpga_reg (int regno, int value)
+//{
+//  return d_usrp->_write_fpga_reg (regno, value);
+//}
+//
+//bool
+//msdd_source_base::_write_fpga_reg_masked (int regno, int value, int mask)
+//{
+//  return d_usrp->_write_fpga_reg_masked (regno, value, mask);
+//}
+//
+//int
+//msdd_source_base::_read_fpga_reg (int regno)
+//{
+//  return d_usrp->_read_fpga_reg (regno);
+//}
+//
+//bool
+//msdd_source_base::_write_9862 (int which_codec, int regno, unsigned char value)
+//{
+//  return d_usrp->_write_9862 (which_codec, regno, value);
+//}
+//
+//int
+//msdd_source_base::_read_9862 (int which_codec, int regno) const
+//{
+//  return d_usrp->_read_9862 (which_codec, regno);
+//}
+//
+//bool
+//msdd_source_base::_write_spi (int optional_header, int enables,
+//                            int format, std::string buf)
+//{
+//  return d_usrp->_write_spi (optional_header, enables, format, buf);
+//}
+//
+//std::string
+//msdd_source_base::_read_spi (int optional_header, int enables, int format, int len)
+//{
+//  return d_usrp->_read_spi (optional_header, enables, format, len);
+//}
+//
+//bool
+//msdd_source_base::set_format(unsigned int format)
+//{
+//  return d_usrp->set_format(format);
+//}
+//
+//unsigned int
+//msdd_source_base::format() const
+//{
+//  return d_usrp->format();
+//}
+//
+//unsigned int
+//msdd_source_base::make_format(int width, int shift, bool want_q, bool bypass_halfband)
+//{
+//  return usrp_standard_rx::make_format(width, shift, want_q, bypass_halfband);
+//}
+//
+//int
+//msdd_source_base::format_width(unsigned int format)
+//{
+//  return usrp_standard_rx::format_width(format);
+//}
+//
+//int
+//msdd_source_base::format_shift(unsigned int format)
+//{
+//  return usrp_standard_rx::format_shift(format);
+//}
+//
+//bool
+//msdd_source_base::format_want_q(unsigned int format)
+//{
+//  return usrp_standard_rx::format_want_q(format);
+//}
+//
+//bool
+//msdd_source_base::format_bypass_halfband(unsigned int format)
+//{
+//  return usrp_standard_rx::format_bypass_halfband(format);
+//}
+
+bool msdd_source_base::set_desired_packet_size (int which, unsigned long packet_size) {
+  bool result(false);
+  
+  if (pimpl->d_desired_sample_size < 2^32) { // FIXME: find maximum sample request for MSDD check if greater than 
+    pimpl->d_desired_sample_size = packet_size;
+  }
+  return result;
+}
+
+unsigned long msdd_source_base::desired_packet_size (int which) const {
+  return pimpl->d_desired_sample_size;
+}
diff --git a/gr-msdd6000/src/lib/msdd_source_base.h b/gr-msdd6000/src/lib/msdd_source_base.h
new file mode 100644 (file)
index 0000000..4a5bde1
--- /dev/null
@@ -0,0 +1,307 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MSDD_SOURCE_BASE_H
+#define INCLUDED_MSDD_SOURCE_BASE_H
+#include <gr_sync_block.h>
+#include <stdexcept>
+
+/*!
+ * \brief abstract interface to MSDD 6000 Softronics module Rx path (Rev 1)
+ */
+
+class msdd_source_base : public gr_sync_block {
+public: 
+  enum msdd_command_type_t {
+    COMMAND_STATUS = 0,
+    SAMPLES_REALTIME = 1,
+    SAMPLES_FFT = 2,
+  };
+  
+  enum msdd_fft_window_type_t {
+    WINDOW_RECTANGLE = 0,
+    WINDOW_HANNING = 1,
+    WINDOW_HAMMING = 2,
+    WINDOW_BLACKMAN = 3
+  };
+  
+  enum msdd_fft_mode_t {
+    MODE_IQ=0, 
+    MODE_MAG=1, 
+    MODE_MAGDB=2
+  };
+  
+  enum msdd_decimation_t {
+    D0=0, 
+    D1=1, 
+    D2=2, 
+    D3=3, 
+    D4=4, 
+    D5=5, 
+    D6=6, 
+    D7=7, 
+    D8=8
+  };    
+  
+  enum msdd_fft_points_t {
+    S256=8, 
+    S512=9, 
+    S1024=10, 
+    S2048=11, 
+    S4096=12, 
+    S8192=13, 
+    S16384=14, 
+    S32768=15
+  };
+  
+private:
+   
+  class Impl;
+  friend class Impl;
+  std::auto_ptr<Impl> pimpl;
+
+protected:
+   
+  msdd_source_base (const std::string &name,
+                   gr_io_signature_sptr output_signature,
+                   int which_board,
+                   int opp_mode,
+                   const char *src, 
+                   unsigned short port_src
+                   ) throw (std::runtime_error);
+
+  /*!
+   * \brief return number of msdd input bytes required to produce noutput items.
+   */
+  virtual int ninput_bytes_reqd_for_noutput_items (int noutput_items) = 0;
+
+  /*!
+   * \brief number of bytes in a low-level sample
+   */
+  unsigned int sizeof_basic_sample() const;
+
+  virtual void copy_from_msdd_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *msdd_buffer,
+                                     int msdd_buffer_length,
+                                     int &bytes_read) = 0;
+  
+  int readsock(int sockfd, unsigned char* buf, int nbytes);
+  
+  void* make_request_packet(unsigned int& size, unsigned int number_samples);
+  
+  unsigned long set_fft_size (int channel, unsigned long fft_size);
+  
+public:
+  //! magic value used on alternate register read interfaces
+  static const int READ_FAILED = -99999;
+  
+  ~msdd_source_base ();
+
+  int work (int noutput_items,
+           gr_vector_const_void_star &input_items,
+           gr_vector_void_star &output_items);
+  
+  bool start();
+  bool stop();
+
+  /*!
+   * \brief open a socket specified by the port and ip address info
+   *
+   * Opens a socket, binds to the address, and waits for a connection
+   * over UDP. If any of these fail, the fuction retuns the error and exits.
+   */
+  bool open();
+
+  /*!
+   * \brief Close current socket.
+   *
+   * Shuts down read/write on the socket
+   */
+  bool close();
+  
+  /*!
+   * \brief Set decimator rate.  \p rate must be EVEN and in [8, 256].
+   *
+   * The final complex sample rate across the USB is
+   *   adc_freq () / decim_rate ()
+   */
+  bool set_decim_rate (unsigned int rate);
+  //bool set_nchannels (int nchan);
+  //bool set_mux (int mux);
+
+  /*!
+   * \brief set the center frequency of the digital down converter.
+   *
+   * \p channel must be 0.  \p freq is the center frequency in Hz.
+   * It must be in the range [-FIXME, FIXME].  The frequency specified is
+   * quantized.  Use rx_freq to retrieve the actual value used.
+   */
+  bool set_rx_freq (int channel, double freq);
+
+  /*!
+   * \brief
+   */
+  bool set_opp_mode (int channel, msdd_command_type_t mode);
+  
+//
+//  /*!
+//   * \brief set fpga special modes
+//   */
+//  bool set_fpga_mode (int mode);
+
+  void set_verbose (bool verbose);
+//
+//  /*!
+//   * \brief Set the digital down converter phase register.
+//   *
+//   * \param channel  which ddc channel [0, 3]
+//   * \param phase    32-bit integer phase value.
+//   */
+//  bool set_ddc_phase(int channel, int phase);
+//
+  /*!
+   * \brief Set Programmable Gain Amplifier (PGA)
+   *
+   * \param which      which A/D [0,3]
+   * \param gain_in_db gain value (linear in dB)
+   *
+   * gain is rounded to closest setting supported by hardware.
+   *
+   * \returns true iff sucessful.
+   *
+   * \sa pga_min(), pga_max(), pga_db_per_step()
+   */
+  bool set_pga (int which, double gain_in_db);
+
+  /*!
+   * \brief Return programmable gain amplifier gain setting in dB.
+   *
+   * \param which      which A/D [0,3]
+   */
+  double pga (int which) const;
+
+  /*!
+   * \brief Return minimum legal PGA setting in dB.
+   */
+  double pga_min () const;
+
+  /*!
+   * \brief Return maximum legal PGA setting in dB.
+   */
+  double pga_max () const;
+
+  /*!
+   * \brief Return hardware step size of PGA (linear in dB).
+   */
+  double pga_db_per_step () const;
+
+  // ACCESSORS
+
+//  long converter_rate() const;
+
+  unsigned int decim_rate () const;
+//  int nchannels () const;
+//  int mux () const;
+  double rx_freq (int channel) const;
+  unsigned int fft_points() const;
+  int noverruns () const;
+
+  /*!
+   * \brief return the msdd's serial number.
+   *
+   * \returns non-zero length string iff successful.
+   */
+  std::string serial_number();
+
+//  /*!
+//   * \brief Enable/disable automatic DC offset removal control loop in FPGA
+//   *
+//   * \param bits  which control loops to enable
+//   * \param mask  which \p bits to pay attention to
+//   *
+//   * If the corresponding bit is set, enable the automatic DC
+//   * offset correction control loop.
+//   *
+//   * <pre>
+//   * The 4 low bits are significant:
+//   *
+//   *   ADC0 = (1 << 0)
+//   *   ADC1 = (1 << 1)
+//   *   ADC2 = (1 << 2)
+//   *   ADC3 = (1 << 3)
+//   * </pre>
+//   *
+//   * By default the control loop is enabled on all ADC's.
+//   */
+//  bool set_dc_offset_cl_enable(int bits, int mask);
+
+  /*!
+   * \brief Specify Rx data format.
+   *
+   * \param format     format specifier
+   *
+   * Rx data format control register
+   *
+   *     3                   2                   1                       
+   *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   *  +-----------------------------------------+-+-+---------+-------+
+   *  |          Reserved (Must be zero)        |B|Q|  WIDTH  | SHIFT |
+   *  +-----------------------------------------+-+-+---------+-------+
+   *
+   *  SHIFT specifies arithmetic right shift [0, 15]
+   *  WIDTH specifies bit-width of I & Q samples across the USB [1, 16] (not all valid)
+   *  Q     if set deliver both I & Q, else just I
+   *  B     if set bypass half-band filter.
+   *
+   * Right now the acceptable values are:
+   *
+   *   B  Q  WIDTH  SHIFT
+   *   0  1    16     0
+   *   0  1     8     8
+   *
+   * More valid combos to come.
+   *
+   * Default value is 0x00000300  16-bits, 0 shift, deliver both I & Q.
+   */
+//  bool set_format(unsigned int format);
+
+  /*!
+   * \brief return current format
+   */
+//  unsigned int format () const;
+//
+//  static unsigned int make_format(int width=16, int shift=0,
+//                               bool want_q=true, bool bypass_halfband=false);
+//  static int format_width(unsigned int format);
+//  static int format_shift(unsigned int format);
+//  static bool format_want_q(unsigned int format);
+//  static bool format_bypass_halfband(unsigned int format);
+
+    bool set_desired_packet_size (int which, unsigned long packet_size);
+
+    unsigned long desired_packet_size (int which) const;
+};
+
+#endif /* INCLUDED_MSDD_SOURCE_BASE_H */
diff --git a/gr-msdd6000/src/lib/msdd_source_c.cc b/gr-msdd6000/src/lib/msdd_source_c.cc
new file mode 100644 (file)
index 0000000..454d9d4
--- /dev/null
@@ -0,0 +1,111 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+//#define MSDD_DEBUG2_TRUE
+
+#ifdef MSDD_DEBUG2_TRUE
+#include <iostream>
+#define MSDD_DEBUG2(x) std::cout << x << std::endl;
+#else
+#define MSDD_DEBUG2(x)
+#endif
+
+#include <msdd_source_c.h>
+#include <gr_io_signature.h>
+
+namespace {
+  static const int NBASIC_SAMPLES_PER_ITEM = 2;        // I & Q
+};
+
+msdd_source_c_sptr
+msdd_make_source_c (int which_board, 
+                   int opp_mode,
+                   const char *src, 
+                   unsigned short port_src
+                   ) throw (std::runtime_error)
+{
+  return msdd_source_c_sptr (new msdd_source_c (
+                                               which_board,
+                                               opp_mode,
+                                               src,
+                                               port_src
+                                               ));
+}
+
+msdd_source_c::msdd_source_c (int which_board,
+                             int opp_mode,
+                             const char *src, 
+                             unsigned short port_src
+                             ) throw (std::runtime_error)
+  : msdd_source_base ("msdd_source_c",
+                     gr_make_io_signature (1, 1, 2 * sizeof (int)),
+                     which_board, opp_mode, src, port_src
+                     )
+{
+
+  switch (sizeof_basic_sample()) {     
+  case 4:
+         d_buffer_copy_behavior.reset(
+          new msdd::BufferCopyBehaviorComplex <short> ());
+    break;
+  default:
+    assert(false);    
+  }                              
+  
+}
+
+msdd_source_c::~msdd_source_c ()
+{
+}
+
+int
+msdd_source_c::ninput_bytes_reqd_for_noutput_items (int noutput_items)
+{
+  return noutput_items * NBASIC_SAMPLES_PER_ITEM * sizeof_basic_sample();
+}
+
+/*
+ * Copy 8 bit fft from mdss buffer into output buffer
+ */
+void
+msdd_source_c::copy_from_msdd_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *msdd_buffer,
+                                     int buffer_length,
+                                     int &bytes_read)
+{
+  unsigned nmsdd_bytes_per_item = NBASIC_SAMPLES_PER_ITEM * sizeof_basic_sample();
+  
+  unsigned int nitems = std::min (output_items_available,
+                                 (int)(buffer_length / nmsdd_bytes_per_item));
+  
+  (*d_buffer_copy_behavior.get())(output_items, msdd_buffer, output_index, nitems);
+  
+  output_items_produced = nitems;
+  bytes_read = nitems * nmsdd_bytes_per_item;
+}
diff --git a/gr-msdd6000/src/lib/msdd_source_c.h b/gr-msdd6000/src/lib/msdd_source_c.h
new file mode 100644 (file)
index 0000000..11aafbb
--- /dev/null
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MSDD_SOURCE_C_H
+#define INCLUDED_MSDD_SOURCE_C_H
+
+#include <msdd_source_base.h>
+#include <msdd_buffer_copy_behaviors.h>
+#include <stdexcept>
+
+class msdd_source_c;
+typedef boost::shared_ptr<msdd_source_c> msdd_source_c_sptr;
+
+// public shared_ptr constructor
+
+msdd_source_c_sptr
+msdd_make_source_c (int which_board, 
+                   int opp_mode,
+                   const char *src, 
+                   unsigned short port_src
+                   ) throw (std::runtime_error);
+
+/*!
+ * \brief interface to MSDD Rx path
+ *
+ * output: 1 stream of short
+ */
+class msdd_source_c : public msdd_source_base {
+private:
+  friend msdd_source_c_sptr
+  msdd_make_source_c (int which_board, 
+                     int opp_mode,
+                     const char *src, 
+                     unsigned short port_src
+                     ) throw (std::runtime_error);
+
+  std::auto_ptr<msdd::BufferCopyBehavior> d_buffer_copy_behavior;
+
+protected:
+  msdd_source_c (int which_board, 
+                int opp_mode,
+                const char *src, 
+                unsigned short port_src
+                ) throw (std::runtime_error);
+
+  int ninput_bytes_reqd_for_noutput_items (int noutput_items);
+
+  virtual void copy_from_msdd_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *msdd_buffer,
+                                     int buffer_length,
+                                     int &bytes_read);
+
+public:
+  ~msdd_source_c ();
+};
+
+#endif /* INCLUDED_MSDD_SOURCE_C_H */
diff --git a/gr-msdd6000/src/lib/msdd_source_s.cc b/gr-msdd6000/src/lib/msdd_source_s.cc
new file mode 100644 (file)
index 0000000..6a21808
--- /dev/null
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define MSDD_DEBUG2_TRUE
+
+#ifdef MSDD_DEBUG2_TRUE
+#include <iostream>
+#define MSDD_DEBUG2(x) std::cout << x << std::endl;
+#else
+#define MSDD_DEBUG2(x)
+#endif
+
+#include <msdd_source_s.h>
+#include <gr_io_signature.h>
+
+namespace {
+  static const int NBASIC_SAMPLES_PER_ITEM = 1;
+}
+
+msdd_source_s_sptr
+msdd_make_source_s (int which_board, 
+                   unsigned int decim_rate,
+                   unsigned int fft_points,
+                   double initial_rx_freq,
+                   int opp_mode,
+                   const char *src, 
+                   unsigned short port_src
+                   ) throw (std::runtime_error)
+{
+  return msdd_source_s_sptr (new msdd_source_s (which_board,
+                                               decim_rate,
+                                               fft_points,
+                                               initial_rx_freq,
+                                               opp_mode,
+                                               src,
+                                               port_src
+                                               ));
+}
+
+
+msdd_source_s::msdd_source_s (int which_board,
+                             unsigned int decim_rate,
+                             unsigned int fft_points,
+                             double initial_rx_freq,
+                             int opp_mode,
+                             const char *src, 
+                             unsigned short port_src
+                             ) throw (std::runtime_error)
+  : msdd_source_base ("msdd_source_s",
+                     gr_make_io_signature (1, 1, sizeof (int)),
+                     which_board, opp_mode, src, port_src
+                     )
+{
+
+  switch (sizeof_basic_sample()) {
+  case 1:
+       d_buffer_copy_behavior.reset(
+        new msdd::BufferCopyBehaviorGeneric<short, unsigned char>());
+    break;
+  case 2:
+       d_buffer_copy_behavior.reset(
+               new msdd::BufferCopyBehaviorGeneric<short, float>());
+    break;
+  case 4:
+       d_buffer_copy_behavior.reset(
+               new msdd::BufferCopyBehaviorGeneric<short, int>());
+    break;
+  default:
+       assert(false);
+  }
+
+}
+
+msdd_source_s::~msdd_source_s ()
+{
+}
+
+int
+msdd_source_s::ninput_bytes_reqd_for_noutput_items (int noutput_items)
+{
+  return noutput_items * NBASIC_SAMPLES_PER_ITEM * sizeof_basic_sample();
+}
+
+void
+msdd_source_s::copy_from_msdd_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *msdd_buffer,
+                                     int buffer_length,
+                                     int &bytes_read)
+{
+  MSDD_DEBUG2("copy_from_msdd_buffer: output_index: " << output_index << " output_items_available: " << output_items_available << " buflen: " << buffer_length)
+
+   unsigned nmsdd_bytes_per_item 
+    (msdd_source_s::ninput_bytes_reqd_for_noutput_items(1));
+  
+  unsigned int nitems = std::min (output_items_available,
+                                 (int)(buffer_length / nmsdd_bytes_per_item));
+  
+  MSDD_DEBUG2("copy_from_msdd_buffer: nmsdd_bytes_per_item: " << nmsdd_bytes_per_item << " nitems: " << nitems)
+
+  (*d_buffer_copy_behavior.get())(output_items, msdd_buffer, output_index, nitems);
+
+  output_items_produced = nitems;
+  bytes_read = nitems * nmsdd_bytes_per_item;
+}
diff --git a/gr-msdd6000/src/lib/msdd_source_s.h b/gr-msdd6000/src/lib/msdd_source_s.h
new file mode 100644 (file)
index 0000000..e32f8ae
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_MSDD_SOURCE_S_H
+#define INCLUDED_MSDD_SOURCE_S_H
+
+#include <msdd_source_base.h>
+#include <msdd_buffer_copy_behaviors.h>
+#include <stdexcept>
+
+class msdd_source_s;
+typedef boost::shared_ptr<msdd_source_s> msdd_source_s_sptr;
+
+// public shared_ptr constructor
+
+msdd_source_s_sptr
+msdd_make_source_s (int which_board, 
+                   unsigned int decim_rate,
+                   unsigned int fft_points,
+                   double initial_rx_freq,
+                   int opp_mode,
+                   const char *src, 
+                   unsigned short port_src
+                   ) throw (std::runtime_error);
+
+/*!
+ * \brief interface to MSDD Rx path
+ *
+ * output: 1 stream of short
+ */
+class msdd_source_s : public msdd_source_base {
+private:
+  friend msdd_source_s_sptr
+  msdd_make_source_s (int which_board, 
+                     unsigned int decim_rate,
+                     unsigned int fft_points,
+                     double initial_rx_freq,
+                     int opp_mode,
+                     const char *src, 
+                     unsigned short port_src
+                     ) throw (std::runtime_error);
+
+  std::auto_ptr<msdd::BufferCopyBehavior> d_buffer_copy_behavior;
+  
+protected:
+  msdd_source_s (int which_board, 
+                unsigned int decim_rate,
+                unsigned int fft_points,
+                double initial_rx_freq,
+                int opp_mode,
+                const char *src, 
+                unsigned short port_src
+                ) throw (std::runtime_error);
+
+  int ninput_bytes_reqd_for_noutput_items (int noutput_items);
+
+  virtual void copy_from_msdd_buffer (gr_vector_void_star &output_items,
+                                     int output_index,
+                                     int output_items_available,
+                                     int &output_items_produced,
+                                     const void *msdd_buffer,
+                                     int buffer_length,
+                                     int &bytes_read);
+public:
+  ~msdd_source_s ();
+};
+
+#endif /* INCLUDED_MSDD_SOURCE_S_H */
diff --git a/gr-msdd6000/src/python/Makefile.am b/gr-msdd6000/src/python/Makefile.am
new file mode 100644 (file)
index 0000000..38040eb
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+EXAMPLE_FILES =
+
+EXTRA_DIST = run_tests.in \
+            $(EXAMPLE_FILES)
+
+ourdatadir = $(exampledir)/msdd6000
+ourdata_DATA = $(EXAMPLE_FILES)
+
+noinst_PYTHON =                        \
+       qa_msdd6000.py                  \
+       test_udp.py                     \
+       test_tcp.py
+
+TESTS =                                \
+       run_tests
+
+
+# Make example scripts with #! executable
+install-data-local: install-ourdataDATA
+       for i in `find $(ourdatadir) -type f ! -perm 755`; do \
+         if head -1 $$i | grep -q '^#!'; then \
+           chmod 755 $$i; \
+           echo "made executable: $$i"; \
+         fi; \
+       done
diff --git a/gr-msdd6000/src/python/qa_msdd6000.py b/gr-msdd6000/src/python/qa_msdd6000.py
new file mode 100755 (executable)
index 0000000..fdcf7e8
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+import msdd
+
+class qa_usrp (gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_000_nop (self):
+        """Just see if we can import the module...
+       """
+        pass
+    
+if __name__ == '__main__':
+    gr_unittest.main ()
diff --git a/gr-msdd6000/src/python/run_tests.in b/gr-msdd6000/src/python/run_tests.in
new file mode 100644 (file)
index 0000000..28e4c73
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# 1st parameter is absolute path to component source directory
+# 2nd parameter is absolute path to component build directory
+# 3rd parameter is path to Python QA directory
+
+@top_builddir@/run_tests.sh \
+    @abs_top_srcdir@/gr-msdd6000 \
+    @abs_top_builddir@/gr-msdd6000 \
+    @srcdir@
diff --git a/gr-msdd6000/src/python/test_tcp.py b/gr-msdd6000/src/python/test_tcp.py
new file mode 100755 (executable)
index 0000000..b02db81
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+
+myport = random.randint(1025,65535);
+
+port = 10000
+host = "10.45.4.43"
+myaddr = ("10.45.1.229",myport);
+
+buf = 100000;
+
+TCPSock = socket(AF_INET,SOCK_STREAM);
+#TCPSock = socket(AF_INET,SOCK_DGRAM);
+TCPSock.bind(myaddr);
+TCPSock.connect((host,port));
+
+f_mhz = 2400;  
+f_hz = 0;      
+gain = 2;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+#samples = 0xffffffff;         #8-15   fft:(returns 2^number[8-15]) raw:(returns number)
+samples = 2;   #8-15   fft:(returns 2^number[8-15]) raw:(returns number)
+decim = 2;     #0-8  
+#decim = decim+16;     # +16 to use 16bit instead of 32 bit 
+mode = 1;      #0=IQ, 1=MAG, 2=MAGDB
+sets = 0xffffffff;     
+#sets = 1;
+
+fft_data = struct.pack("<IIIIIIIIII", 0x02, 0x20, f_mhz, f_hz, gain,window, samples, decim, mode,sets);
+raw_data = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+stat_data = struct.pack("!II", 0x0000, 0x0000)
+
+data = raw_data;
+
+#TCPSock.sendto(data, (host,port))
+TCPSock.send(data);
+
+print "sent"
+
+
+
+count = 0;
+while(1):
+       data,addr = TCPSock.recvfrom(buf);
+       
+       print "got response"
+       
+       print "Data length: %d bytes."%(len(data));
+       if(len(data)==12):
+               a,b,c = struct.unpack("!III",data);
+               print "%x,%x,%x"%(a,b,c);
+
+       datavector = [];
+
+       for d in data:
+               a = struct.unpack("<b",d);
+               datavector.append(a);
+
+       print datavector;
+               
+       count = count + 1;
+       
+       if(count > 1):
+               sets = 3;
+               raw_data_2 = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+               TCPSock.send(raw_data_2);
+               
+               
+               
+TCPSock.close();
+
+
+
diff --git a/gr-msdd6000/src/python/test_udp.py b/gr-msdd6000/src/python/test_udp.py
new file mode 100755 (executable)
index 0000000..da5c39d
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+
+
+port = 10001
+host = "10.45.4.43"
+
+myaddr = ("10.45.1.229",10000);
+
+buf = 1024;
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(myaddr);
+
+f_mhz = 2400;
+f_hz = 1;
+gain = 3;
+samples = 512;
+decim = 2;
+sets = 16;
+
+
+req_data = struct.pack("<IIIIIIIIII", 0x0001, 0x0002, f_mhz, f_hz, gain, samples, decim, sets);
+data = struct.pack("<II", 0x0000, 0x0000);
+
+
+
+UDPSock.sendto(stat_data, (host,port))
+
+
+print "sent"
+
+data,addr = UDPSock.recvfrom(buf);
+print "got response"
+
+
diff --git a/gr-msdd6000/src/python_test/test_tcp.py b/gr-msdd6000/src/python_test/test_tcp.py
new file mode 100755 (executable)
index 0000000..b02db81
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+import random;
+
+myport = random.randint(1025,65535);
+
+port = 10000
+host = "10.45.4.43"
+myaddr = ("10.45.1.229",myport);
+
+buf = 100000;
+
+TCPSock = socket(AF_INET,SOCK_STREAM);
+#TCPSock = socket(AF_INET,SOCK_DGRAM);
+TCPSock.bind(myaddr);
+TCPSock.connect((host,port));
+
+f_mhz = 2400;  
+f_hz = 0;      
+gain = 2;      
+window = 3;    #0=rect, 1=hanning, 2=hamming, 3=blackman
+#samples = 0xffffffff;         #8-15   fft:(returns 2^number[8-15]) raw:(returns number)
+samples = 2;   #8-15   fft:(returns 2^number[8-15]) raw:(returns number)
+decim = 2;     #0-8  
+#decim = decim+16;     # +16 to use 16bit instead of 32 bit 
+mode = 1;      #0=IQ, 1=MAG, 2=MAGDB
+sets = 0xffffffff;     
+#sets = 1;
+
+fft_data = struct.pack("<IIIIIIIIII", 0x02, 0x20, f_mhz, f_hz, gain,window, samples, decim, mode,sets);
+raw_data = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+stat_data = struct.pack("!II", 0x0000, 0x0000)
+
+data = raw_data;
+
+#TCPSock.sendto(data, (host,port))
+TCPSock.send(data);
+
+print "sent"
+
+
+
+count = 0;
+while(1):
+       data,addr = TCPSock.recvfrom(buf);
+       
+       print "got response"
+       
+       print "Data length: %d bytes."%(len(data));
+       if(len(data)==12):
+               a,b,c = struct.unpack("!III",data);
+               print "%x,%x,%x"%(a,b,c);
+
+       datavector = [];
+
+       for d in data:
+               a = struct.unpack("<b",d);
+               datavector.append(a);
+
+       print datavector;
+               
+       count = count + 1;
+       
+       if(count > 1):
+               sets = 3;
+               raw_data_2 = struct.pack("<IIIIIIII", 0x01, 0x18, f_mhz, f_hz, gain,samples, decim,sets);
+               TCPSock.send(raw_data_2);
+               
+               
+               
+TCPSock.close();
+
+
+
diff --git a/gr-msdd6000/src/python_test/test_udp.py b/gr-msdd6000/src/python_test/test_udp.py
new file mode 100755 (executable)
index 0000000..da5c39d
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+
+from socket import *
+import string
+import time
+import struct;
+
+
+port = 10001
+host = "10.45.4.43"
+
+myaddr = ("10.45.1.229",10000);
+
+buf = 1024;
+
+UDPSock = socket(AF_INET,SOCK_DGRAM);
+UDPSock.bind(myaddr);
+
+f_mhz = 2400;
+f_hz = 1;
+gain = 3;
+samples = 512;
+decim = 2;
+sets = 16;
+
+
+req_data = struct.pack("<IIIIIIIIII", 0x0001, 0x0002, f_mhz, f_hz, gain, samples, decim, sets);
+data = struct.pack("<II", 0x0000, 0x0000);
+
+
+
+UDPSock.sendto(stat_data, (host,port))
+
+
+print "sent"
+
+data,addr = UDPSock.recvfrom(buf);
+print "got response"
+
+