summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/io
diff options
context:
space:
mode:
authorManoj Gudi2013-10-07 20:19:55 +0530
committerManoj Gudi2013-10-07 20:20:35 +0530
commit1826d0763c8595997f5f4af1fdb0354e9c0998ad (patch)
treeacbd852cd5a1bf17241b1038b5e37a0e72e64612 /gnuradio-core/src/lib/io
parent452defdb4a78e9e826740ddf4b9673e926c568a4 (diff)
parent24b640997ba7fee0c725e65f401f5cbebdab8d08 (diff)
downloadgnuradio-1826d0763c8595997f5f4af1fdb0354e9c0998ad.tar.gz
gnuradio-1826d0763c8595997f5f4af1fdb0354e9c0998ad.tar.bz2
gnuradio-1826d0763c8595997f5f4af1fdb0354e9c0998ad.zip
README change
Diffstat (limited to 'gnuradio-core/src/lib/io')
-rw-r--r--gnuradio-core/src/lib/io/CMakeLists.txt118
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc87
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_sink.h59
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_sink.i35
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_source.cc151
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_source.h68
-rw-r--r--gnuradio-core/src/lib/io/gr_file_descriptor_source.i35
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.cc84
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.h58
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink.i45
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.cc125
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.h75
-rw-r--r--gnuradio-core/src/lib/io/gr_file_sink_base.i51
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.cc192
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.h107
-rw-r--r--gnuradio-core/src/lib/io/gr_file_source.i45
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink.i39
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink_f.cc165
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink_f.h71
-rw-r--r--gnuradio-core/src/lib/io/gr_message_burst_source.cc144
-rw-r--r--gnuradio-core/src/lib/io/gr_message_burst_source.h71
-rw-r--r--gnuradio-core/src/lib/io/gr_message_burst_source.i38
-rw-r--r--gnuradio-core/src/lib/io/gr_message_debug.cc120
-rw-r--r--gnuradio-core/src/lib/io/gr_message_debug.h114
-rw-r--r--gnuradio-core/src/lib/io/gr_message_debug.i30
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.cc79
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.h63
-rw-r--r--gnuradio-core/src/lib/io/gr_message_sink.i36
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.cc120
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.h69
-rw-r--r--gnuradio-core/src/lib/io/gr_message_source.i38
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_guts.cc437
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_guts.h123
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink.i77
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_f.cc78
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_f.h63
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_x.cc156
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_x.h77
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu.cc79
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu.h39
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu.i30
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc132
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h63
-rw-r--r--gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i31
-rw-r--r--gnuradio-core/src/lib/io/gr_socket_pdu.cc157
-rw-r--r--gnuradio-core/src/lib/io/gr_socket_pdu.h203
-rw-r--r--gnuradio-core/src/lib/io/gr_socket_pdu.i33
-rw-r--r--gnuradio-core/src/lib/io/gr_stream_pdu_base.cc123
-rw-r--r--gnuradio-core/src/lib/io/gr_stream_pdu_base.h59
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_file_sink.cc216
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_file_sink.h72
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_file_sink.i35
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc137
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h76
-rw-r--r--gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i31
-rw-r--r--gnuradio-core/src/lib/io/gr_trigger_mode.h38
-rw-r--r--gnuradio-core/src/lib/io/gr_tuntap_pdu.cc145
-rw-r--r--gnuradio-core/src/lib/io/gr_tuntap_pdu.h74
-rw-r--r--gnuradio-core/src/lib/io/gr_tuntap_pdu.i30
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_sink.cc304
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_sink.h112
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_sink.i46
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_source.cc374
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_source.h110
-rw-r--r--gnuradio-core/src/lib/io/gr_udp_source.i41
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_sink.cc280
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_sink.h138
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_sink.i47
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_source.cc171
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_source.h95
-rw-r--r--gnuradio-core/src/lib/io/gr_wavfile_source.i42
-rw-r--r--gnuradio-core/src/lib/io/gri_wavfile.cc251
-rw-r--r--gnuradio-core/src/lib/io/gri_wavfile.h96
-rw-r--r--gnuradio-core/src/lib/io/i2c.cc28
-rw-r--r--gnuradio-core/src/lib/io/i2c.h49
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio.cc29
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio.h51
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio_pp.cc87
-rw-r--r--gnuradio-core/src/lib/io/i2c_bbio_pp.h57
-rw-r--r--gnuradio-core/src/lib/io/i2c_bitbang.cc144
-rw-r--r--gnuradio-core/src/lib/io/i2c_bitbang.h65
-rw-r--r--gnuradio-core/src/lib/io/io.i83
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702.cc183
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702.h71
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702_eval_board.cc88
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702_eval_board.h49
-rw-r--r--gnuradio-core/src/lib/io/microtune_4702_eval_board.i36
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937.cc146
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937.h68
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937_eval_board.cc97
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937_eval_board.h50
-rw-r--r--gnuradio-core/src/lib/io/microtune_4937_eval_board.i36
-rw-r--r--gnuradio-core/src/lib/io/microtune_eval_board.i95
-rw-r--r--gnuradio-core/src/lib/io/microtune_eval_board_defs.h71
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx.cc41
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx.h66
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc144
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h98
-rw-r--r--gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i58
-rw-r--r--gnuradio-core/src/lib/io/ppio.cc39
-rw-r--r--gnuradio-core/src/lib/io/ppio.h63
-rw-r--r--gnuradio-core/src/lib/io/ppio.i48
-rw-r--r--gnuradio-core/src/lib/io/ppio_ppdev.cc321
-rw-r--r--gnuradio-core/src/lib/io/ppio_ppdev.h62
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.cc65
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.h53
-rw-r--r--gnuradio-core/src/lib/io/sdr_1000.i36
107 files changed, 10130 insertions, 0 deletions
diff --git a/gnuradio-core/src/lib/io/CMakeLists.txt b/gnuradio-core/src/lib/io/CMakeLists.txt
new file mode 100644
index 000000000..59ca06b5a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/CMakeLists.txt
@@ -0,0 +1,118 @@
+# Copyright 2010-2011 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.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+########################################################################
+# Append gnuradio-core library sources
+########################################################################
+list(APPEND gnuradio_core_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_histo_sink_f.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_guts.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink_f.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink_x.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bitbang.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bbio.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bbio_pp.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_4702.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_4937.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_xxxx.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/ppio_ppdev.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_wavfile.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_pdu.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_stream_pdu_base.cc
+)
+
+########################################################################
+# Install runtime headers
+########################################################################
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_histo_sink_f.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_guts.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink_f.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink_x.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_trigger_mode.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bitbang.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bbio.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/i2c_bbio_pp.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_4702.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_4937.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_eval_board_defs.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/microtune_xxxx.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/ppio_ppdev.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gri_wavfile.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_pdu.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_stream_pdu_base.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "core_devel"
+)
+
+########################################################################
+# Install swig headers
+########################################################################
+if(ENABLE_PYTHON)
+install(FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/io.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_histo_sink.i
+ ${CMAKE_CURRENT_SOURCE_DIR}/gr_oscope_sink.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "core_swig"
+)
+endif(ENABLE_PYTHON)
+
+########################################################################
+# Handle triple-threat files that have cc, h, and i
+########################################################################
+set(gr_core_io_triple_threats
+ gr_file_sink
+ gr_file_sink_base
+ gr_file_source
+ gr_file_descriptor_sink
+ gr_file_descriptor_source
+ gr_message_debug
+ gr_message_sink
+ gr_message_source
+ gr_message_burst_source
+ gr_pdu_to_tagged_stream
+ microtune_xxxx_eval_board
+ microtune_4702_eval_board
+ microtune_4937_eval_board
+ ppio
+ sdr_1000
+ gr_udp_sink
+ gr_udp_source
+ gr_wavfile_source
+ gr_wavfile_sink
+ gr_tagged_file_sink
+ gr_tagged_stream_to_pdu
+ gr_tuntap_pdu
+ gr_socket_pdu
+)
+
+foreach(file_tt ${gr_core_io_triple_threats})
+ list(APPEND gnuradio_core_sources ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.cc)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio COMPONENT "core_devel")
+ if(ENABLE_PYTHON)
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${file_tt}.i DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig COMPONENT "core_swig")
+ endif(ENABLE_PYTHON)
+endforeach(file_tt ${gr_core_io_triple_threats})
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc
new file mode 100644
index 000000000..099d46dbd
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 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
+
+#include <gr_file_descriptor_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <stdio.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+gr_file_descriptor_sink::gr_file_descriptor_sink (size_t itemsize, int fd)
+ : gr_sync_block ("file_descriptor_sink",
+ gr_make_io_signature (1, 1, itemsize),
+ gr_make_io_signature (0, 0, 0)),
+ d_itemsize (itemsize), d_fd (fd)
+{
+}
+
+gr_file_descriptor_sink_sptr
+gr_make_file_descriptor_sink (size_t itemsize, int fd)
+{
+ return gnuradio::get_initial_sptr(new gr_file_descriptor_sink (itemsize, fd));
+}
+
+gr_file_descriptor_sink::~gr_file_descriptor_sink ()
+{
+ close (d_fd);
+}
+
+int
+gr_file_descriptor_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *inbuf = (char *) input_items[0];
+ unsigned long byte_size = noutput_items * d_itemsize;
+
+ while (byte_size > 0){
+ ssize_t r;
+
+ r = write (d_fd, inbuf, byte_size);
+ if (r == -1){
+ if (errno == EINTR)
+ continue;
+ else {
+ perror ("gr_file_descriptor_sink");
+ return -1; // indicate we're done
+ }
+ }
+ else {
+ byte_size -= r;
+ inbuf += r;
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h
new file mode 100644
index 000000000..3b1c1167f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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_GR_FILE_DESCRIPTOR_SINK_H
+#define INCLUDED_GR_FILE_DESCRIPTOR_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_file_descriptor_sink;
+typedef boost::shared_ptr<gr_file_descriptor_sink> gr_file_descriptor_sink_sptr;
+
+GR_CORE_API gr_file_descriptor_sink_sptr gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+/*!
+ * \brief Write stream to file descriptor.
+ * \ingroup sink_blk
+ */
+
+class GR_CORE_API gr_file_descriptor_sink : public gr_sync_block
+{
+ friend GR_CORE_API gr_file_descriptor_sink_sptr gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+ private:
+ size_t d_itemsize;
+ int d_fd;
+
+ protected:
+ gr_file_descriptor_sink (size_t itemsize, int fd);
+
+ public:
+ ~gr_file_descriptor_sink ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_FILE_DESCRIPTOR_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.i b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.i
new file mode 100644
index 000000000..2c256e44d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_descriptor_sink)
+
+gr_file_descriptor_sink_sptr
+gr_make_file_descriptor_sink (size_t itemsize, int fd);
+
+class gr_file_descriptor_sink : public gr_sync_block
+{
+ protected:
+ gr_file_descriptor_sink (size_t itemsize, int fd);
+
+ public:
+ ~gr_file_descriptor_sink ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc b/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc
new file mode 100644
index 000000000..a63abf96b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 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
+
+#include <gr_file_descriptor_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+gr_file_descriptor_source::gr_file_descriptor_source (size_t itemsize,
+ int fd,
+ bool repeat)
+ : gr_sync_block ("file_descriptor_source",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, itemsize)),
+ d_itemsize (itemsize), d_fd (fd), d_repeat (repeat),
+ d_residue (new unsigned char[itemsize]), d_residue_len (0)
+{
+}
+
+// public constructor that returns a shared_ptr
+
+gr_file_descriptor_source_sptr
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat)
+{
+ return gr_file_descriptor_source_sptr (
+ new gr_file_descriptor_source (itemsize, fd, repeat));
+}
+
+gr_file_descriptor_source::~gr_file_descriptor_source ()
+{
+ close (d_fd);
+ delete [] d_residue;
+}
+
+int
+gr_file_descriptor_source::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (noutput_items > 0);
+
+ char *o = (char *) output_items[0];
+ int nread = 0;
+
+ while (1){
+ int r = read_items (o, noutput_items - nread);
+ if (r == -1){
+ if (errno == EINTR)
+ continue;
+ else {
+ perror ("file_descriptor_source[read]");
+ return -1;
+ }
+ }
+ else if (r == 0){ // end of file
+ if (!d_repeat)
+ break;
+ else {
+ flush_residue ();
+ if (lseek (d_fd, 0, SEEK_SET) == -1){
+ perror ("file_descriptor_source[lseek]");
+ return -1;
+ }
+ }
+ }
+ else {
+ o += r * d_itemsize;
+ nread += r;
+ break;
+ }
+ }
+
+ if (nread == 0) // EOF
+ return -1;
+
+ return nread;
+}
+
+int
+gr_file_descriptor_source::read_items (char *buf, int nitems)
+{
+ assert (nitems > 0);
+ assert (d_residue_len < d_itemsize);
+
+ int nbytes_read = 0;
+
+ if (d_residue_len > 0){
+ memcpy (buf, d_residue, d_residue_len);
+ nbytes_read = d_residue_len;
+ d_residue_len = 0;
+ }
+
+ int r = read (d_fd, buf + nbytes_read, nitems * d_itemsize - nbytes_read);
+ if (r <= 0){
+ handle_residue (buf, nbytes_read);
+ return r;
+ }
+
+ r = handle_residue (buf, r + nbytes_read);
+
+ if (r == 0) // block until we get something
+ return read_items (buf, nitems);
+
+ return r;
+}
+
+int
+gr_file_descriptor_source::handle_residue (char *buf, int nbytes_read)
+{
+ assert (nbytes_read >= 0);
+ int nitems_read = nbytes_read / d_itemsize;
+ d_residue_len = nbytes_read % d_itemsize;
+ if (d_residue_len > 0){
+ // fprintf (stderr, "handle_residue: %d\n", d_residue_len);
+ memcpy (d_residue, buf + nbytes_read - d_residue_len, d_residue_len);
+ }
+ return nitems_read;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.h b/gnuradio-core/src/lib/io/gr_file_descriptor_source.h
new file mode 100644
index 000000000..ebabd81ed
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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_GR_FILE_DESCRIPTOR_SOURCE_H
+#define INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+
+class gr_file_descriptor_source;
+typedef boost::shared_ptr<gr_file_descriptor_source> gr_file_descriptor_source_sptr;
+
+GR_CORE_API gr_file_descriptor_source_sptr
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat = false);
+
+/*!
+ * \brief Read stream from file descriptor.
+ * \ingroup source_blk
+ */
+
+class GR_CORE_API gr_file_descriptor_source : public gr_sync_block
+{
+ friend GR_CORE_API gr_file_descriptor_source_sptr
+ gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+ private:
+ size_t d_itemsize;
+ int d_fd;
+ bool d_repeat;
+
+ unsigned char *d_residue;
+ unsigned long d_residue_len;
+
+ protected:
+ gr_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+
+ int read_items (char *buf, int nitems);
+ int handle_residue (char *buf, int nbytes_read);
+ void flush_residue () { d_residue_len = 0; }
+
+
+ public:
+ ~gr_file_descriptor_source ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FILE_DESCRIPTOR_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.i b/gnuradio-core/src/lib/io/gr_file_descriptor_source.i
new file mode 100644
index 000000000..3ca082522
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_descriptor_source)
+
+gr_file_descriptor_source_sptr
+gr_make_file_descriptor_source (size_t itemsize, int fd, bool repeat=false);
+
+class gr_file_descriptor_source : public gr_sync_block
+{
+ protected:
+ gr_file_descriptor_source (size_t itemsize, int fd, bool repeat);
+
+ public:
+ ~gr_file_descriptor_source ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.cc b/gnuradio-core/src/lib/io/gr_file_sink.cc
new file mode 100644
index 000000000..10c8360cb
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2007,2010 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
+
+#include <gr_file_sink.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+
+gr_file_sink_sptr
+gr_make_file_sink (size_t itemsize, const char *filename)
+{
+ return gnuradio::get_initial_sptr(new gr_file_sink (itemsize, filename));
+}
+
+gr_file_sink::gr_file_sink(size_t itemsize, const char *filename)
+ : gr_sync_block ("file_sink",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(0, 0, 0)),
+ gr_file_sink_base(filename, true),
+ d_itemsize(itemsize)
+{
+}
+
+gr_file_sink::~gr_file_sink ()
+{
+}
+
+int
+gr_file_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *inbuf = (char*)input_items[0];
+ int nwritten = 0;
+
+ do_update(); // update d_fp is reqd
+
+ if(!d_fp)
+ return noutput_items; // drop output on the floor
+
+ while(nwritten < noutput_items) {
+ int count = fwrite(inbuf, d_itemsize, noutput_items - nwritten, d_fp);
+ if(count == 0) {
+ if(ferror(d_fp)) {
+ std::stringstream s;
+ s << "file_sink write failed with error " << fileno(d_fp) << std::endl;
+ throw std::runtime_error(s.str());
+ }
+ else { // is EOF
+ break;
+ }
+ }
+ nwritten += count;
+ inbuf += count * d_itemsize;
+ }
+
+ if(d_unbuffered)
+ fflush (d_fp);
+
+ return nwritten;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.h b/gnuradio-core/src/lib/io/gr_file_sink.h
new file mode 100644
index 000000000..e40ec9ab8
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink.h
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 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_GR_FILE_SINK_H
+#define INCLUDED_GR_FILE_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_file_sink_base.h>
+
+class gr_file_sink;
+typedef boost::shared_ptr<gr_file_sink> gr_file_sink_sptr;
+
+GR_CORE_API gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
+
+/*!
+ * \brief Write stream to file.
+ * \ingroup sink_blk
+ */
+
+class GR_CORE_API gr_file_sink : public gr_sync_block, public gr_file_sink_base
+{
+ friend GR_CORE_API gr_file_sink_sptr gr_make_file_sink(size_t itemsize, const char *filename);
+
+ private:
+ size_t d_itemsize;
+
+ protected:
+ gr_file_sink(size_t itemsize, const char *filename);
+
+ public:
+ ~gr_file_sink();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FILE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_sink.i b/gnuradio-core/src/lib/io/gr_file_sink.i
new file mode 100644
index 000000000..47ab9e964
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink.i
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,file_sink)
+
+gr_file_sink_sptr
+gr_make_file_sink (size_t itemsize, const char *filename);
+
+class gr_file_sink : public gr_sync_block, public gr_file_sink_base
+{
+ protected:
+ gr_file_sink (size_t itemsize, const char *filename);
+
+ public:
+ ~gr_file_sink ();
+
+ /*!
+ * \brief open filename and begin output to it.
+ */
+ bool open(const char *filename);
+
+ /*!
+ * \brief close current output file.
+ */
+ void close();
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.cc b/gnuradio-core/src/lib/io/gr_file_sink_base.cc
new file mode 100644
index 000000000..d0aca418e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.cc
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2007,2009 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
+
+#include <gr_file_sink_base.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <gruel/thread.h>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+gr_file_sink_base::gr_file_sink_base(const char *filename, bool is_binary)
+ : d_fp(0), d_new_fp(0), d_updated(false), d_is_binary(is_binary)
+{
+ if (!open(filename))
+ throw std::runtime_error ("can't open file");
+}
+
+gr_file_sink_base::~gr_file_sink_base ()
+{
+ close();
+ if (d_fp){
+ fclose(d_fp);
+ d_fp = 0;
+ }
+}
+
+bool
+gr_file_sink_base::open(const char *filename)
+{
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+
+ // we use the open system call to get access to the O_LARGEFILE flag.
+ int fd;
+ if ((fd = ::open (filename,
+ O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY,
+ 0664)) < 0){
+ perror (filename);
+ return false;
+ }
+ if (d_new_fp){ // if we've already got a new one open, close it
+ fclose(d_new_fp);
+ d_new_fp = 0;
+ }
+
+ if ((d_new_fp = fdopen (fd, d_is_binary ? "wb" : "w")) == NULL){
+ perror (filename);
+ ::close(fd); // don't leak file descriptor if fdopen fails.
+ }
+
+ d_updated = true;
+ return d_new_fp != 0;
+}
+
+void
+gr_file_sink_base::close()
+{
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+
+ if (d_new_fp){
+ fclose(d_new_fp);
+ d_new_fp = 0;
+ }
+ d_updated = true;
+}
+
+void
+gr_file_sink_base::do_update()
+{
+ if (d_updated){
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this block
+ if (d_fp)
+ fclose(d_fp);
+ d_fp = d_new_fp; // install new file pointer
+ d_new_fp = 0;
+ d_updated = false;
+ }
+}
+
+void
+gr_file_sink_base::set_unbuffered(bool unbuffered)
+{
+ d_unbuffered = unbuffered;
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.h b/gnuradio-core/src/lib/io/gr_file_sink_base.h
new file mode 100644
index 000000000..8a70cee76
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,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_GR_FILE_SINK_BASE_H
+#define INCLUDED_GR_FILE_SINK_BASE_H
+
+#include <gr_core_api.h>
+#include <boost/thread.hpp>
+#include <cstdio>
+
+/*!
+ * \brief Common base class for file sinks
+ */
+class GR_CORE_API gr_file_sink_base
+{
+ protected:
+ FILE *d_fp; // current FILE pointer
+ FILE *d_new_fp; // new FILE pointer
+ bool d_updated; // is there a new FILE pointer?
+ bool d_is_binary;
+ boost::mutex d_mutex;
+ bool d_unbuffered;
+
+ protected:
+ gr_file_sink_base(const char *filename, bool is_binary);
+
+ public:
+ ~gr_file_sink_base();
+
+ /*!
+ * \brief Open filename and begin output to it.
+ */
+ bool open(const char *filename);
+
+ /*!
+ * \brief Close current output file.
+ *
+ * Closes current output file and ignores any output until
+ * open is called to connect to another file.
+ */
+ void close();
+
+ /*!
+ * \brief if we've had an update, do it now.
+ */
+ void do_update();
+
+
+ /*!
+ * \brief turn on unbuffered writes for slower outputs
+ */
+ void set_unbuffered(bool unbuffered);
+};
+
+
+#endif /* INCLUDED_GR_FILE_SINK_BASE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_sink_base.i b/gnuradio-core/src/lib/io/gr_file_sink_base.i
new file mode 100644
index 000000000..993dba277
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_sink_base.i
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+class gr_file_sink_base
+{
+ protected:
+ gr_file_sink_base(const char *filename, bool is_binary);
+
+ public:
+ ~gr_file_sink_base();
+
+ /*!
+ * \brief Open filename and begin output to it.
+ */
+ bool open(const char *filename);
+
+ /*!
+ * \brief Close current output file.
+ *
+ * Closes current output file and ignores any output until
+ * open is called to connect to another file.
+ */
+ void close();
+
+ /*!
+ * \brief if we've had an update, do it now.
+ */
+ void do_update();
+
+ /*!
+ *\brief turn on unbuffered mode for slow outputs
+ */
+ void set_unbuffered(bool unbuffered);
+};
diff --git a/gnuradio-core/src/lib/io/gr_file_source.cc b/gnuradio-core/src/lib/io/gr_file_source.cc
new file mode 100644
index 000000000..6da7abac2
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_source.cc
@@ -0,0 +1,192 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010 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
+
+#include <gruel/thread.h>
+#include <gr_file_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <stdio.h>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+gr_file_source::gr_file_source(size_t itemsize, const char *filename, bool repeat)
+ : gr_sync_block("file_source",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, itemsize)),
+ d_itemsize(itemsize), d_fp(0), d_new_fp (0), d_repeat(repeat),
+ d_updated(false)
+{
+ open(filename, repeat);
+}
+
+// public constructor that returns a shared_ptr
+
+gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat)
+{
+ return gnuradio::get_initial_sptr(new gr_file_source (itemsize, filename, repeat));
+}
+
+gr_file_source::~gr_file_source ()
+{
+ close();
+ if(d_fp) {
+ fclose(d_fp);
+ d_fp = 0;
+ }
+}
+
+int
+gr_file_source::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *o = (char *) output_items[0];
+ int i;
+ int size = noutput_items;
+
+ do_update(); // update d_fp is reqd
+ if(d_fp == NULL)
+ throw std::runtime_error("work with file not open");
+
+ gruel::scoped_lock lock(fp_mutex); // hold for the rest of this function
+ while (size) {
+ i = fread(o, d_itemsize, size, (FILE *) d_fp);
+
+ size -= i;
+ o += i * d_itemsize;
+
+ if (size == 0) // done
+ break;
+
+ if (i > 0) // short read, try again
+ continue;
+
+ // We got a zero from fread. This is either EOF or error. In
+ // any event, if we're in repeat mode, seek back to the beginning
+ // of the file and try again, else break
+
+ if (!d_repeat)
+ break;
+
+ if (fseek ((FILE *) d_fp, 0, SEEK_SET) == -1) {
+ std::stringstream s;
+ s << "[" << __FILE__ << "]" << " fseek failed" << std::endl;
+ throw std::runtime_error(s.str());
+ }
+ }
+
+ if (size > 0){ // EOF or error
+ if (size == noutput_items) // we didn't read anything; say we're done
+ return -1;
+ return noutput_items - size; // else return partial result
+ }
+
+ return noutput_items;
+}
+
+bool
+gr_file_source::seek (long seek_point, int whence)
+{
+ // obtain exclusive access for duration of this function
+ gruel::scoped_lock lock(fp_mutex);
+ return fseek((FILE *) d_fp, seek_point * d_itemsize, whence) == 0;
+}
+
+void
+gr_file_source::open(const char *filename, bool repeat)
+{
+ // obtain exclusive access for duration of this function
+ gruel::scoped_lock lock(fp_mutex);
+
+ int fd;
+
+ // we use "open" to use to the O_LARGEFILE flag
+ if((fd = ::open(filename, O_RDONLY | OUR_O_LARGEFILE | OUR_O_BINARY)) < 0) {
+ perror(filename);
+ throw std::runtime_error("can't open file");
+ }
+
+ if(d_new_fp) {
+ fclose(d_new_fp);
+ d_new_fp = 0;
+ }
+
+ if((d_new_fp = fdopen (fd, "rb")) == NULL) {
+ perror(filename);
+ ::close(fd); // don't leak file descriptor if fdopen fails
+ throw std::runtime_error("can't open file");
+ }
+
+ d_updated = true;
+ d_repeat = repeat;
+}
+
+void
+gr_file_source::close()
+{
+ // obtain exclusive access for duration of this function
+ gruel::scoped_lock lock(fp_mutex);
+
+ if(d_new_fp != NULL) {
+ fclose(d_new_fp);
+ d_new_fp = NULL;
+ }
+ d_updated = true;
+}
+
+void
+gr_file_source::do_update()
+{
+ if(d_updated) {
+ gruel::scoped_lock lock(fp_mutex); // hold while in scope
+
+ if(d_fp)
+ fclose(d_fp);
+
+ d_fp = d_new_fp; // install new file pointer
+ d_new_fp = 0;
+ d_updated = false;
+ }
+}
diff --git a/gnuradio-core/src/lib/io/gr_file_source.h b/gnuradio-core/src/lib/io/gr_file_source.h
new file mode 100644
index 000000000..0478fba04
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_source.h
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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_GR_FILE_SOURCE_H
+#define INCLUDED_GR_FILE_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <boost/thread/mutex.hpp>
+
+class gr_file_source;
+typedef boost::shared_ptr<gr_file_source> gr_file_source_sptr;
+
+GR_CORE_API gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat = false);
+
+/*!
+ * \brief Read stream from file
+ * \ingroup source_blk
+ */
+
+class GR_CORE_API gr_file_source : public gr_sync_block
+{
+ private:
+ size_t d_itemsize;
+ FILE *d_fp;
+ FILE *d_new_fp;
+ bool d_repeat;
+ bool d_updated;
+
+ protected:
+ gr_file_source(size_t itemsize, const char *filename, bool repeat);
+
+ void do_update();
+
+ boost::mutex fp_mutex;
+
+ public:
+ /*!
+ * \brief Create a file source.
+ *
+ * Opens \p filename as a source of items into a flowgraph. The data
+ * is expected to be in binary format, item after item. The \p
+ * itemsize of the block determines the conversion from bits to
+ * items.
+ *
+ * If \p repeat is turned on, the file will repeat the file after
+ * it's reached the end.
+ *
+ * \param itemsize the size of each item in the file, in bytes
+ * \param filename name of the file to source from
+ * \param repeat repeat file from start
+ */
+ friend GR_CORE_API gr_file_source_sptr
+ gr_make_file_source(size_t itemsize,
+ const char *filename,
+ bool repeat);
+
+ ~gr_file_source();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ /*!
+ * \brief Seek file to \p seek_point relative to \p whence
+ *
+ * \param seek_point sample offset in file
+ * \param whence one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek)
+ */
+ bool seek(long seek_point, int whence);
+
+ /*!
+ * \brief Opens a new file.
+ *
+ * \param filename name of the file to source from
+ * \param repeat repeat file from start
+ */
+ void open(const char *filename, bool repeat);
+
+ /*!
+ * \brief Close the file handle.
+ */
+ void close();
+
+};
+
+#endif /* INCLUDED_GR_FILE_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_file_source.i b/gnuradio-core/src/lib/io/gr_file_source.i
new file mode 100644
index 000000000..e71cef0d1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_file_source.i
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+
+%constant int SEEK_SET = 0; /* Seek from beginning of file. */
+%constant int SEEK_CUR = 1; /* Seek from current position. */
+%constant int SEEK_END = 2; /* Seek from end of file. */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,file_source)
+
+gr_file_source_sptr
+gr_make_file_source (size_t itemsize, const char *filename, bool repeat=false);
+
+class gr_file_source : public gr_sync_block
+{
+ protected:
+ gr_file_source (size_t itemsize, const char *filename, bool repeat);
+
+ public:
+ ~gr_file_source ();
+
+ bool seek (long seek_point, int whence);
+ void open (const char *filename, bool repeat);
+ void close();
+};
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink.i b/gnuradio-core/src/lib/io/gr_histo_sink.i
new file mode 100644
index 000000000..14079e190
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink.i
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,histo_sink_f)
+
+gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+
+class gr_histo_sink_f : public gr_sync_block
+{
+public:
+ ~gr_histo_sink_f (void);
+
+ unsigned int get_frame_size(void);
+ unsigned int get_num_bins(void);
+
+ void set_frame_size(unsigned int frame_size);
+ void set_num_bins(unsigned int num_bins);
+
+};
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink_f.cc b/gnuradio-core/src/lib/io/gr_histo_sink_f.cc
new file mode 100644
index 000000000..fc0c12ce6
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink_f.cc
@@ -0,0 +1,165 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,2010,2011 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
+
+#include <gr_histo_sink_f.h>
+#include <gr_io_signature.h>
+#include <boost/math/special_functions/round.hpp>
+
+static float get_clean_num(float num){
+ if (num == 0) return 0;
+ /* extract sign and exponent from num */
+ int sign = (num < 0) ? -1 : 1; num = fabs(num);
+ float exponent = floor(log10(num));
+ /* search for closest number with base 1, 2, 5, 10 */
+ float closest_num = 10*pow(10, exponent);
+ if (fabs(num - 1*pow(10, exponent)) < fabs(num - closest_num))
+ closest_num = 1*pow(10, exponent);
+ if (fabs(num - 2*pow(10, exponent)) < fabs(num - closest_num))
+ closest_num = 2*pow(10, exponent);
+ if (fabs(num - 5*pow(10, exponent)) < fabs(num - closest_num))
+ closest_num = 5*pow(10, exponent);
+ return sign*closest_num;
+}
+
+gr_histo_sink_f_sptr
+gr_make_histo_sink_f (gr_msg_queue_sptr msgq)
+{
+ return gnuradio::get_initial_sptr(new gr_histo_sink_f (msgq));
+}
+
+gr_histo_sink_f::gr_histo_sink_f (gr_msg_queue_sptr msgq)
+ : gr_sync_block ("histo_sink_f", gr_make_io_signature (1, 1, sizeof (float)), gr_make_io_signature (0, 0, 0)),
+ d_msgq (msgq), d_num_bins(11), d_frame_size(1000), d_sample_count(0), d_bins(NULL), d_samps(NULL)
+{
+ //allocate arrays and clear
+ set_num_bins(d_num_bins);
+ set_frame_size(d_frame_size);
+}
+
+gr_histo_sink_f::~gr_histo_sink_f (void)
+{
+ delete [] d_samps;
+ delete [] d_bins;
+}
+
+int
+gr_histo_sink_f::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const float *in = (const float *) input_items[0];
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+ for (unsigned int i = 0; i < (unsigned int)noutput_items; i++){
+ d_samps[d_sample_count] = in[i];
+ d_sample_count++;
+ /* processed a frame? */
+ if (d_sample_count == d_frame_size){
+ send_frame();
+ clear();
+ }
+ }
+ return noutput_items;
+}
+
+void
+gr_histo_sink_f::send_frame(void){
+ /* output queue full, drop the data */
+ if (d_msgq->full_p()) return;
+ /* find the minimum and maximum */
+ float minimum = d_samps[0];
+ float maximum = d_samps[0];
+ for (unsigned int i = 0; i < d_frame_size; i++){
+ if (d_samps[i] < minimum) minimum = d_samps[i];
+ if (d_samps[i] > maximum) maximum = d_samps[i];
+ }
+ minimum = get_clean_num(minimum);
+ maximum = get_clean_num(maximum);
+ if (minimum == maximum || minimum > maximum) return; //useless data or screw up?
+ /* load the bins */
+ int index;
+ float bin_width = (maximum - minimum)/(d_num_bins-1);
+ for (unsigned int i = 0; i < d_sample_count; i++){
+ index = boost::math::iround((d_samps[i] - minimum)/bin_width);
+ /* ensure the index range in case a small floating point error is involed */
+ if (index < 0) index = 0;
+ if (index >= (int)d_num_bins) index = d_num_bins-1;
+ d_bins[index]++;
+ }
+ /* Build a message to hold the output records */
+ gr_message_sptr msg = gr_make_message(0, minimum, maximum, d_num_bins*sizeof(float));
+ float *out = (float *)msg->msg(); // get pointer to raw message buffer
+ /* normalize the bins and put into message */
+ for (unsigned int i = 0; i < d_num_bins; i++){
+ out[i] = ((float)d_bins[i])/d_frame_size;
+ }
+ /* send the message */
+ d_msgq->handle(msg);
+}
+
+void
+gr_histo_sink_f::clear(void){
+ d_sample_count = 0;
+ /* zero the bins */
+ for (unsigned int i = 0; i < d_num_bins; i++){
+ d_bins[i] = 0;
+ }
+}
+
+/**************************************************
+ * Getters
+ **************************************************/
+unsigned int
+gr_histo_sink_f::get_frame_size(void){
+ return d_frame_size;
+}
+
+unsigned int
+gr_histo_sink_f::get_num_bins(void){
+ return d_num_bins;
+}
+
+/**************************************************
+ * Setters
+ **************************************************/
+void
+gr_histo_sink_f::set_frame_size(unsigned int frame_size){
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+ d_frame_size = frame_size;
+ /* allocate a new sample array */
+ delete [] d_samps;
+ d_samps = new float[d_frame_size];
+ clear();
+}
+
+void
+gr_histo_sink_f::set_num_bins(unsigned int num_bins){
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this function
+ d_num_bins = num_bins;
+ /* allocate a new bin array */
+ delete [] d_bins;
+ d_bins = new unsigned int[d_num_bins];
+ clear();
+}
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink_f.h b/gnuradio-core/src/lib/io/gr_histo_sink_f.h
new file mode 100644
index 000000000..934066ba2
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink_f.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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_GR_HISTO_SINK_F_H
+#define INCLUDED_GR_HISTO_SINK_F_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+#include <gruel/thread.h>
+
+class gr_histo_sink_f;
+typedef boost::shared_ptr<gr_histo_sink_f> gr_histo_sink_f_sptr;
+
+GR_CORE_API gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+
+/*!
+ * \brief Histogram module.
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_histo_sink_f : public gr_sync_block
+{
+private:
+ gr_msg_queue_sptr d_msgq;
+ unsigned int d_num_bins;
+ unsigned int d_frame_size;
+ unsigned int d_sample_count;
+ unsigned int *d_bins;
+ float *d_samps;
+ gruel::mutex d_mutex;
+
+ friend GR_CORE_API gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+ gr_histo_sink_f (gr_msg_queue_sptr msgq);
+ void send_frame(void);
+ void clear(void);
+
+public:
+ ~gr_histo_sink_f (void);
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ unsigned int get_frame_size(void);
+ unsigned int get_num_bins(void);
+
+ void set_frame_size(unsigned int frame_size);
+ void set_num_bins(unsigned int num_bins);
+
+};
+
+#endif /* INCLUDED_GR_HISTO_SINK_F_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_burst_source.cc b/gnuradio-core/src/lib/io/gr_message_burst_source.cc
new file mode 100644
index 000000000..e9e2dfd4d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_burst_source.cc
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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
+
+#include <gr_message_burst_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+#include <gr_tags.h>
+
+// public constructor that returns a shared_ptr
+
+gr_message_burst_source_sptr
+gr_make_message_burst_source(size_t itemsize, int msgq_limit)
+{
+ return gnuradio::get_initial_sptr(new gr_message_burst_source(itemsize, msgq_limit));
+}
+
+// public constructor that takes existing message queue
+gr_message_burst_source_sptr
+gr_make_message_burst_source(size_t itemsize, gr_msg_queue_sptr msgq)
+{
+ return gnuradio::get_initial_sptr(new gr_message_burst_source(itemsize, msgq));
+}
+
+gr_message_burst_source::gr_message_burst_source (size_t itemsize, int msgq_limit)
+ : gr_sync_block("message_burst_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false)
+{
+ std::stringstream id;
+ id << name() << unique_id();
+ d_me = pmt::pmt_string_to_symbol(id.str());
+}
+
+gr_message_burst_source::gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq)
+ : gr_sync_block("message_burst_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_msgq(msgq), d_msg_offset(0), d_eof(false)
+{
+ std::stringstream id;
+ id << name() << unique_id();
+ d_me = pmt::pmt_string_to_symbol(id.str());
+}
+
+gr_message_burst_source::~gr_message_burst_source()
+{
+}
+
+int
+gr_message_burst_source::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ int nn = 0;
+
+ uint64_t abs_sample_count = nitems_written(0);
+
+ while (nn < noutput_items){
+ if (d_msg){
+ //
+ // Consume whatever we can from the current message
+ //
+
+ int mm = std::min(noutput_items - nn, (int)((d_msg->length() - d_msg_offset) / d_itemsize));
+ memcpy (out, &(d_msg->msg()[d_msg_offset]), mm * d_itemsize);
+
+ nn += mm;
+ out += mm * d_itemsize;
+ d_msg_offset += mm * d_itemsize;
+ assert(d_msg_offset <= d_msg->length());
+
+ if (d_msg_offset == d_msg->length()){
+ if (d_msg->type() == 1) // type == 1 sets EOF
+ d_eof = true;
+ d_msg.reset();
+ //tag end of burst
+ add_item_tag(0, //stream ID
+ abs_sample_count+nn-1, //sample number
+ pmt::pmt_string_to_symbol("tx_eob"),
+ pmt::pmt_from_bool(1),
+ d_me //block src id
+ );
+ }
+ }
+ else {
+ //
+ // No current message
+ //
+ if (d_msgq->empty_p() && nn > 0){ // no more messages in the queue, return what we've got
+ break;
+ }
+
+ if (d_eof)
+ return -1;
+
+ d_msg = d_msgq->delete_head(); // block, waiting for a message
+ d_msg_offset = 0;
+ //tag start of burst
+ add_item_tag(0, //stream ID
+ abs_sample_count+nn, //sample number
+ pmt::pmt_string_to_symbol("tx_sob"),
+ pmt::pmt_from_bool(1),
+ d_me //block src id
+ );
+
+
+ if ((d_msg->length() % d_itemsize) != 0)
+ throw std::runtime_error("msg length is not a multiple of d_itemsize");
+ }
+ }
+
+ return nn;
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_burst_source.h b/gnuradio-core/src/lib/io/gr_message_burst_source.h
new file mode 100644
index 000000000..63e220113
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_burst_source.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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_GR_MESSAGE_BURST_SOURCE_H
+#define INCLUDED_GR_MESSAGE_BURST_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_message_burst_source;
+typedef boost::shared_ptr<gr_message_burst_source> gr_message_burst_source_sptr;
+
+GR_CORE_API gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, int msgq_limit=0);
+GR_CORE_API gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+/*!
+ * \brief Turn received messages into a stream and tag them for UHD to send.
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_message_burst_source : public gr_sync_block
+{
+ private:
+ size_t d_itemsize;
+ gr_msg_queue_sptr d_msgq;
+ gr_message_sptr d_msg;
+ unsigned d_msg_offset;
+ bool d_eof;
+
+ pmt::pmt_t d_me;
+
+ friend GR_CORE_API gr_message_burst_source_sptr
+ gr_make_message_burst_source(size_t itemsize, int msgq_limit);
+ friend GR_CORE_API gr_message_burst_source_sptr
+ gr_make_message_burst_source(size_t itemsize, gr_msg_queue_sptr msgq);
+
+ protected:
+ gr_message_burst_source (size_t itemsize, int msgq_limit);
+ gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+ public:
+ ~gr_message_burst_source ();
+
+ gr_msg_queue_sptr msgq() const { return d_msgq; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_gr_message_burst_source_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_burst_source.i b/gnuradio-core/src/lib/io/gr_message_burst_source.i
new file mode 100644
index 000000000..f7ad840c2
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_burst_source.i
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_burst_source);
+
+gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, int msgq_limit=0);
+gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+class gr_message_burst_source : public gr_sync_block
+{
+ protected:
+ gr_message_burst_source (size_t itemsize, int msgq_limit);
+ gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+ public:
+ ~gr_message_burst_source ();
+
+ gr_msg_queue_sptr msgq() const;
+};
diff --git a/gnuradio-core/src/lib/io/gr_message_debug.cc b/gnuradio-core/src/lib/io/gr_message_debug.cc
new file mode 100644
index 000000000..9eb1bb639
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_debug.cc
@@ -0,0 +1,120 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010,2012 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
+
+#include <gr_message_debug.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+#include <iostream>
+
+// public constructor that returns a shared_ptr
+
+gr_message_debug_sptr
+gr_make_message_debug ()
+{
+ return gnuradio::get_initial_sptr(new gr_message_debug());
+}
+
+void
+gr_message_debug::print(pmt::pmt_t msg)
+{
+ std::cout << "******* MESSAGE DEBUG PRINT ********\n";
+ pmt::pmt_print(msg);
+ std::cout << "************************************\n";
+}
+
+void
+gr_message_debug::store(pmt::pmt_t msg)
+{
+ gruel::scoped_lock guard(d_mutex);
+ d_messages.push_back(msg);
+}
+
+void
+gr_message_debug::print_pdu(pmt::pmt_t pdu)
+{
+ pmt::pmt_t meta = pmt::pmt_car(pdu);
+ pmt::pmt_t vector = pmt::pmt_cdr(pdu);
+ std::cout << "* MESSAGE DEBUG PRINT PDU VERBOSE *\n";
+ pmt::pmt_print(meta);
+ size_t len = pmt::pmt_length(vector);
+ std::cout << "pdu_length = " << len << std::endl;
+ std::cout << "contents = " << std::endl;
+ size_t offset(0);
+ const uint8_t* d = (const uint8_t*) pmt_uniform_vector_elements(vector, offset);
+ for(size_t i=0; i<len; i+=16){
+ printf("%04x: ", ((unsigned int)i));
+ for(size_t j=i; j<std::min(i+16,len); j++){
+ printf("%02x ",d[j] );
+ }
+
+ std::cout << std::endl;
+ }
+
+ std::cout << "***********************************\n";
+}
+
+int
+gr_message_debug::num_messages()
+{
+ return (int)d_messages.size();
+}
+
+pmt::pmt_t
+gr_message_debug::get_message(int i)
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ if((size_t)i >= d_messages.size()) {
+ throw std::runtime_error("gr_message_debug: index for message out of bounds.\n");
+ }
+
+ return d_messages[i];
+}
+
+gr_message_debug::gr_message_debug()
+ : gr_block("message_debug",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(0, 0, 0))
+{
+ message_port_register_in(pmt::mp("print"));
+ set_msg_handler(pmt::mp("print"), boost::bind(&gr_message_debug::print, this, _1));
+
+ message_port_register_in(pmt::mp("store"));
+ set_msg_handler(pmt::mp("store"), boost::bind(&gr_message_debug::store, this, _1));
+
+ message_port_register_in(pmt::mp("print_pdu"));
+ set_msg_handler(pmt::mp("print_pdu"), boost::bind(&gr_message_debug::print_pdu, this, _1));
+}
+
+gr_message_debug::~gr_message_debug()
+{
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_debug.h b/gnuradio-core/src/lib/io/gr_message_debug.h
new file mode 100644
index 000000000..f1374e806
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_debug.h
@@ -0,0 +1,114 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2012 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_GR_MESSAGE_DEBUG_H
+#define INCLUDED_GR_MESSAGE_DEBUG_H
+
+#include <gr_core_api.h>
+#include <gr_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gruel/thread.h>
+
+class gr_message_debug;
+typedef boost::shared_ptr<gr_message_debug> gr_message_debug_sptr;
+
+GR_CORE_API gr_message_debug_sptr gr_make_message_debug();
+
+/*!
+ * \brief Print received messages to stdout
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_message_debug : public gr_block
+{
+ private:
+ friend GR_CORE_API gr_message_debug_sptr
+ gr_make_message_debug();
+
+ /*!
+ * \brief Messages received in this port are printed to stdout.
+ *
+ * This port receives messages from the scheduler's message handling
+ * mechanism and prints it to stdout. This message handler function
+ * is only meant to be used by the scheduler to handle messages
+ * posted to port 'print'.
+ *
+ * \param msg A pmt message passed from the scheduler's message handling.
+ */
+ void print(pmt::pmt_t msg);
+
+ /*!
+ * \brief PDU formatted messages received in this port are printed to stdout.
+ *
+ * This port receives messages from the scheduler's message handling
+ * mechanism and prints it to stdout. This message handler function
+ * is only meant to be used by the scheduler to handle messages
+ * posted to port 'print'.
+ *
+ * \param pdu A PDU message passed from the scheduler's message handling.
+ */
+ void print_pdu(pmt::pmt_t pdu);
+
+ /*!
+ * \brief Messages received in this port are stored in a vector.
+ *
+ * This port receives messages from the scheduler's message handling
+ * mechanism and stores it in a vector. Messages can be retrieved
+ * later using the 'get_message' function. This message handler
+ * function is only meant to be used by the scheduler to handle
+ * messages posted to port 'store'.
+ *
+ * \param msg A pmt message passed from the scheduler's message handling.
+ */
+ void store(pmt::pmt_t msg);
+
+ gruel::mutex d_mutex;
+ std::vector<pmt::pmt_t> d_messages;
+
+ protected:
+ gr_message_debug ();
+
+ public:
+ ~gr_message_debug ();
+
+ /*!
+ * \brief Reports the number of messages received by this block.
+ */
+ int num_messages();
+
+ /*!
+ * \brief Get a message (as a PMT) from the message vector at index \p i.
+ *
+ * Messages passed to the 'store' port will be stored in a
+ * vector. This function retrieves those messages by index. They are
+ * index in order of when they were received (all messages are just
+ * pushed onto the back of a vector). This is mostly useful in
+ * debugging message passing graphs and in QA code.
+ *
+ * \param i The index in the vector for the message to retrieve.
+ *
+ * \return a message at index \p i as a pmt_t.
+ */
+ pmt::pmt_t get_message(int i);
+};
+
+#endif /* INCLUDED_GR_MESSAGE_DEBUG_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_debug.i b/gnuradio-core/src/lib/io/gr_message_debug.i
new file mode 100644
index 000000000..65d3bfc4a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_debug.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_debug);
+
+%{
+#include <gr_message_debug.h>
+%}
+
+%include "gr_message_debug.h"
+
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.cc b/gnuradio-core/src/lib/io/gr_message_sink.cc
new file mode 100644
index 000000000..ae0b5c764
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_sink.cc
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 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
+
+#include <gr_message_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+
+
+// public constructor that returns a shared_ptr
+
+gr_message_sink_sptr
+gr_make_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block)
+{
+ return gnuradio::get_initial_sptr(new gr_message_sink(itemsize, msgq, dont_block));
+}
+
+gr_message_sink::gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block)
+ : gr_sync_block("message_sink",
+ gr_make_io_signature(1, 1, itemsize),
+ gr_make_io_signature(0, 0, 0)),
+ d_itemsize(itemsize), d_msgq(msgq), d_dont_block(dont_block)
+{
+}
+
+gr_message_sink::~gr_message_sink()
+{
+}
+
+int
+gr_message_sink::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *in = (const char *) input_items[0];
+
+ // if we'd block, drop the data on the floor and say everything is OK
+ if (d_dont_block && d_msgq->full_p())
+ return noutput_items;
+
+ // build a message to hold whatever we've got
+ gr_message_sptr msg = gr_make_message(0, // msg type
+ d_itemsize, // arg1 for other end
+ noutput_items, // arg2 for other end (redundant)
+ noutput_items * d_itemsize); // len of msg
+ memcpy(msg->msg(), in, noutput_items * d_itemsize);
+
+ d_msgq->handle(msg); // send it
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.h b/gnuradio-core/src/lib/io/gr_message_sink.h
new file mode 100644
index 000000000..84005694a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_sink.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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_GR_MESSAGE_SINK_H
+#define INCLUDED_GR_MESSAGE_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_message_sink;
+typedef boost::shared_ptr<gr_message_sink> gr_message_sink_sptr;
+
+GR_CORE_API gr_message_sink_sptr gr_make_message_sink (size_t itemsize,
+ gr_msg_queue_sptr msgq,
+ bool dont_block);
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_message_sink : public gr_sync_block
+{
+ private:
+ size_t d_itemsize;
+ gr_msg_queue_sptr d_msgq;
+ bool d_dont_block;
+
+ friend GR_CORE_API gr_message_sink_sptr
+ gr_make_message_sink(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ protected:
+ gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ public:
+ ~gr_message_sink ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MESSAGE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_sink.i b/gnuradio-core/src/lib/io/gr_message_sink.i
new file mode 100644
index 000000000..8415cbd66
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_sink.i
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_sink);
+
+gr_message_sink_sptr gr_make_message_sink (size_t itemsize,
+ gr_msg_queue_sptr msgq,
+ bool dont_block);
+
+class gr_message_sink : public gr_sync_block
+{
+ protected:
+ gr_message_sink (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+
+ public:
+ ~gr_message_sink ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_message_source.cc b/gnuradio-core/src/lib/io/gr_message_source.cc
new file mode 100644
index 000000000..fb3da89a8
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.cc
@@ -0,0 +1,120 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2010 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
+
+#include <gr_message_source.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+
+
+// public constructor that returns a shared_ptr
+
+gr_message_source_sptr
+gr_make_message_source(size_t itemsize, int msgq_limit)
+{
+ return gnuradio::get_initial_sptr(new gr_message_source(itemsize, msgq_limit));
+}
+
+// public constructor that takes existing message queue
+gr_message_source_sptr
+gr_make_message_source(size_t itemsize, gr_msg_queue_sptr msgq)
+{
+ return gnuradio::get_initial_sptr(new gr_message_source(itemsize, msgq));
+}
+
+gr_message_source::gr_message_source (size_t itemsize, int msgq_limit)
+ : gr_sync_block("message_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false)
+{
+}
+
+gr_message_source::gr_message_source (size_t itemsize, gr_msg_queue_sptr msgq)
+ : gr_sync_block("message_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_msgq(msgq), d_msg_offset(0), d_eof(false)
+{
+}
+
+gr_message_source::~gr_message_source()
+{
+}
+
+int
+gr_message_source::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ int nn = 0;
+
+ while (nn < noutput_items){
+ if (d_msg){
+ //
+ // Consume whatever we can from the current message
+ //
+ int mm = std::min(noutput_items - nn, (int)((d_msg->length() - d_msg_offset) / d_itemsize));
+ memcpy (out, &(d_msg->msg()[d_msg_offset]), mm * d_itemsize);
+
+ nn += mm;
+ out += mm * d_itemsize;
+ d_msg_offset += mm * d_itemsize;
+ assert(d_msg_offset <= d_msg->length());
+
+ if (d_msg_offset == d_msg->length()){
+ if (d_msg->type() == 1) // type == 1 sets EOF
+ d_eof = true;
+ d_msg.reset();
+ }
+ }
+ else {
+ //
+ // No current message
+ //
+ if (d_msgq->empty_p() && nn > 0){ // no more messages in the queue, return what we've got
+ break;
+ }
+
+ if (d_eof)
+ return -1;
+
+ d_msg = d_msgq->delete_head(); // block, waiting for a message
+ d_msg_offset = 0;
+
+ if ((d_msg->length() % d_itemsize) != 0)
+ throw std::runtime_error("msg length is not a multiple of d_itemsize");
+ }
+ }
+
+ return nn;
+}
diff --git a/gnuradio-core/src/lib/io/gr_message_source.h b/gnuradio-core/src/lib/io/gr_message_source.h
new file mode 100644
index 000000000..c510d1775
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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_GR_MESSAGE_SOURCE_H
+#define INCLUDED_GR_MESSAGE_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+class gr_message_source;
+typedef boost::shared_ptr<gr_message_source> gr_message_source_sptr;
+
+GR_CORE_API gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+GR_CORE_API gr_message_source_sptr gr_make_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+/*!
+ * \brief Turn received messages into a stream
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_message_source : public gr_sync_block
+{
+ private:
+ size_t d_itemsize;
+ gr_msg_queue_sptr d_msgq;
+ gr_message_sptr d_msg;
+ unsigned d_msg_offset;
+ bool d_eof;
+
+ friend GR_CORE_API gr_message_source_sptr
+ gr_make_message_source(size_t itemsize, int msgq_limit);
+ friend GR_CORE_API gr_message_source_sptr
+ gr_make_message_source(size_t itemsize, gr_msg_queue_sptr msgq);
+
+ protected:
+ gr_message_source (size_t itemsize, int msgq_limit);
+ gr_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+ public:
+ ~gr_message_source ();
+
+ gr_msg_queue_sptr msgq() const { return d_msgq; }
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MESSAGE_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_message_source.i b/gnuradio-core/src/lib/io/gr_message_source.i
new file mode 100644
index 000000000..9ee9157e8
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_message_source.i
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,message_source);
+
+gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0);
+gr_message_source_sptr gr_make_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+class gr_message_source : public gr_sync_block
+{
+ protected:
+ gr_message_source (size_t itemsize, int msgq_limit);
+ gr_message_source (size_t itemsize, gr_msg_queue_sptr msgq);
+
+ public:
+ ~gr_message_source ();
+
+ gr_msg_queue_sptr msgq() const;
+};
diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.cc b/gnuradio-core/src/lib/io/gr_oscope_guts.cc
new file mode 100644
index 000000000..a5ea3002a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_guts.cc
@@ -0,0 +1,437 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 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
+#include <gr_oscope_guts.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <algorithm>
+#include <unistd.h>
+#include <math.h>
+#include <assert.h>
+
+/*
+ * Bad performance if it's large, and flaky triggering if it's too small
+ */
+static const int OUTPUT_RECORD_SIZE = 1024; // Must be power of 2
+
+/*
+ * For (slow-updated) STRIPCHART triggering, we make the record size larger, since we
+ * potentially want to be able to "see" hours of data. This works as long as the
+ * update rates to a STRIPCHART are low, which they generally are--that's rather what
+ * a stripchart is all about!
+ */
+static const int SCHART_MULT = 8;
+
+
+static inline int
+wrap_bi (int buffer_index, int mx) // wrap buffer index
+{
+ return buffer_index & (mx - 1);
+}
+
+static inline int
+incr_bi (int buffer_index, int mx) // increment buffer index
+{
+ return wrap_bi (buffer_index + 1, mx);
+}
+
+static inline int
+decr_bi (int buffer_index, int mx) // decrement buffer index
+{
+ return wrap_bi (buffer_index - 1, mx);
+}
+
+gr_oscope_guts::gr_oscope_guts (double sample_rate, gr_msg_queue_sptr msgq)
+ : d_nchannels (1),
+ d_msgq (msgq),
+ d_trigger_mode (gr_TRIG_MODE_AUTO),
+ d_trigger_slope (gr_TRIG_SLOPE_POS),
+ d_trigger_channel (0),
+ d_sample_rate (sample_rate),
+ d_update_rate (20),
+ d_trigger_level (0),
+ d_obi (0),
+ d_state (HOLD_OFF),
+ d_decimator_count (0),
+ d_decimator_count_init (1),
+ d_hold_off_count (0),
+ d_hold_off_count_init (OUTPUT_RECORD_SIZE/2-1),
+ d_pre_trigger_count (0),
+ d_post_trigger_count (0),
+ d_post_trigger_count_init (OUTPUT_RECORD_SIZE/2)
+{
+ for (int i = 0; i < MAX_CHANNELS; i++)
+ d_buffer[i] = 0;
+
+ for (int i = 0; i < MAX_CHANNELS; i++){
+ d_buffer[i] = new float [OUTPUT_RECORD_SIZE*SCHART_MULT];
+ for (int j = 0; j < OUTPUT_RECORD_SIZE*SCHART_MULT; j++)
+ d_buffer[i][j] = 0.0;
+ }
+
+ // be sure buffer is full before first write
+ enter_hold_off ();
+ update_rate_or_decimation_changed ();
+}
+
+gr_oscope_guts::~gr_oscope_guts ()
+{
+ for (int i = 0; i < MAX_CHANNELS; i++)
+ delete [] d_buffer[i];
+}
+
+// MANIPULATORS
+
+// \p channel_data points to nchannels float values. These are the values
+// for each channel at this sample time.
+
+void
+gr_oscope_guts::process_sample (const float *channel_data)
+{
+ d_decimator_count--;
+ if (d_decimator_count > 0)
+ return;
+
+ d_decimator_count = d_decimator_count_init;
+
+ if (d_trigger_mode != gr_TRIG_MODE_STRIPCHART)
+ {
+ for (int i = 0; i < d_nchannels; i++)
+ d_buffer[i][d_obi] = channel_data[i]; // copy data into buffer
+
+ switch (d_state){
+ case HOLD_OFF:
+ d_hold_off_count--;
+ if (d_hold_off_count <= 0)
+ enter_look_for_trigger ();
+ break;
+
+ case LOOK_FOR_TRIGGER:
+ if (found_trigger ())
+ enter_post_trigger ();
+ break;
+
+ case POST_TRIGGER:
+ d_post_trigger_count--;
+ if (d_post_trigger_count <= 0){
+ write_output_records ();
+ enter_hold_off ();
+ }
+ break;
+
+ default:
+ assert (0);
+ }
+
+ d_obi = incr_bi (d_obi, OUTPUT_RECORD_SIZE);
+ }
+ else
+ {
+ for (int i = 0; i < d_nchannels; i++)
+ {
+ for (int j = (OUTPUT_RECORD_SIZE*SCHART_MULT)-1; j > 0; j--)
+ {
+ d_buffer[i][j] = d_buffer[i][j-1];
+ }
+ d_buffer[i][0] = channel_data[i];
+ }
+ d_trigger_off = 0;
+ write_output_records();
+ }
+}
+
+/*
+ * Functions called on state entry
+ */
+
+void
+gr_oscope_guts::enter_hold_off ()
+{
+ d_state = HOLD_OFF;
+ d_hold_off_count = d_hold_off_count_init;
+}
+
+void
+gr_oscope_guts::enter_look_for_trigger ()
+{
+ d_pre_trigger_count = 0;
+ d_state = LOOK_FOR_TRIGGER;
+}
+
+void
+gr_oscope_guts::enter_post_trigger ()
+{
+ d_state = POST_TRIGGER;
+ d_post_trigger_count = d_post_trigger_count_init;
+ //ensure that the trigger offset is no more than than half a sample
+ if (d_trigger_off > .5) d_trigger_off -= 1;
+ else d_post_trigger_count--;
+}
+
+// ----------------------------------------------------------------
+// returns true if trigger found
+
+bool
+gr_oscope_guts::found_trigger ()
+{
+ int mx = d_trigger_mode == gr_TRIG_MODE_STRIPCHART ? OUTPUT_RECORD_SIZE*SCHART_MULT :
+ OUTPUT_RECORD_SIZE;
+
+ float prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi, mx)];
+ float new_sample = d_buffer[d_trigger_channel][d_obi];
+
+ switch (d_trigger_mode){
+
+ case gr_TRIG_MODE_AUTO: //too many samples without a trigger
+ d_pre_trigger_count++;
+ if (d_pre_trigger_count > OUTPUT_RECORD_SIZE/2) return true;
+
+ case gr_TRIG_MODE_NORM: //look for trigger
+ switch (d_trigger_slope){
+
+ case gr_TRIG_SLOPE_POS: //trigger point in pos slope?
+ if (new_sample < d_trigger_level || prev_sample >= d_trigger_level) return false;
+ break;
+
+ case gr_TRIG_SLOPE_NEG: //trigger point in neg slope?
+ if (new_sample > d_trigger_level || prev_sample <= d_trigger_level) return false;
+ break;
+ }
+
+ //calculate the trigger offset in % sample
+ d_trigger_off = (d_trigger_level - prev_sample)/(new_sample - prev_sample);
+ return true;
+
+ case gr_TRIG_MODE_FREE: //free run mode, always trigger
+ d_trigger_off = 0;
+ return true;
+
+ default:
+ assert (0);
+ return false;
+ }
+}
+
+// ----------------------------------------------------------------
+// write output records (duh!)
+
+void
+gr_oscope_guts::write_output_records ()
+{
+ int mx;
+
+ mx = d_trigger_mode == gr_TRIG_MODE_STRIPCHART ?
+ OUTPUT_RECORD_SIZE*SCHART_MULT : OUTPUT_RECORD_SIZE;
+
+ // if the output queue if full, drop the data like its hot.
+ if (d_msgq->full_p())
+ return;
+ // Build a message to hold the output records
+ gr_message_sptr msg =
+ gr_make_message(0, // msg type
+ d_nchannels, // arg1 for other side
+ mx, // arg2 for other side
+ ((d_nchannels * mx) + 1) * sizeof(float)); // sizeof payload
+
+ float *out = (float *)msg->msg(); // get pointer to raw message buffer
+
+ for (int ch = 0; ch < d_nchannels; ch++){
+ // note that d_obi + 1 points at the oldest sample in the buffer
+ for (int i = 0; i < mx; i++){
+ out[i] = d_buffer[ch][wrap_bi(d_obi + 1 + i, mx)];
+ }
+ out += mx;
+ }
+ //Set the last sample as the trigger offset:
+ // The non gl scope sink will not look at this last sample.
+ // The gl scope sink will use this last sample as an offset.
+ out[0] = d_trigger_off;
+ d_msgq->handle(msg); // send the msg
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_oscope_guts::set_update_rate (double update_rate)
+{
+ d_update_rate = std::min (std::max (1./10., update_rate), d_sample_rate);
+ update_rate_or_decimation_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_decimation_count (int decimator_count)
+{
+ decimator_count = std::max (1, decimator_count);
+ d_decimator_count_init = decimator_count;
+ update_rate_or_decimation_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_sample_rate(double sample_rate)
+{
+ d_sample_rate = sample_rate;
+ return set_update_rate(update_rate());
+}
+
+
+void
+gr_oscope_guts::update_rate_or_decimation_changed ()
+{
+ d_hold_off_count_init =
+ (int) rint (d_sample_rate / d_update_rate / d_decimator_count_init);
+}
+
+bool
+gr_oscope_guts::set_trigger_channel (int channel)
+{
+ if (channel >= 0 && channel < d_nchannels){
+ d_trigger_channel = channel;
+ trigger_changed ();
+ return true;
+ }
+
+ return false;
+}
+
+bool
+gr_oscope_guts::set_trigger_mode (gr_trigger_mode mode)
+{
+ d_trigger_mode = mode;
+ trigger_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_trigger_slope (gr_trigger_slope slope)
+{
+ d_trigger_slope = slope;
+ trigger_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_trigger_level (double trigger_level)
+{
+ d_trigger_level = trigger_level;
+ trigger_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_trigger_level_auto ()
+{
+ // find the level 1/2 way between the min and the max
+
+ float min_v = d_buffer[d_trigger_channel][0];
+ float max_v = d_buffer[d_trigger_channel][0];
+
+ for (int i = 1; i < OUTPUT_RECORD_SIZE; i++){
+ min_v = std::min (min_v, d_buffer[d_trigger_channel][i]);
+ max_v = std::max (max_v, d_buffer[d_trigger_channel][i]);
+ }
+ return set_trigger_level((min_v + max_v) * 0.5);
+}
+
+bool
+gr_oscope_guts::set_num_channels(int nchannels)
+{
+ if (nchannels > 0 && nchannels <= MAX_CHANNELS){
+ d_nchannels = nchannels;
+ return true;
+ }
+ return false;
+}
+
+
+void
+gr_oscope_guts::trigger_changed ()
+{
+ enter_look_for_trigger ();
+}
+
+// ACCESSORS
+
+int
+gr_oscope_guts::num_channels () const
+{
+ return d_nchannels;
+}
+
+double
+gr_oscope_guts::sample_rate () const
+{
+ return d_sample_rate;
+}
+
+double
+gr_oscope_guts::update_rate () const
+{
+ return d_update_rate;
+}
+
+int
+gr_oscope_guts::get_decimation_count () const
+{
+ return d_decimator_count_init;
+}
+
+int
+gr_oscope_guts::get_trigger_channel () const
+{
+ return d_trigger_channel;
+}
+
+gr_trigger_mode
+gr_oscope_guts::get_trigger_mode () const
+{
+ return d_trigger_mode;
+}
+
+gr_trigger_slope
+gr_oscope_guts::get_trigger_slope () const
+{
+ return d_trigger_slope;
+}
+
+double
+gr_oscope_guts::get_trigger_level () const
+{
+ return d_trigger_level;
+}
+
+int
+gr_oscope_guts::get_samples_per_output_record () const
+{
+ int mx;
+
+ mx = OUTPUT_RECORD_SIZE;
+ if (d_trigger_mode == gr_TRIG_MODE_STRIPCHART)
+ {
+ mx = OUTPUT_RECORD_SIZE*SCHART_MULT;
+ }
+ return mx;
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.h b/gnuradio-core/src/lib/io/gr_oscope_guts.h
new file mode 100644
index 000000000..bc9513c7e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_guts.h
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005 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_GR_OSCOPE_GUTS_H
+#define INCLUDED_GR_OSCOPE_GUTS_H
+
+#include <gr_core_api.h>
+#include <gr_trigger_mode.h>
+#include <gr_msg_queue.h>
+
+/*!
+ * \brief guts of oscilloscope trigger and buffer module
+ *
+ * This module processes sets of samples provided the \p process_sample
+ * method. When appropriate given the updateRate, sampleRate and
+ * trigger conditions, process_sample will periodically write output
+ * records of captured data to output_fd. For each trigger event,
+ * nchannels records will be written. Each record consists of
+ * get_samples_per_output_record binary floats. The trigger instant
+ * occurs at the 1/2 way point in the buffer. Thus, output records
+ * consist of 50% pre-trigger data and 50% post-trigger data.
+ */
+
+class GR_CORE_API gr_oscope_guts {
+public:
+ static const int MAX_CHANNELS = 8;
+private:
+ enum scope_state { HOLD_OFF, LOOK_FOR_TRIGGER, POST_TRIGGER };
+
+ int d_nchannels; // how many channels
+ gr_msg_queue_sptr d_msgq; // message queue we stuff output records into
+ gr_trigger_mode d_trigger_mode;
+ gr_trigger_slope d_trigger_slope;
+ int d_trigger_channel; // which channel to watch for trigger condition
+ double d_sample_rate; // input sample rate in Hz
+ double d_update_rate; // approx freq to produce an output record (Hz)
+ double d_trigger_level;
+
+ int d_obi; // output buffer index
+ float *d_buffer[MAX_CHANNELS];
+
+ scope_state d_state;
+ int d_decimator_count;
+ int d_decimator_count_init;
+ int d_hold_off_count;
+ int d_hold_off_count_init;
+ int d_pre_trigger_count;
+ int d_post_trigger_count;
+ int d_post_trigger_count_init;
+ float d_trigger_off; //%sample trigger is off
+
+ // NOT IMPLEMENTED
+ gr_oscope_guts (const gr_oscope_guts &rhs); // no copy constructor
+ gr_oscope_guts &operator= (const gr_oscope_guts &rhs); // no assignment operator
+
+ void trigger_changed ();
+ void update_rate_or_decimation_changed ();
+ bool found_trigger (); // returns true if found
+ void write_output_records ();
+
+ void enter_hold_off (); // called on state entry
+ void enter_look_for_trigger ();
+ void enter_post_trigger ();
+
+public:
+ // CREATORS
+ gr_oscope_guts (double sample_rate, gr_msg_queue_sptr msgq);
+ ~gr_oscope_guts ();
+
+ // MANIPULATORS
+
+ /*!
+ * \p channel_data points to nchannels float values. These are the values
+ * for each channel at this sample time.
+ */
+ void process_sample (const float *channel_data);
+
+ bool set_update_rate (double update_rate);
+ bool set_decimation_count (int decimation_count);
+ bool set_trigger_channel (int channel);
+ bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_slope (gr_trigger_slope slope);
+ bool set_trigger_level (double trigger_level);
+ bool set_trigger_level_auto (); // set to 50% level
+ bool set_sample_rate(double sample_rate);
+ bool set_num_channels(int nchannels);
+
+
+ // ACCESSORS
+ int num_channels () const;
+ double sample_rate () const;
+ double update_rate () const;
+ int get_decimation_count () const;
+ int get_trigger_channel () const;
+ gr_trigger_mode get_trigger_mode () const;
+ gr_trigger_slope get_trigger_slope () const;
+ double get_trigger_level () const;
+
+ // # of samples written to each output record.
+ int get_samples_per_output_record () const;
+};
+
+#endif /* INCLUDED_GR_OSCOPE_GUTS_H */
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink.i b/gnuradio-core/src/lib/io/gr_oscope_sink.i
new file mode 100644
index 000000000..3d7072ed4
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink.i
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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 gr_trigger_mode.h
+
+// GR_SWIG_BLOCK_MAGIC(gr,oscope_sink_x)
+
+%ignore gr_oscope_sink_x;
+class gr_oscope_sink_x : public gr_sync_block
+{
+ protected:
+ gr_oscope_sink_x (const std::string name,
+ gr_io_signature_sptr input_sig,
+ double sample_rate);
+
+ public:
+ ~gr_oscope_sink_x ();
+
+ bool set_update_rate (double update_rate);
+ bool set_decimation_count (int decimation_count);
+ bool set_trigger_channel (int channel);
+ bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_slope (gr_trigger_slope slope);
+ bool set_trigger_level (double trigger_level);
+ bool set_trigger_level_auto (); // set to 50% level
+ bool set_sample_rate(double sample_rate);
+
+ // ACCESSORS
+ int num_channels () const;
+ double sample_rate () const;
+ double update_rate () const;
+ int get_decimation_count () const;
+ int get_trigger_channel () const;
+ gr_trigger_mode get_trigger_mode () const;
+ gr_trigger_slope get_trigger_slope () const;
+ double get_trigger_level () const;
+
+ // # of samples written to each output record.
+ int get_samples_per_output_record () const;
+};
+
+// ----------------------------------------------------------------
+
+GR_SWIG_BLOCK_MAGIC(gr,oscope_sink_f)
+
+gr_oscope_sink_f_sptr
+gr_make_oscope_sink_f (double sample_rate, gr_msg_queue_sptr msgq);
+
+class gr_oscope_sink_f : public gr_oscope_sink_x
+{
+private:
+ gr_oscope_sink_f (double sample_rate, gr_msg_queue_sptr msgq);
+
+public:
+ ~gr_oscope_sink_f ();
+};
+
+// ----------------------------------------------------------------
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc b/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
new file mode 100644
index 000000000..493a25e81
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2005,2010 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
+
+#include <gr_oscope_sink_f.h>
+#include <gr_io_signature.h>
+#include <gr_oscope_guts.h>
+
+
+gr_oscope_sink_f_sptr
+gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq)
+{
+ return gnuradio::get_initial_sptr(new gr_oscope_sink_f (sampling_rate, msgq));
+}
+
+
+gr_oscope_sink_f::gr_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq)
+ : gr_oscope_sink_x ("oscope_sink_f",
+ gr_make_io_signature (1, gr_oscope_guts::MAX_CHANNELS, sizeof (float)),
+ sampling_rate),
+ d_msgq(msgq)
+{
+ d_guts = new gr_oscope_guts (d_sampling_rate, d_msgq);
+}
+
+
+bool
+gr_oscope_sink_f::check_topology (int ninputs, int noutputs)
+{
+ return d_guts->set_num_channels(ninputs);
+}
+
+
+gr_oscope_sink_f::~gr_oscope_sink_f ()
+{
+}
+
+int
+gr_oscope_sink_f::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ int ni = input_items.size ();
+ float tmp[gr_oscope_guts::MAX_CHANNELS];
+
+ for (int i = 0; i < noutput_items; i++){
+
+ // FIXME for now, copy the data. Fix later if reqd
+ for (int ch = 0; ch < ni; ch++)
+ tmp[ch] = ((const float *) input_items[ch])[i];
+
+ d_guts->process_sample (tmp);
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_f.h b/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
new file mode 100644
index 000000000..8d434d2bc
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004,2005 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_GR_OSCOPE_SINK_F_H
+#define INCLUDED_GR_OSCOPE_SINK_F_H
+
+#include <gr_core_api.h>
+#include <gr_oscope_sink_x.h>
+#include <gr_msg_queue.h>
+
+class gr_oscope_sink_f;
+typedef boost::shared_ptr<gr_oscope_sink_x> gr_oscope_sink_f_sptr;
+
+GR_CORE_API gr_oscope_sink_f_sptr gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+
+/*!
+ * \brief Building block for python oscilloscope module.
+ * \ingroup sink_blk
+ *
+ * Accepts multiple float streams.
+ */
+class GR_CORE_API gr_oscope_sink_f : public gr_oscope_sink_x
+{
+private:
+ friend GR_CORE_API gr_oscope_sink_f_sptr
+ gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+ gr_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
+
+ gr_msg_queue_sptr d_msgq;
+
+ public:
+ ~gr_oscope_sink_f ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool check_topology (int ninputs, int noutputs);
+};
+
+#endif /* INCLUDED_GR_OSCOPE_SINK_F_H */
+
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc b/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
new file mode 100644
index 000000000..9580dbf6a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
@@ -0,0 +1,156 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 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
+
+#include <gr_oscope_sink_x.h>
+#include <gr_io_signature.h>
+#include <gr_oscope_guts.h>
+
+
+gr_oscope_sink_x::gr_oscope_sink_x (const std::string name,
+ gr_io_signature_sptr input_sig,
+ double sampling_rate)
+ : gr_sync_block (name, input_sig, gr_make_io_signature (0, 0, 0)),
+ d_sampling_rate (sampling_rate), d_guts (0)
+{
+}
+
+gr_oscope_sink_x::~gr_oscope_sink_x ()
+{
+ delete d_guts;
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_oscope_sink_x::set_update_rate (double update_rate)
+{
+ return d_guts->set_update_rate (update_rate);
+}
+
+bool
+gr_oscope_sink_x::set_decimation_count (int decimation_count)
+{
+ return d_guts->set_decimation_count (decimation_count);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_channel (int channel)
+{
+ return d_guts->set_trigger_channel (channel);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_mode (gr_trigger_mode mode)
+{
+ return d_guts->set_trigger_mode (mode);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_slope (gr_trigger_slope slope)
+{
+ return d_guts->set_trigger_slope (slope);
+}
+
+bool
+gr_oscope_sink_x::set_trigger_level (double trigger_level)
+{
+ return d_guts->set_trigger_level (trigger_level);
+}
+
+
+bool
+gr_oscope_sink_x::set_trigger_level_auto ()
+{
+ return d_guts->set_trigger_level_auto ();
+}
+
+bool
+gr_oscope_sink_x::set_sample_rate (double sample_rate)
+{
+ return d_guts->set_sample_rate (sample_rate);
+}
+
+bool
+gr_oscope_sink_x::set_num_channels (int nchannels)
+{
+ return d_guts->set_num_channels (nchannels);
+}
+
+// ACCESSORS
+
+int
+gr_oscope_sink_x::num_channels () const
+{
+ return d_guts->num_channels ();
+}
+
+double
+gr_oscope_sink_x::sample_rate () const
+{
+ return d_guts->sample_rate ();
+}
+
+double
+gr_oscope_sink_x::update_rate () const
+{
+ return d_guts->update_rate ();
+}
+
+int
+gr_oscope_sink_x::get_decimation_count () const
+{
+ return d_guts->get_decimation_count ();
+}
+
+int
+gr_oscope_sink_x::get_trigger_channel () const
+{
+ return d_guts->get_trigger_channel ();
+}
+
+gr_trigger_mode
+gr_oscope_sink_x::get_trigger_mode () const
+{
+ return d_guts->get_trigger_mode ();
+}
+
+gr_trigger_slope
+gr_oscope_sink_x::get_trigger_slope () const
+{
+ return d_guts->get_trigger_slope ();
+}
+
+double
+gr_oscope_sink_x::get_trigger_level () const
+{
+ return d_guts->get_trigger_level ();
+}
+
+int
+gr_oscope_sink_x::get_samples_per_output_record () const
+{
+ return d_guts->get_samples_per_output_record ();
+}
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_x.h b/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
new file mode 100644
index 000000000..153d0937a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 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_GR_OSCOPE_SINK_X_H
+#define INCLUDED_GR_OSCOPE_SINK_X_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_trigger_mode.h>
+
+class gr_oscope_guts;
+
+/*!
+ * \brief Abstract class for python oscilloscope module.
+ * \ingroup sink_blk
+ *
+ * Don't instantiate this. Use gr_oscope_sink_f or gr_oscope_sink_c instead.
+ */
+class GR_CORE_API gr_oscope_sink_x : public gr_sync_block
+{
+protected:
+ double d_sampling_rate;
+ gr_oscope_guts *d_guts;
+
+ gr_oscope_sink_x (const std::string name,
+ gr_io_signature_sptr input_sig,
+ double sampling_rate);
+
+public:
+ ~gr_oscope_sink_x ();
+
+ bool set_update_rate (double update_rate);
+ bool set_decimation_count (int decimation_count);
+ bool set_trigger_channel (int channel);
+ bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_slope (gr_trigger_slope slope);
+ bool set_trigger_level (double trigger_level);
+ bool set_trigger_level_auto (); // set to 50% level
+ bool set_sample_rate(double sample_rate);
+ bool set_num_channels (int nchannels);
+
+
+ // ACCESSORS
+ int num_channels () const;
+ double sample_rate () const;
+ double update_rate () const;
+ int get_decimation_count () const;
+ int get_trigger_channel () const;
+ gr_trigger_mode get_trigger_mode () const;
+ gr_trigger_slope get_trigger_slope () const;
+ double get_trigger_level () const;
+
+ // # of samples written to each output record.
+ int get_samples_per_output_record () const;
+
+};
+
+#endif /* INCLUDED_GR_OSCOPE_SINK_X_H */
diff --git a/gnuradio-core/src/lib/io/gr_pdu.cc b/gnuradio-core/src/lib/io/gr_pdu.cc
new file mode 100644
index 000000000..302fd7b9b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu.cc
@@ -0,0 +1,79 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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
+
+#include <gr_pdu.h>
+
+size_t
+gr_pdu_itemsize(gr_pdu_vector_type type){
+ switch(type){
+ case pdu_byte:
+ return 1;
+ case pdu_float:
+ return sizeof(float);
+ case pdu_complex:
+ return sizeof(gr_complex);
+ default:
+ throw std::runtime_error("bad type!");
+ }
+}
+
+bool
+gr_pdu_type_matches(gr_pdu_vector_type type, pmt::pmt_t v){
+ switch(type){
+ case pdu_byte:
+ return pmt::pmt_is_u8vector(v);
+ case pdu_float:
+ return pmt::pmt_is_f32vector(v);
+ case pdu_complex:
+ return pmt::pmt_is_c32vector(v);
+ default:
+ throw std::runtime_error("bad type!");
+ }
+}
+
+pmt::pmt_t
+gr_pdu_make_vector(gr_pdu_vector_type type, const uint8_t* buf, size_t items){
+ switch(type){
+ case pdu_byte:
+ return pmt::pmt_init_u8vector(items, buf);
+ case pdu_float:
+ return pmt::pmt_init_f32vector(items, (const float*)buf);
+ case pdu_complex:
+ return pmt::pmt_init_c32vector(items, (const gr_complex*)buf);
+ default:
+ throw std::runtime_error("bad type!");
+ }
+}
+
+gr_pdu_vector_type type_from_pmt(pmt::pmt_t vector){
+ if(pmt_is_u8vector(vector))
+ return pdu_byte;
+ if(pmt_is_f32vector(vector))
+ return pdu_float;
+ if(pmt_is_c32vector(vector))
+ return pdu_complex;
+ throw std::runtime_error("bad type!");
+}
diff --git a/gnuradio-core/src/lib/io/gr_pdu.h b/gnuradio-core/src/lib/io/gr_pdu.h
new file mode 100644
index 000000000..a5ae87db7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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 GR_PDU_H
+#define GR_PDU_H
+
+#include <gr_complex.h>
+#include <gruel/pmt.h>
+
+#define pdu_port_id pmt::mp("pdus")
+#define pdu_length_tag pmt::mp("pdu_length")
+
+enum gr_pdu_vector_type { pdu_byte, pdu_float, pdu_complex };
+
+size_t gr_pdu_itemsize(gr_pdu_vector_type type);
+bool gr_pdu_type_matches(gr_pdu_vector_type type, pmt::pmt_t v);
+pmt::pmt_t gr_pdu_make_vector(gr_pdu_vector_type type, const uint8_t* buf, size_t items);
+gr_pdu_vector_type type_from_pmt(pmt::pmt_t vector);
+
+#endif
diff --git a/gnuradio-core/src/lib/io/gr_pdu.i b/gnuradio-core/src/lib/io/gr_pdu.i
new file mode 100644
index 000000000..ada3a63a7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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 <gr_pdu.h>
+%}
+
+enum gr_pdu_vector_type { pdu_byte, pdu_float, pdu_complex };
+
+
+
diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc
new file mode 100644
index 000000000..5c319dc39
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.cc
@@ -0,0 +1,132 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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
+
+#include <gr_pdu_to_tagged_stream.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+
+
+// public constructor that returns a shared_ptr
+
+gr_pdu_to_tagged_stream_sptr
+gr_make_pdu_to_tagged_stream(gr_pdu_vector_type t)
+{
+ return gnuradio::get_initial_sptr(new gr_pdu_to_tagged_stream(t));
+}
+
+gr_pdu_to_tagged_stream::gr_pdu_to_tagged_stream (gr_pdu_vector_type t)
+ : gr_sync_block("pdu_to_tagged_stream",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, gr_pdu_itemsize(t))),
+ d_vectortype(t), d_itemsize(gr_pdu_itemsize(t))
+{
+ message_port_register_in(pdu_port_id);
+}
+
+gr_pdu_to_tagged_stream::~gr_pdu_to_tagged_stream()
+{
+}
+
+int
+gr_pdu_to_tagged_stream::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ int nout = 0;
+
+ // if we have remaining output, send it
+ if(d_remain.size() > 0){
+ nout = std::min((size_t)d_remain.size()/d_itemsize, (size_t)noutput_items);
+ memcpy(out, &d_remain[0], nout*d_itemsize);
+ d_remain.erase( d_remain.begin(), d_remain.begin()+nout);
+ noutput_items -= nout;
+ out += nout*d_itemsize;
+ }
+
+ // if we have space for at least one item output as much as we can
+ if(noutput_items > 0){
+
+ // grab a message if one exists
+ //pmt::pmt_t msg( delete_head_nowait( pdu_port_id ) );
+ pmt::pmt_t msg( delete_head_blocking( pdu_port_id ) );
+ if(msg.get() == NULL ){
+ return nout;
+ }
+
+ // make sure type is valid
+ if(!pmt::pmt_is_pair(msg)){
+ throw std::runtime_error("received a malformed pdu message!");
+ }
+
+// printf("got a msg\n");
+// pmt::pmt_print(msg);
+
+ // grab the components of the pdu message
+ pmt::pmt_t meta(pmt::pmt_car(msg)); // make sure this is NIL || Dict ?
+ pmt::pmt_t vect(pmt::pmt_cdr(msg)); // make sure this is a vector?
+
+ // compute offset for output tag
+ uint64_t offset = nitems_written(0) + nout;
+
+ // add a tag for pdu length
+ add_item_tag(0, offset, pdu_length_tag, pmt::pmt_from_long( pmt::pmt_length(vect) ), pmt::mp(alias()));
+
+ // if we recieved metadata add it as tags
+ if( !pmt_eq(meta, pmt::PMT_NIL) ){
+ pmt::pmt_t pair(pmt::pmt_dict_keys( meta ));
+ while( !pmt_eq(pair, pmt::PMT_NIL) ){
+ pmt::pmt_t k(pmt::pmt_cdr(pair));
+ pmt::pmt_t v(pmt::pmt_dict_ref(meta, k, pmt::PMT_NIL));
+ add_item_tag(0, offset, k, v, pmt::mp(alias()));
+ }
+ }
+
+ // copy vector output
+ size_t ncopy = std::min((size_t)noutput_items, (size_t)pmt::pmt_length(vect));
+ size_t nsave = pmt::pmt_length(vect) - ncopy;
+
+ // copy output
+ size_t io(0);
+ nout += ncopy;
+ memcpy(out, pmt_uniform_vector_elements(vect,io), ncopy*d_itemsize);
+
+ // save leftover items if needed for next work call
+ if(nsave > 0){
+ d_remain.resize(nsave*d_itemsize, 0);
+ memcpy(&d_remain[0], pmt_uniform_vector_elements(vect,ncopy), nsave*d_itemsize);
+ }
+
+ }
+
+ return nout;
+}
diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h
new file mode 100644
index 000000000..3105a3d38
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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_GR_PDU_TO_TAGGED_STREAM_H
+#define INCLUDED_GR_PDU_TO_TAGGED_STREAM_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gr_pdu.h>
+
+class gr_pdu_to_tagged_stream;
+typedef boost::shared_ptr<gr_pdu_to_tagged_stream> gr_pdu_to_tagged_stream_sptr;
+
+GR_CORE_API gr_pdu_to_tagged_stream_sptr gr_make_pdu_to_tagged_stream (gr_pdu_vector_type t);
+
+/*!
+ * \brief Turn received messages into a stream
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_pdu_to_tagged_stream : public gr_sync_block
+{
+ private:
+ gr_pdu_vector_type d_vectortype;
+ size_t d_itemsize;
+ std::vector<uint8_t> d_remain;
+
+ friend GR_CORE_API gr_pdu_to_tagged_stream_sptr
+ gr_make_pdu_to_tagged_stream(gr_pdu_vector_type t);
+
+ protected:
+ gr_pdu_to_tagged_stream (gr_pdu_vector_type t);
+
+ public:
+ ~gr_pdu_to_tagged_stream ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+};
+
+#endif /* INCLUDED_GR_PDU_TO_TAGGED_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i
new file mode 100644
index 000000000..ec760b309
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_pdu_to_tagged_stream.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,pdu_to_tagged_stream);
+
+%{
+#include <gr_pdu_to_tagged_stream.h>
+%}
+
+%include <gr_pdu_to_tagged_stream.h>
+
+
diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.cc b/gnuradio-core/src/lib/io/gr_socket_pdu.cc
new file mode 100644
index 000000000..bb374b300
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_socket_pdu.cc
@@ -0,0 +1,157 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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
+
+#include <gr_socket_pdu.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+#include <iostream>
+#include <gr_pdu.h>
+#include <boost/format.hpp>
+
+// public constructor that returns a shared_ptr
+gr_socket_pdu_sptr
+gr_make_socket_pdu (std::string type, std::string addr, std::string port, int MTU)
+{
+ return gnuradio::get_initial_sptr(new gr_socket_pdu(type,addr,port,MTU));
+}
+
+gr_socket_pdu::gr_socket_pdu (std::string type, std::string addr, std::string port, int MTU)
+ : gr_stream_pdu_base(MTU)
+{
+
+ if( (type == "TCP_SERVER") || (type == "TCP_CLIENT")){
+ boost::asio::ip::tcp::resolver resolver(_io_service);
+ boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port);
+ _tcp_endpoint = *resolver.resolve(query);
+ }
+ if( (type == "UDP_SERVER") || (type == "UDP_CLIENT")){
+ boost::asio::ip::udp::resolver resolver(_io_service);
+ boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port);
+ if( (type == "UDP_SERVER") ){
+ _udp_endpoint = *resolver.resolve(query);
+ } else {
+ _udp_endpoint_other = *resolver.resolve(query);
+ }
+ }
+
+ // register ports
+ message_port_register_out(pmt::mp("pdus"));
+ message_port_register_in(pmt::mp("pdus"));
+
+ // set up socketry
+ if (type == "TCP_SERVER"){
+ _acceptor_tcp.reset(new boost::asio::ip::tcp::acceptor(_io_service, _tcp_endpoint));
+ _acceptor_tcp->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+ start_tcp_accept();
+ // bind tcp server send handler
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::tcp_server_send, this, _1));
+ } else if(type =="TCP_CLIENT"){
+ boost::system::error_code error = boost::asio::error::host_not_found;
+ _tcp_socket.reset(new boost::asio::ip::tcp::socket(_io_service));
+ _tcp_socket->connect(_tcp_endpoint, error);
+ if(error){
+ throw boost::system::system_error(error);
+ }
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::tcp_client_send, this, _1));
+ _tcp_socket->async_read_some(
+ boost::asio::buffer(rxbuf),
+ boost::bind(&gr_socket_pdu::handle_tcp_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+
+ } else if(type =="UDP_SERVER"){
+ _udp_socket.reset(new boost::asio::ip::udp::socket(_io_service, _udp_endpoint));
+ _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other,
+ boost::bind(&gr_socket_pdu::handle_udp_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::udp_send, this, _1));
+ } else if(type =="UDP_CLIENT"){
+ _udp_socket.reset(new boost::asio::ip::udp::socket(_io_service, _udp_endpoint));
+ _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other,
+ boost::bind(&gr_socket_pdu::handle_udp_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_socket_pdu::udp_send, this, _1));
+ } else {
+ throw std::runtime_error("unknown socket type!");
+ }
+
+ // start thread for io_service
+ d_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&gr_socket_pdu::run_io_service, this)));
+ d_started = true;
+}
+
+void tcp_connection::handle_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred)
+ {
+ if(!error)
+ {
+ pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&buf[0]);
+ pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
+
+ d_block->message_port_pub( pmt::mp("pdus"), pdu );
+
+ socket_.async_read_some(
+ boost::asio::buffer(buf),
+ boost::bind(&tcp_connection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+
+ } else {
+ std::cout << "error occurred\n";
+ }
+
+ }
+
+
+void gr_socket_pdu::tcp_server_send(pmt::pmt_t msg){
+ pmt::pmt_t vector = pmt::pmt_cdr(msg);
+ for(size_t i=0; i<d_tcp_connections.size(); i++){
+ d_tcp_connections[i]->send(vector);
+ }
+}
+
+void gr_socket_pdu::tcp_client_send(pmt::pmt_t msg){
+ pmt::pmt_t vector = pmt::pmt_cdr(msg);
+ size_t len = pmt::pmt_length(vector);
+ size_t offset(0);
+ boost::array<char, 10000> txbuf;
+ memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len);
+ _tcp_socket->send(boost::asio::buffer(txbuf,len));
+}
+
+void gr_socket_pdu::udp_send(pmt::pmt_t msg){
+ pmt::pmt_t vector = pmt::pmt_cdr(msg);
+ size_t len = pmt::pmt_length(vector);
+ size_t offset(0);
+ boost::array<char, 10000> txbuf;
+ memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len);
+ if(_udp_endpoint_other.address().to_string() != "0.0.0.0")
+ _udp_socket->send_to(boost::asio::buffer(txbuf,len), _udp_endpoint_other);
+}
diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.h b/gnuradio-core/src/lib/io/gr_socket_pdu.h
new file mode 100644
index 000000000..2fedb317d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_socket_pdu.h
@@ -0,0 +1,203 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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_GR_SOCKET_PDU_H
+#define INCLUDED_GR_SOCKET_PDU_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gr_stream_pdu_base.h>
+#include <boost/array.hpp>
+#include <boost/asio.hpp>
+#include <iostream>
+
+class gr_socket_pdu;
+typedef boost::shared_ptr<gr_socket_pdu> gr_socket_pdu_sptr;
+
+GR_CORE_API gr_socket_pdu_sptr gr_make_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000);
+
+class tcp_connection
+ : public boost::enable_shared_from_this<tcp_connection>
+{
+public:
+ typedef boost::shared_ptr<tcp_connection> pointer;
+ gr_socket_pdu *d_block;
+ boost::array<char, 10000> buf;
+
+ static pointer create(boost::asio::io_service& io_service)
+ {
+ return pointer(new tcp_connection(io_service));
+ }
+
+ boost::asio::ip::tcp::socket& socket()
+ {
+ return socket_;
+ }
+
+ void start(gr_socket_pdu* parent)
+ {
+ d_block = parent;
+// message_ = "connected to gr_socket_pdu\n";
+// boost::asio::async_write(socket_, boost::asio::buffer(message_),
+// boost::bind(&tcp_connection::handle_write, shared_from_this(),
+// boost::asio::placeholders::error,
+// boost::asio::placeholders::bytes_transferred));
+
+ socket_.async_read_some(
+ boost::asio::buffer(buf),
+ boost::bind(&tcp_connection::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+ }
+ void send(pmt::pmt_t vector){
+ size_t len = pmt::pmt_length(vector);
+ size_t offset(0);
+ boost::array<char, 10000> txbuf;
+ memcpy(&txbuf[0], pmt::pmt_uniform_vector_elements(vector, offset), len);
+ boost::asio::async_write(socket_, boost::asio::buffer(txbuf, len),
+ boost::bind(&tcp_connection::handle_write, shared_from_this(),
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ }
+
+ ~tcp_connection(){
+// std::cout << "tcp_connection destroyed\n";
+ }
+
+private:
+ tcp_connection(boost::asio::io_service& io_service)
+ : socket_(io_service)
+ {
+ }
+
+ void handle_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred);
+
+ void handle_write(const boost::system::error_code& /*error*/,
+ size_t /*bytes_transferred*/)
+ {
+ }
+
+ boost::asio::ip::tcp::socket socket_;
+ std::string message_;
+};
+
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_socket_pdu : public gr_stream_pdu_base
+{
+ private:
+ friend GR_CORE_API gr_socket_pdu_sptr
+ gr_make_socket_pdu(std::string type, std::string addr, std::string port, int MTU);
+
+ boost::asio::io_service _io_service;
+
+ boost::array<char, 10000> rxbuf;
+
+ // tcp specific
+ boost::asio::ip::tcp::endpoint _tcp_endpoint;
+
+ // specific to tcp server
+ boost::shared_ptr<boost::asio::ip::tcp::acceptor> _acceptor_tcp;
+ std::vector<tcp_connection::pointer> d_tcp_connections;
+ void tcp_server_send(pmt::pmt_t msg);
+ void tcp_client_send(pmt::pmt_t msg);
+ void udp_send(pmt::pmt_t msg);
+
+ // specific to tcp client
+ boost::shared_ptr<boost::asio::ip::tcp::socket> _tcp_socket;
+
+ // specific to udp client/server
+ boost::asio::ip::udp::endpoint _udp_endpoint;
+ boost::asio::ip::udp::endpoint _udp_endpoint_other;
+ boost::shared_ptr<boost::asio::ip::udp::socket> _udp_socket;
+
+ void handle_receive(const boost::system::error_code& error, std::size_t ){
+ }
+
+ void start_tcp_accept(){
+ tcp_connection::pointer new_connection =
+ tcp_connection::create(_acceptor_tcp->get_io_service());
+
+ _acceptor_tcp->async_accept(new_connection->socket(),
+ boost::bind(&gr_socket_pdu::handle_tcp_accept, this, new_connection,
+ boost::asio::placeholders::error));
+ }
+
+ void handle_tcp_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error){
+ if (!error)
+ {
+ new_connection->start(this);
+ d_tcp_connections.push_back(new_connection);
+ start_tcp_accept();
+ } else {
+ std::cout << error << std::endl;
+ }
+ }
+
+ void run_io_service(){
+ _io_service.run();
+ }
+
+ void handle_udp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){
+ if(!error){
+ pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]);
+ pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
+
+ message_port_pub( pmt::mp("pdus"), pdu );
+
+ _udp_socket->async_receive_from( boost::asio::buffer(rxbuf), _udp_endpoint_other,
+ boost::bind(&gr_socket_pdu::handle_udp_read, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ } else {
+ throw boost::system::system_error(error);
+// std::cout << "error occurred\n";
+ }
+ }
+ void handle_tcp_read(const boost::system::error_code& error/*error*/, size_t bytes_transferred){
+ if(!error)
+ {
+ pmt::pmt_t vector = pmt::pmt_init_u8vector(bytes_transferred, (const uint8_t*)&rxbuf[0]);
+ pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
+
+ message_port_pub( pmt::mp("pdus"), pdu );
+
+ _tcp_socket->async_read_some(
+ boost::asio::buffer(rxbuf),
+ boost::bind(&gr_socket_pdu::handle_tcp_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+
+ } else {
+ //std::cout << "error occurred\n";
+ throw boost::system::system_error(error);
+ }
+ }
+
+ protected:
+ gr_socket_pdu (std::string type, std::string addr, std::string port, int MTU=10000);
+ public:
+ ~gr_socket_pdu () {}
+};
+
+#endif /* INCLUDED_GR_TUNTAP_PDU_H */
diff --git a/gnuradio-core/src/lib/io/gr_socket_pdu.i b/gnuradio-core/src/lib/io/gr_socket_pdu.i
new file mode 100644
index 000000000..3e20b63e2
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_socket_pdu.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,socket_pdu);
+
+%ignore tcp_connection;
+
+%{
+#include <gr_socket_pdu.h>
+%}
+
+%include "gr_stream_pdu_base.h"
+%include "gr_socket_pdu.h"
+
diff --git a/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc b/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc
new file mode 100644
index 000000000..7250c33e5
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_stream_pdu_base.cc
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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
+
+#include <ciso646>
+#include <gr_stream_pdu_base.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+#include <iostream>
+#include <gr_pdu.h>
+#include <boost/asio.hpp>
+#include <boost/format.hpp>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+static const long timeout_us = 100*1000; //100ms
+
+gr_stream_pdu_base::gr_stream_pdu_base (int MTU)
+ : gr_sync_block("stream_pdu_base",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(0, 0, 0)),
+ d_finished(false), d_started(false), d_fd(-1)
+{
+ // reserve space for rx buffer
+ d_rxbuf.resize(MTU,0);
+}
+
+gr_stream_pdu_base::~gr_stream_pdu_base()
+{
+ stop_rxthread();
+}
+
+void gr_stream_pdu_base::stop_rxthread(){
+ d_finished = true;
+ if(d_started){
+ d_thread->interrupt();
+ d_thread->join();
+ }
+ }
+
+void gr_stream_pdu_base::start_rxthread(pmt::pmt_t _rxport){
+ rxport = _rxport;
+ d_thread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&gr_stream_pdu_base::run, this)));
+ d_started = true;
+ }
+
+void gr_stream_pdu_base::run(){
+ while(!d_finished) {
+ if(not wait_ready()){ continue; }
+ const int result = read( d_fd, &d_rxbuf[0], d_rxbuf.size() );
+ if(result <= 0){ throw std::runtime_error("gr_stream_pdu_base, bad socket read!"); }
+ pmt::pmt_t vector = pmt::pmt_init_u8vector(result, &d_rxbuf[0]);
+ pmt::pmt_t pdu = pmt::pmt_cons( pmt::PMT_NIL, vector);
+ message_port_pub(rxport, pdu);
+ }
+}
+
+void gr_stream_pdu_base::send(pmt::pmt_t msg){
+ pmt::pmt_t vector = pmt::pmt_cdr(msg);
+ size_t offset(0);
+ size_t itemsize(gr_pdu_itemsize(type_from_pmt(vector)));
+ int len( pmt::pmt_length(vector)*itemsize );
+
+ const int rv = write(d_fd, pmt::pmt_uniform_vector_elements(vector, offset), len);
+ if(rv != len){
+ std::cerr << boost::format("WARNING: gr_stream_pdu_base::send(pdu) write failed! (d_fd=%d, len=%d, rv=%d)")
+ % d_fd % len % rv << std::endl;
+ }
+}
+
+int
+gr_stream_pdu_base::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ throw std::runtime_error("should not be called.\n");
+ return 0;
+}
+
+bool gr_stream_pdu_base::wait_ready(){
+ //setup timeval for timeout
+ timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = timeout_us;
+
+ //setup rset for timeout
+ fd_set rset;
+ FD_ZERO(&rset);
+ FD_SET(d_fd, &rset);
+
+ //call select with timeout on receive socket
+ return ::select(d_fd+1, &rset, NULL, NULL, &tv) > 0;
+}
diff --git a/gnuradio-core/src/lib/io/gr_stream_pdu_base.h b/gnuradio-core/src/lib/io/gr_stream_pdu_base.h
new file mode 100644
index 000000000..35bacf523
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_stream_pdu_base.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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_GR_STREAM_PDU_BASE_H
+#define INCLUDED_GR_STREAM_PDU_BASE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_stream_pdu_base : public gr_sync_block
+{
+ public:
+ boost::shared_ptr<boost::thread> d_thread;
+ bool d_finished;
+ bool d_started;
+ std::vector<uint8_t> d_rxbuf;
+ void run();
+ int d_fd;
+ gr_stream_pdu_base (int MTU=10000);
+ ~gr_stream_pdu_base ();
+ void send(pmt::pmt_t msg);
+ bool wait_ready();
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ void start_rxthread(pmt::pmt_t _rxport);
+ void stop_rxthread();
+ private:
+ pmt::pmt_t rxport;
+};
+
+typedef boost::shared_ptr<gr_stream_pdu_base> gr_stream_pdu_base_sptr;
+
+#endif /* INCLUDED_GR_TUNTAP_PDU_H */
diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc
new file mode 100644
index 000000000..6d642088e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc
@@ -0,0 +1,216 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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
+
+#include <gr_tagged_file_sink.h>
+#include <gr_io_signature.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <iostream>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+
+gr_tagged_file_sink::gr_tagged_file_sink (size_t itemsize, double samp_rate)
+ : gr_sync_block ("tagged_file_sink",
+ gr_make_io_signature (1, 1, itemsize),
+ gr_make_io_signature (0, 0, 0)),
+ d_itemsize (itemsize), d_n(0), d_sample_rate(samp_rate)
+{
+ d_state = NOT_IN_BURST;
+ d_last_N = 0;
+ d_timeval = 0;
+}
+
+gr_tagged_file_sink_sptr
+gr_make_tagged_file_sink (size_t itemsize, double samp_rate)
+{
+ return gnuradio::get_initial_sptr(new gr_tagged_file_sink (itemsize, samp_rate));
+}
+
+gr_tagged_file_sink::~gr_tagged_file_sink ()
+{
+}
+
+int
+gr_tagged_file_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *inbuf = (char *) input_items[0];
+
+ uint64_t start_N = nitems_read(0);
+ uint64_t end_N = start_N + (uint64_t)(noutput_items);
+ pmt::pmt_t bkey = pmt::pmt_string_to_symbol("burst");
+ //pmt::pmt_t tkey = pmt::pmt_string_to_symbol("time"); // use gr_tags::key_time
+
+ std::vector<gr_tag_t> all_tags;
+ get_tags_in_range(all_tags, 0, start_N, end_N);
+
+ std::sort(all_tags.begin(), all_tags.end(), gr_tag_t::offset_compare);
+
+ std::vector<gr_tag_t>::iterator vitr = all_tags.begin();
+
+ int idx = 0, idx_stop = 0;
+ while(idx < noutput_items) {
+ if(d_state == NOT_IN_BURST) {
+ while(vitr != all_tags.end()) {
+ if((pmt::pmt_eqv((*vitr).key, bkey)) &&
+ pmt::pmt_is_true((*vitr).value)) {
+
+ uint64_t N = (*vitr).offset;
+ idx = (int)(N - start_N);
+
+ //std::cout << std::endl << "Found start of burst: "
+ // << idx << ", " << N << std::endl;
+
+ // Find time burst occurred by getting latest time tag and extrapolating
+ // to new time based on sample rate of this block.
+ std::vector<gr_tag_t> time_tags;
+ //get_tags_in_range(time_tags, 0, d_last_N, N, gr_tags::key_time);
+ get_tags_in_range(time_tags, 0, d_last_N, N,
+ pmt::pmt_string_to_symbol("time"));
+ if(time_tags.size() > 0) {
+ const gr_tag_t tag = time_tags[time_tags.size()-1];
+
+ uint64_t time_nitems = tag.offset;
+
+ // Get time based on last time tag from USRP
+ pmt::pmt_t time = tag.value;
+ int tsecs = pmt::pmt_to_long(pmt::pmt_tuple_ref(time, 0));
+ double tfrac = pmt::pmt_to_double(pmt::pmt_tuple_ref(time, 1));
+
+ // Get new time from last time tag + difference in time to when
+ // burst tag occured based on the sample rate
+ double delta = (double)(N - time_nitems) / d_sample_rate;
+ d_timeval = (double)tsecs + tfrac + delta;
+
+ //std::cout.setf(std::ios::fixed, std::ios::floatfield);
+ //std::cout.precision(8);
+ //std::cout << "Time found: " << (double)tsecs + tfrac << std::endl;
+ //std::cout << " time: " << d_timeval << std::endl;
+ //std::cout << " time at N = " << time_nitems << " burst N = " << N << std::endl;
+ }
+ else {
+ // if no time tag, use last seen tag and update time based on
+ // sample rate of the block
+ d_timeval += (double)(N - d_last_N) / d_sample_rate;
+ //std::cout << "Time not found" << std::endl;
+ //std::cout << " time: " << d_timeval << std::endl;
+ }
+ d_last_N = N;
+
+ std::stringstream filename;
+ filename.setf(std::ios::fixed, std::ios::floatfield);
+ filename.precision(8);
+ filename << "file" << unique_id() << "_" << d_n << "_" << d_timeval << ".dat";
+ d_n++;
+
+ int fd;
+ if ((fd = ::open (filename.str().c_str(),
+ O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY,
+ 0664)) < 0){
+ perror (filename.str().c_str());
+ return -1;
+ }
+
+ // FIXME:
+ //if ((d_handle = fdopen (fd, d_is_binary ? "wb" : "w")) == NULL){
+ if ((d_handle = fdopen (fd, "wb")) == NULL){
+ perror (filename.str().c_str());
+ ::close(fd); // don't leak file descriptor if fdopen fails.
+ }
+
+ //std::cout << "Created new file: " << filename.str() << std::endl;
+
+ d_state = IN_BURST;
+ break;
+ }
+
+ vitr++;
+ }
+ if(d_state == NOT_IN_BURST)
+ return noutput_items;
+ }
+ else { // In burst
+ while(vitr != all_tags.end()) {
+ if((pmt::pmt_eqv((*vitr).key, bkey)) &&
+ pmt::pmt_is_false((*vitr).value)) {
+ uint64_t N = (*vitr).offset;
+ idx_stop = (int)N - start_N;
+
+ //std::cout << "Found end of burst: "
+ // << idx_stop << ", " << N << std::endl;
+
+ int count = fwrite (&inbuf[d_itemsize*idx], d_itemsize,
+ idx_stop-idx, d_handle);
+ if (count == 0) {
+ if(ferror(d_handle)) {
+ perror("gr_tagged_file_sink: error writing file");
+ }
+ }
+ idx = idx_stop;
+ d_state = NOT_IN_BURST;
+ vitr++;
+ fclose(d_handle);
+ break;
+ }
+ else {
+ vitr++;
+ }
+ }
+ if(d_state == IN_BURST) {
+ int count = fwrite (&inbuf[d_itemsize*idx], d_itemsize,
+ noutput_items-idx, d_handle);
+ if (count == 0) {
+ if(ferror(d_handle)) {
+ perror("gr_tagged_file_sink: error writing file");
+ }
+ }
+ idx = noutput_items;
+ }
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.h b/gnuradio-core/src/lib/io/gr_tagged_file_sink.h
new file mode 100644
index 000000000..d6f931a67
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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_GR_TAGGED_FILE_SINK_H
+#define INCLUDED_GR_TAGGED_FILE_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <cstdio> // for FILE
+
+class gr_tagged_file_sink;
+typedef boost::shared_ptr<gr_tagged_file_sink> gr_tagged_file_sink_sptr;
+
+GR_CORE_API gr_tagged_file_sink_sptr gr_make_tagged_file_sink (size_t itemsize,
+ double samp_rate);
+
+/*!
+ * \brief Write stream to file descriptor.
+ * \ingroup sink_blk
+ */
+
+class GR_CORE_API gr_tagged_file_sink : public gr_sync_block
+{
+ friend GR_CORE_API gr_tagged_file_sink_sptr gr_make_tagged_file_sink (size_t itemsize,
+ double samp_rate);
+
+ private:
+ enum {
+ NOT_IN_BURST = 0,
+ IN_BURST
+ };
+
+ size_t d_itemsize;
+ int d_state;
+ FILE *d_handle;
+ int d_n;
+ double d_sample_rate;
+ uint64_t d_last_N;
+ double d_timeval;
+
+ protected:
+ gr_tagged_file_sink (size_t itemsize, double samp_rate);
+
+ public:
+ ~gr_tagged_file_sink ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_TAGGED_FILE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.i b/gnuradio-core/src/lib/io/gr_tagged_file_sink.i
new file mode 100644
index 000000000..2f2596e12
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,tagged_file_sink)
+
+gr_tagged_file_sink_sptr
+gr_make_tagged_file_sink (size_t itemsize, double samp_rate);
+
+class gr_tagged_file_sink : public gr_sync_block
+{
+ protected:
+ gr_tagged_file_sink (size_t itemsize, double samp_rate);
+
+ public:
+ ~gr_tagged_file_sink ();
+};
diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc
new file mode 100644
index 000000000..8211b7672
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.cc
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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
+
+#include <gr_tagged_stream_to_pdu.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+
+// public constructor that returns a shared_ptr
+
+gr_tagged_stream_to_pdu_sptr
+gr_make_tagged_stream_to_pdu(gr_pdu_vector_type t)
+{
+ return gnuradio::get_initial_sptr(new gr_tagged_stream_to_pdu(t));
+}
+
+gr_tagged_stream_to_pdu::gr_tagged_stream_to_pdu (gr_pdu_vector_type t)
+ : gr_sync_block("tagged_stream_to_pdu",
+ gr_make_io_signature(1, 1, gr_pdu_itemsize(t)),
+ gr_make_io_signature(0, 0, 0)),
+ d_vectortype(t), d_itemsize(gr_pdu_itemsize(t)), d_inpdu(false),
+ d_pdu_meta(pmt::PMT_NIL), d_pdu_vector(pmt::PMT_NIL)
+{
+ message_port_register_out(pdu_port_id);
+}
+
+gr_tagged_stream_to_pdu::~gr_tagged_stream_to_pdu()
+{
+ printf("destructor running\n");
+}
+
+int
+gr_tagged_stream_to_pdu::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const uint8_t *in = (const uint8_t*) input_items[0];
+ uint64_t abs_N = nitems_read(0);
+
+ // if we are not in a pdu already, start a new one
+ if(!d_inpdu){
+ get_tags_in_range(d_tags, 0, abs_N, abs_N+1);
+ bool found_length_tag(false);
+ for(d_tags_itr = d_tags.begin(); (d_tags_itr != d_tags.end()) && (!found_length_tag); d_tags_itr++){
+ if( pmt::pmt_equal( (*d_tags_itr).key, pdu_length_tag ) ){
+ if( (*d_tags_itr).offset != abs_N ){
+ throw std::runtime_error("expected next pdu length tag on a different item...");
+ }
+ found_length_tag = true;
+ d_pdu_length = pmt::pmt_to_long( (*d_tags_itr).value );
+ d_pdu_remain = d_pdu_length;
+ d_pdu_meta = pmt::pmt_make_dict();
+ break;
+ } // if have length tag
+ } // iter over tags
+ if(!found_length_tag){
+ throw std::runtime_error("tagged stream does not contain a pdu_length tag!");
+ }
+ }
+
+ size_t ncopy = std::min((size_t)noutput_items, d_pdu_remain);
+
+ // copy any tags in this range into our meta object
+ get_tags_in_range(d_tags, 0, abs_N, abs_N+ncopy);
+ for(d_tags_itr = d_tags.begin(); d_tags_itr != d_tags.end(); d_tags_itr++){
+ if( ! pmt_equal( (*d_tags_itr).key, pdu_length_tag ) ){
+ d_pdu_meta = pmt_dict_add(d_pdu_meta, (*d_tags_itr).key, (*d_tags_itr).value);
+ }
+ }
+
+ // copy samples for this vector into either a pmt or our save buffer
+ if(ncopy == d_pdu_remain){ // we will send this pdu
+ if(d_save.size() == 0){
+ d_pdu_vector = gr_pdu_make_vector(d_vectortype, in, ncopy);
+ send_message();
+ } else {
+ size_t oldsize = d_save.size();
+ d_save.resize((oldsize + ncopy)*d_itemsize, 0);
+ memcpy( &d_save[oldsize*d_itemsize], in, ncopy*d_itemsize );
+ d_pdu_vector = gr_pdu_make_vector(d_vectortype, &d_save[0], d_pdu_length);
+ send_message();
+ d_save.clear();
+ }
+ } else {
+ d_inpdu = true;
+ size_t oldsize = d_save.size();
+ d_save.resize( (oldsize+ncopy)*d_itemsize );
+ memcpy( &d_save[oldsize*d_itemsize], in, ncopy*d_itemsize );
+ d_pdu_remain -= ncopy;
+ }
+
+ return ncopy;
+}
+
+void gr_tagged_stream_to_pdu::send_message(){
+
+ if(pmt::pmt_length(d_pdu_vector) != d_pdu_length){
+ throw std::runtime_error("msg length not correct");
+ }
+
+ pmt::pmt_t msg = pmt::pmt_cons( d_pdu_meta, d_pdu_vector );
+ message_port_pub( pdu_port_id, msg );
+
+ d_pdu_meta = pmt::PMT_NIL;
+ d_pdu_vector = pmt::PMT_NIL;
+ d_pdu_length = 0;
+ d_pdu_remain = 0;
+ d_inpdu = false;
+}
diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h
new file mode 100644
index 000000000..c3fff3581
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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_GR_TAGGED_STREAM_TO_PDU_H
+#define INCLUDED_GR_TAGGED_STREAM_TO_PDU_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gr_pdu.h>
+
+class gr_tagged_stream_to_pdu;
+typedef boost::shared_ptr<gr_tagged_stream_to_pdu> gr_tagged_stream_to_pdu_sptr;
+
+GR_CORE_API gr_tagged_stream_to_pdu_sptr gr_make_tagged_stream_to_pdu (gr_pdu_vector_type t);
+
+/*!
+ * \brief Turn received messages into a stream
+ * \ingroup source_blk
+ */
+class GR_CORE_API gr_tagged_stream_to_pdu : public gr_sync_block
+{
+ private:
+ gr_pdu_vector_type d_vectortype;
+ size_t d_itemsize;
+
+ std::vector<uint8_t> d_save;
+
+ std::vector<gr_tag_t> d_tags;
+ std::vector<gr_tag_t>::iterator d_tags_itr;
+
+ bool d_inpdu;
+
+ size_t d_pdu_length;
+ size_t d_pdu_remain;
+ pmt::pmt_t d_pdu_meta;
+ pmt::pmt_t d_pdu_vector;
+
+ friend GR_CORE_API gr_tagged_stream_to_pdu_sptr
+ gr_make_tagged_stream_to_pdu(gr_pdu_vector_type t);
+
+ protected:
+ gr_tagged_stream_to_pdu (gr_pdu_vector_type t);
+
+ public:
+ ~gr_tagged_stream_to_pdu ();
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ void send_message();
+
+};
+
+#endif /* INCLUDED_GR_PDU_TO_TAGGED_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i
new file mode 100644
index 000000000..f12987b74
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tagged_stream_to_pdu.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,tagged_stream_to_pdu);
+
+%{
+#include <gr_tagged_stream_to_pdu.h>
+%}
+
+%include <gr_tagged_stream_to_pdu.h>
+
+
diff --git a/gnuradio-core/src/lib/io/gr_trigger_mode.h b/gnuradio-core/src/lib/io/gr_trigger_mode.h
new file mode 100644
index 000000000..be131686b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_trigger_mode.h
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 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_GR_TRIGGER_MODE_H
+#define INCLUDED_GR_TRIGGER_MODE_H
+
+enum gr_trigger_mode {
+ gr_TRIG_MODE_FREE,
+ gr_TRIG_MODE_AUTO,
+ gr_TRIG_MODE_NORM,
+ gr_TRIG_MODE_STRIPCHART,
+};
+
+enum gr_trigger_slope {
+ gr_TRIG_SLOPE_POS,
+ gr_TRIG_SLOPE_NEG,
+};
+
+#endif /* INCLUDED_GR_TRIGGER_MODE_H */
diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc b/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc
new file mode 100644
index 000000000..8dd4b18a1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.cc
@@ -0,0 +1,145 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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
+
+#include <gr_tuntap_pdu.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <string.h>
+#include <iostream>
+#include <gr_pdu.h>
+#include <boost/format.hpp>
+
+#if (defined(linux) || defined(__linux) || defined(__linux__))
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <arpa/inet.h>
+#include <linux/if.h>
+
+
+// public constructor that returns a shared_ptr
+
+gr_tuntap_pdu_sptr
+gr_make_tuntap_pdu (std::string dev, int MTU)
+{
+ return gnuradio::get_initial_sptr(new gr_tuntap_pdu(dev, MTU));
+}
+
+gr_tuntap_pdu::gr_tuntap_pdu (std::string dev, int MTU)
+ : gr_stream_pdu_base(MTU)
+{
+
+ // make the tuntap
+ char dev_cstr[1024];
+ memset(dev_cstr, 0x00, 1024);
+ strncpy(dev_cstr, dev.c_str(), std::min(sizeof(dev_cstr), dev.size()));
+ d_fd = tun_alloc(dev_cstr);
+ if(d_fd <= 0){
+ throw std::runtime_error("TunTap make: tun_alloc failed (are you running as root?)");
+ }
+
+ std::cout << boost::format(
+ "Allocated virtual ethernet interface: %s\n"
+ "You must now use ifconfig to set its IP address. E.g.,\n"
+ " $ sudo ifconfig %s 192.168.200.1\n"
+ "Be sure to use a different address in the same subnet for each machine.\n"
+ ) % dev % dev << std::endl;
+
+ // set up output message port
+ message_port_register_out(pmt::mp("pdus"));
+ start_rxthread(pmt::mp("pdus"));
+
+ // set up input message port
+ message_port_register_in(pmt::mp("pdus"));
+ set_msg_handler(pmt::mp("pdus"), boost::bind(&gr_tuntap_pdu::send, this, _1));
+}
+
+
+int gr_tuntap_pdu::tun_alloc(char *dev, int flags) {
+ struct ifreq ifr;
+ int fd, err;
+ const char *clonedev = "/dev/net/tun";
+
+ /* Arguments taken by the function:
+ *
+ * char *dev: the name of an interface (or '\0'). MUST have enough
+ * space to hold the interface name if '\0' is passed
+ * int flags: interface flags (eg, IFF_TUN etc.)
+ */
+
+ /* open the clone device */
+ if( (fd = open(clonedev, O_RDWR)) < 0 ) {
+ return fd;
+ }
+
+ /* preparation of the struct ifr, of type "struct ifreq" */
+ memset(&ifr, 0, sizeof(ifr));
+
+ ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */
+
+ if (*dev) {
+ /* if a device name was specified, put it in the structure; otherwise,
+ * the kernel will try to allocate the "next" device of the
+ * specified type */
+ strncpy(ifr.ifr_name, dev, IFNAMSIZ);
+ }
+
+ /* try to create the device */
+ if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
+ close(fd);
+ return err;
+ }
+
+ /* if the operation was successful, write back the name of the
+ * interface to the variable "dev", so the caller can know
+ * it. Note that the caller MUST reserve space in *dev (see calling
+ * code below) */
+ strcpy(dev, ifr.ifr_name);
+
+ /* this is the special file descriptor that the caller will use to talk
+ * with the virtual interface */
+ return fd;
+}
+
+#else //if not linux
+
+gr_block_sptr
+gr_make_tuntap_pdu(std::string dev, int MTU)
+{
+ gr_block_sptr rv;
+ throw std::runtime_error("tuntap only implemented on linux");
+ return rv;
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.h b/gnuradio-core/src/lib/io/gr_tuntap_pdu.h
new file mode 100644
index 000000000..18c83f42b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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_GR_TUNTAP_PDU_H
+#define INCLUDED_GR_TUNTAP_PDU_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_message.h>
+#include <gr_msg_queue.h>
+#include <gr_stream_pdu_base.h>
+
+#if (defined(linux) || defined(__linux) || defined(__linux__))
+
+#include <linux/if_tun.h>
+
+class gr_tuntap_pdu;
+typedef boost::shared_ptr<gr_tuntap_pdu> gr_tuntap_pdu_sptr;
+
+GR_CORE_API gr_tuntap_pdu_sptr gr_make_tuntap_pdu (std::string dev, int MTU=10000);
+
+/*!
+ * \brief Gather received items into messages and insert into msgq
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_tuntap_pdu : public gr_stream_pdu_base
+{
+ private:
+ friend GR_CORE_API gr_tuntap_pdu_sptr
+ gr_make_tuntap_pdu(std::string dev, int MTU);
+ int tun_alloc(char* dev, int flags = IFF_TAP | IFF_NO_PI);
+ std::string d_dev;
+ protected:
+ gr_tuntap_pdu (std::string dev, int MTU=10000);
+
+ public:
+ ~gr_tuntap_pdu () {}
+
+};
+
+#else // if not linux
+
+class gr_tuntap_pdu
+{
+private:
+ gr_tuntap_pdu() {};
+public:
+ ~gr_tuntap_pdu() {};
+};
+
+GR_CORE_API gr_block_sptr gr_make_tuntap_pdu (std::string dev, int MTU=0);
+
+#endif
+
+#endif /* INCLUDED_GR_TUNTAP_PDU_H */
diff --git a/gnuradio-core/src/lib/io/gr_tuntap_pdu.i b/gnuradio-core/src/lib/io/gr_tuntap_pdu.i
new file mode 100644
index 000000000..589bbc385
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_tuntap_pdu.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,tuntap_pdu);
+
+%{
+#include <gr_tuntap_pdu.h>
+%}
+
+%include "gr_tuntap_pdu.h"
+
diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.cc b/gnuradio-core/src/lib/io/gr_udp_sink.cc
new file mode 100644
index 000000000..6b1d34ef7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_sink.cc
@@ -0,0 +1,304 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009,2010 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 <boost/asio.hpp>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_udp_sink.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#if defined(HAVE_NETDB_H)
+#include <netdb.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h> //usually included by <netdb.h>?
+#endif
+typedef void* optval_t;
+#elif defined(HAVE_WINDOWS_H)
+// if not posix, assume winsock
+#define USING_WINSOCK
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#define SHUT_RDWR 2
+typedef char* optval_t;
+#endif
+
+#include <gruel/thread.h>
+
+#define SNK_VERBOSE 0
+
+static int is_error( int perr )
+{
+ // Compare error to posix error code; return nonzero if match.
+#if defined(USING_WINSOCK)
+#define ENOPROTOOPT 109
+#define ECONNREFUSED 111
+ // All codes to be checked for must be defined below
+ int werr = WSAGetLastError();
+ switch( werr ) {
+ case WSAETIMEDOUT:
+ return( perr == EAGAIN );
+ case WSAENOPROTOOPT:
+ return( perr == ENOPROTOOPT );
+ case WSAECONNREFUSED:
+ return( perr == ECONNREFUSED );
+ default:
+ fprintf(stderr,"gr_udp_source/is_error: unknown error %d\n", perr );
+ throw std::runtime_error("internal error");
+ }
+ return 0;
+#else
+ return( perr == errno );
+#endif
+}
+
+static void report_error( const char *msg1, const char *msg2 )
+{
+ // Deal with errors, both posix and winsock
+#if defined(USING_WINSOCK)
+ int werr = WSAGetLastError();
+ fprintf(stderr, "%s: winsock error %d\n", msg1, werr );
+#else
+ perror(msg1);
+#endif
+ if( msg2 != NULL )
+ throw std::runtime_error(msg2);
+ return;
+}
+
+gr_udp_sink::gr_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size, bool eof)
+ : gr_sync_block ("udp_sink",
+ gr_make_io_signature (1, 1, itemsize),
+ gr_make_io_signature (0, 0, 0)),
+ d_itemsize (itemsize), d_payload_size(payload_size), d_eof(eof),
+ d_socket(-1), d_connected(false)
+{
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+ // initialize winsock DLL
+ WSADATA wsaData;
+ int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
+ if( iResult != NO_ERROR ) {
+ report_error( "gr_udp_source WSAStartup", "can't open socket" );
+ }
+#endif
+
+ // create socket
+ d_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if(d_socket == -1) {
+ report_error("socket open","can't open socket");
+ }
+
+ // Don't wait when shutting down
+ linger lngr;
+ lngr.l_onoff = 1;
+ lngr.l_linger = 0;
+ if(setsockopt(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) {
+ if( !is_error(ENOPROTOOPT) ) { // no SO_LINGER for SOCK_DGRAM on Windows
+ report_error("SO_LINGER","can't set socket option SO_LINGER");
+ }
+ }
+
+ // Get the destination address
+ connect(host, port);
+}
+
+// public constructor that returns a shared_ptr
+
+gr_udp_sink_sptr
+gr_make_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size, bool eof)
+{
+ return gnuradio::get_initial_sptr(new gr_udp_sink (itemsize,
+ host, port,
+ payload_size, eof));
+}
+
+gr_udp_sink::~gr_udp_sink ()
+{
+ if (d_connected)
+ disconnect();
+
+ if (d_socket != -1){
+ shutdown(d_socket, SHUT_RDWR);
+#if defined(USING_WINSOCK)
+ closesocket(d_socket);
+#else
+ ::close(d_socket);
+#endif
+ d_socket = -1;
+ }
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+ // free winsock resources
+ WSACleanup();
+#endif
+}
+
+int
+gr_udp_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *in = (const char *) input_items[0];
+ ssize_t r=0, bytes_sent=0, bytes_to_send=0;
+ ssize_t total_size = noutput_items*d_itemsize;
+
+ #if SNK_VERBOSE
+ printf("Entered udp_sink\n");
+ #endif
+
+ gruel::scoped_lock guard(d_mutex); // protect d_socket
+
+ while(bytes_sent < total_size) {
+ bytes_to_send = std::min((ssize_t)d_payload_size, (total_size-bytes_sent));
+
+ if(d_connected) {
+ r = send(d_socket, (in+bytes_sent), bytes_to_send, 0);
+ if(r == -1) { // error on send command
+ if( is_error(ECONNREFUSED) )
+ r = bytes_to_send; // discard data until receiver is started
+ else {
+ report_error("udp_sink",NULL); // there should be no error case where
+ return -1; // this function should not exit immediately
+ }
+ }
+ }
+ else
+ r = bytes_to_send; // discarded for lack of connection
+ bytes_sent += r;
+
+ #if SNK_VERBOSE
+ printf("\tbyte sent: %d bytes\n", r);
+ #endif
+ }
+
+ #if SNK_VERBOSE
+ printf("Sent: %d bytes (noutput_items: %d)\n", bytes_sent, noutput_items);
+ #endif
+
+ return noutput_items;
+}
+
+void gr_udp_sink::connect( const char *host, unsigned short port )
+{
+ if(d_connected)
+ disconnect();
+
+ if(host != NULL ) {
+ // Get the destination address
+ struct addrinfo *ip_dst;
+ struct addrinfo hints;
+ memset( (void*)&hints, 0, sizeof(hints) );
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ char port_str[12];
+ sprintf( port_str, "%d", port );
+
+ // FIXME leaks if report_error throws below
+ int ret = getaddrinfo( host, port_str, &hints, &ip_dst );
+ if( ret != 0 )
+ report_error("gr_udp_source/getaddrinfo",
+ "can't initialize destination socket" );
+
+ // don't need d_mutex lock when !d_connected
+ if(::connect(d_socket, ip_dst->ai_addr, ip_dst->ai_addrlen) == -1) {
+ report_error("socket connect","can't connect to socket");
+ }
+ d_connected = true;
+
+ freeaddrinfo(ip_dst);
+ }
+
+ return;
+}
+
+void gr_udp_sink::disconnect()
+{
+ if(!d_connected)
+ return;
+
+ #if SNK_VERBOSE
+ printf("gr_udp_sink disconnecting\n");
+ #endif
+
+ gruel::scoped_lock guard(d_mutex); // protect d_socket from work()
+
+ // Send a few zero-length packets to signal receiver we are done
+ if(d_eof) {
+ int i;
+ for( i = 0; i < 3; i++ )
+ (void) send( d_socket, NULL, 0, 0 ); // ignore errors
+ }
+
+ // Sending EOF can produce ERRCONNREFUSED errors that won't show up
+ // until the next send or recv, which might confuse us if it happens
+ // on a new connection. The following does a nonblocking recv to
+ // clear any such errors.
+ timeval timeout;
+ timeout.tv_sec = 0; // zero time for immediate return
+ timeout.tv_usec = 0;
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(d_socket, &readfds);
+ int r = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
+ if(r < 0) {
+ #if SNK_VERBOSE
+ report_error("udp_sink/select",NULL);
+ #endif
+ }
+ else if(r > 0) { // call recv() to get error return
+ r = recv(d_socket, (char*)&readfds, sizeof(readfds), 0);
+ if(r < 0) {
+ #if SNK_VERBOSE
+ report_error("udp_sink/recv",NULL);
+ #endif
+ }
+ }
+
+ // Since I can't find any way to disconnect a datagram socket in Cygwin,
+ // we just leave it connected but disable sending.
+#if 0
+ // zeroed address structure should reset connection
+ struct sockaddr addr;
+ memset( (void*)&addr, 0, sizeof(addr) );
+ // addr.sa_family = AF_UNSPEC; // doesn't work on Cygwin
+ // addr.sa_family = AF_INET; // doesn't work on Cygwin
+
+ if(::connect(d_socket, &addr, sizeof(addr)) == -1)
+ report_error("socket connect","can't connect to socket");
+#endif
+
+ d_connected = false;
+
+ return;
+}
diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.h b/gnuradio-core/src/lib/io/gr_udp_sink.h
new file mode 100644
index 000000000..bf042a6d1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_sink.h
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009,2010 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_GR_UDP_SINK_H
+#define INCLUDED_GR_UDP_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gruel/thread.h>
+
+class gr_udp_sink;
+typedef boost::shared_ptr<gr_udp_sink> gr_udp_sink_sptr;
+
+GR_CORE_API gr_udp_sink_sptr
+gr_make_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size=1472, bool eof=true);
+
+/*!
+ * \brief Write stream to an UDP socket.
+ * \ingroup sink_blk
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of the receiving host; use
+ * NULL or None for no connection
+ * \param port Destination port to connect to on receiving host
+ * \param payload_size UDP payload size by default set to 1472 =
+ * (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof Send zero-length packet on disconnect
+ */
+
+class GR_CORE_API gr_udp_sink : public gr_sync_block
+{
+ friend GR_CORE_API gr_udp_sink_sptr gr_make_udp_sink (size_t itemsize,
+ const char *host,
+ unsigned short port,
+ int payload_size, bool eof);
+ private:
+ size_t d_itemsize;
+
+ int d_payload_size; // maximum transmission unit (packet length)
+ bool d_eof; // send zero-length packet on disconnect
+ int d_socket; // handle to socket
+ bool d_connected; // are we connected?
+ gruel::mutex d_mutex; // protects d_socket and d_connected
+
+ protected:
+ /*!
+ * \brief UDP Sink Constructor
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of the receiving host; use
+ * NULL or None for no connection
+ * \param port Destination port to connect to on receiving host
+ * \param payload_size UDP payload size by default set to
+ * 1472 = (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof Send zero-length packet on disconnect
+ */
+ gr_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size, bool eof);
+
+ public:
+ ~gr_udp_sink ();
+
+ /*! \brief return the PAYLOAD_SIZE of the socket */
+ int payload_size() { return d_payload_size; }
+
+ /*! \brief Change the connection to a new destination
+ *
+ * \param host The name or IP address of the receiving host; use
+ * NULL or None to break the connection without closing
+ * \param port Destination port to connect to on receiving host
+ *
+ * Calls disconnect() to terminate any current connection first.
+ */
+ void connect( const char *host, unsigned short port );
+
+ /*! \brief Send zero-length packet (if eof is requested) then stop sending
+ *
+ * Zero-byte packets can be interpreted as EOF by gr_udp_source. Note that
+ * disconnect occurs automatically when the sink is destroyed, but not when
+ * its top_block stops.*/
+ void disconnect();
+
+ // should we export anything else?
+
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_UDP_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.i b/gnuradio-core/src/lib/io/gr_udp_sink.i
new file mode 100644
index 000000000..ba7043937
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_sink.i
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 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.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,udp_sink)
+
+gr_udp_sink_sptr
+gr_make_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size=1472, bool eof=true) throw (std::runtime_error);
+
+class gr_udp_sink : public gr_sync_block
+{
+ protected:
+ gr_udp_sink (size_t itemsize,
+ const char *host, unsigned short port,
+ int payload_size, bool eof)
+ throw (std::runtime_error);
+
+ public:
+ ~gr_udp_sink ();
+
+ int payload_size() { return d_payload_size; }
+ void connect( const char *host, unsigned short port );
+ void disconnect();
+
+};
diff --git a/gnuradio-core/src/lib/io/gr_udp_source.cc b/gnuradio-core/src/lib/io/gr_udp_source.cc
new file mode 100644
index 000000000..eca8e89d0
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_source.cc
@@ -0,0 +1,374 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009,2010 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
+#include <gr_udp_source.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(HAVE_NETDB_H)
+#include <netdb.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+typedef void* optval_t;
+
+// ntohs() on FreeBSD may require both netinet/in.h and arpa/inet.h, in order
+#if defined(HAVE_NETINET_IN_H)
+#include <netinet/in.h>
+#endif
+#if defined(HAVE_ARPA_INET_H)
+#include <arpa/inet.h>
+#endif
+
+#elif defined(HAVE_WINDOWS_H)
+// if not posix, assume winsock
+#define USING_WINSOCK
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#define SHUT_RDWR 2
+typedef char* optval_t;
+#endif
+
+#define USE_SELECT 1 // non-blocking receive on all platforms
+#define USE_RCV_TIMEO 0 // non-blocking receive on all but Cygwin
+#define SRC_VERBOSE 0
+
+static int is_error( int perr )
+{
+ // Compare error to posix error code; return nonzero if match.
+#if defined(USING_WINSOCK)
+#define ENOPROTOOPT 109
+ // All codes to be checked for must be defined below
+ int werr = WSAGetLastError();
+ switch( werr ) {
+ case WSAETIMEDOUT:
+ return( perr == EAGAIN );
+ case WSAENOPROTOOPT:
+ return( perr == ENOPROTOOPT );
+ default:
+ fprintf(stderr,"gr_udp_source/is_error: unknown error %d\n", perr );
+ throw std::runtime_error("internal error");
+ }
+ return 0;
+#else
+ return( perr == errno );
+#endif
+}
+
+static void report_error( const char *msg1, const char *msg2 )
+{
+ // Deal with errors, both posix and winsock
+#if defined(USING_WINSOCK)
+ int werr = WSAGetLastError();
+ fprintf(stderr, "%s: winsock error %d\n", msg1, werr );
+#else
+ perror(msg1);
+#endif
+ if( msg2 != NULL )
+ throw std::runtime_error(msg2);
+ return;
+}
+
+gr_udp_source::gr_udp_source(size_t itemsize, const char *host,
+ unsigned short port, int payload_size,
+ bool eof, bool wait)
+ : gr_sync_block ("udp_source",
+ gr_make_io_signature(0, 0, 0),
+ gr_make_io_signature(1, 1, itemsize)),
+ d_itemsize(itemsize), d_payload_size(payload_size),
+ d_eof(eof), d_wait(wait), d_socket(-1), d_residual(0), d_temp_offset(0)
+{
+ int ret = 0;
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+ // initialize winsock DLL
+ WSADATA wsaData;
+ int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
+ if( iResult != NO_ERROR ) {
+ report_error( "gr_udp_source WSAStartup", "can't open socket" );
+ }
+#endif
+
+ // Set up the address stucture for the source address and port numbers
+ // Get the source IP address from the host name
+ struct addrinfo *ip_src; // store the source IP address to use
+ struct addrinfo hints;
+ memset( (void*)&hints, 0, sizeof(hints) );
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_flags = AI_PASSIVE;
+ char port_str[12];
+ sprintf( port_str, "%d", port );
+
+ // FIXME leaks if report_error throws below
+ ret = getaddrinfo( host, port_str, &hints, &ip_src );
+ if( ret != 0 )
+ report_error("gr_udp_source/getaddrinfo",
+ "can't initialize source socket" );
+
+ // FIXME leaks if report_error throws below
+ d_temp_buff = new char[d_payload_size]; // allow it to hold up to payload_size bytes
+
+ // create socket
+ d_socket = socket(ip_src->ai_family, ip_src->ai_socktype,
+ ip_src->ai_protocol);
+ if(d_socket == -1) {
+ report_error("socket open","can't open socket");
+ }
+
+ // Turn on reuse address
+ int opt_val = 1;
+ if(setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, (optval_t)&opt_val, sizeof(int)) == -1) {
+ report_error("SO_REUSEADDR","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(d_socket, SOL_SOCKET, SO_LINGER, (optval_t)&lngr, sizeof(linger)) == -1) {
+ if( !is_error(ENOPROTOOPT) ) { // no SO_LINGER for SOCK_DGRAM on Windows
+ report_error("SO_LINGER","can't set socket option SO_LINGER");
+ }
+ }
+
+#if USE_RCV_TIMEO
+ // Set a timeout on the receive function to not block indefinitely
+ // This value can (and probably should) be changed
+ // Ignored on Cygwin
+#if defined(USING_WINSOCK)
+ DWORD timeout = 1000; // milliseconds
+#else
+ timeval timeout;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+#endif
+ if(setsockopt(d_socket, SOL_SOCKET, SO_RCVTIMEO, (optval_t)&timeout, sizeof(timeout)) == -1) {
+ report_error("SO_RCVTIMEO","can't set socket option SO_RCVTIMEO");
+ }
+#endif // USE_RCV_TIMEO
+
+ // bind socket to an address and port number to listen on
+ if(bind (d_socket, ip_src->ai_addr, ip_src->ai_addrlen) == -1) {
+ report_error("socket bind","can't bind socket");
+ }
+ freeaddrinfo(ip_src);
+
+}
+
+gr_udp_source_sptr
+gr_make_udp_source (size_t itemsize, const char *ipaddr,
+ unsigned short port, int payload_size, bool eof, bool wait)
+{
+ return gnuradio::get_initial_sptr(new gr_udp_source (itemsize, ipaddr,
+ port, payload_size, eof, wait));
+}
+
+gr_udp_source::~gr_udp_source ()
+{
+ delete [] d_temp_buff;
+
+ if (d_socket != -1){
+ shutdown(d_socket, SHUT_RDWR);
+#if defined(USING_WINSOCK)
+ closesocket(d_socket);
+#else
+ ::close(d_socket);
+#endif
+ d_socket = -1;
+ }
+
+#if defined(USING_WINSOCK) // for Windows (with MinGW)
+ // free winsock resources
+ WSACleanup();
+#endif
+}
+
+int
+gr_udp_source::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ ssize_t r=0, nbytes=0, bytes_received=0;
+ ssize_t total_bytes = (ssize_t)(d_itemsize*noutput_items);
+
+ #if SRC_VERBOSE
+ printf("\nEntered udp_source\n");
+ #endif
+
+ // Remove items from temp buffer if they are in there
+ if(d_residual) {
+ nbytes = std::min(d_residual, total_bytes);
+ memcpy(out, d_temp_buff+d_temp_offset, nbytes);
+ bytes_received = nbytes;
+
+ #if SRC_VERBOSE
+ printf("\tTemp buff size: %d offset: %d (bytes_received: %d) (noutput_items: %d)\n",
+ d_residual, d_temp_offset, bytes_received, noutput_items);
+ #endif
+
+ // Increment pointer
+ out += bytes_received;
+
+ // Update indexing of amount of bytes left in the buffer
+ d_residual -= nbytes;
+ d_temp_offset += nbytes;
+
+ // Return now with what we've got.
+ assert(nbytes % d_itemsize == 0);
+ return nbytes/d_itemsize;
+ }
+
+ while(1) {
+ // get the data into our output buffer and record the number of bytes
+
+#if USE_SELECT
+ // RCV_TIMEO doesn't work on all systems (e.g., Cygwin)
+ // use select() instead of, or in addition to RCV_TIMEO
+ fd_set readfds;
+ timeval timeout;
+ timeout.tv_sec = 1; // Init timeout each iteration. Select can modify it.
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfds);
+ FD_SET(d_socket, &readfds);
+ r = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
+ if(r < 0) {
+ report_error("udp_source/select",NULL);
+ return -1;
+ }
+ else if(r == 0 ) { // timed out
+ if( d_wait ) {
+ // Allow boost thread interrupt, then try again
+ //boost::this_thread::interruption_point();
+ //continue;
+ return 0;
+ }
+ else
+ return -1;
+ }
+#endif // USE_SELECT
+
+ // This is a non-blocking call with a timeout set in the constructor
+ r = recv(d_socket, d_temp_buff, d_payload_size, 0); // get the entire payload or the what's available
+
+ // If r > 0, round it down to a multiple of d_itemsize
+ // (If sender is broken, don't propagate problem)
+ if (r > 0)
+ r = (r/d_itemsize) * d_itemsize;
+
+ // Check if there was a problem; forget it if the operation just timed out
+ if(r == -1) {
+ if( is_error(EAGAIN) ) { // handle non-blocking call timeout
+ #if SRC_VERBOSE
+ printf("UDP receive timed out\n");
+ #endif
+
+ if( d_wait ) {
+ // Allow boost thread interrupt, then try again
+ //boost::this_thread::interruption_point();
+ //continue;
+ return 0;
+ }
+ else
+ return -1;
+ }
+ else {
+ report_error("udp_source/recv",NULL);
+ return -1;
+ }
+ }
+ else if(r==0) {
+ if(d_eof) {
+ // zero-length packet interpreted as EOF
+
+ #if SNK_VERBOSE
+ printf("\tzero-length packet received; returning EOF\n");
+ #endif
+
+ return -1;
+ }
+ else{
+ // do we need to allow boost thread interrupt?
+ boost::this_thread::interruption_point();
+ continue;
+ }
+ }
+ else {
+ // Calculate the number of bytes we can take from the buffer in this call
+ nbytes = std::min(r, total_bytes-bytes_received);
+
+ // adjust the total number of bytes we have to round down to nearest integer of an itemsize
+ nbytes -= ((bytes_received+nbytes) % d_itemsize);
+
+ // copy the number of bytes we want to look at here
+ memcpy(out, d_temp_buff, nbytes);
+
+ d_residual = r - nbytes; // save the number of bytes stored
+ d_temp_offset=nbytes; // reset buffer index
+
+ // keep track of the total number of bytes received
+ bytes_received += nbytes;
+
+ // increment the pointer
+ out += nbytes;
+
+ // Immediately return when data comes in
+ break;
+ }
+
+ #if SNK_VERBOSE
+ printf("\tbytes received: %d bytes (nbytes: %d)\n", bytes, nbytes);
+ #endif
+ }
+
+ #if SRC_VERBOSE
+ printf("Total Bytes Received: %d (bytes_received / noutput_items = %d / %d)\n",
+ bytes_received, bytes_received, noutput_items);
+ #endif
+
+ // bytes_received is already set to some integer multiple of itemsize
+ return bytes_received/d_itemsize;
+}
+
+// Return port number of d_socket
+int gr_udp_source::get_port(void)
+{
+ sockaddr_in name;
+ socklen_t len = sizeof(name);
+ int ret = getsockname( d_socket, (sockaddr*)&name, &len );
+ if( ret ) {
+ report_error("gr_udp_source/getsockname",NULL);
+ return -1;
+ }
+ return ntohs(name.sin_port);
+}
diff --git a/gnuradio-core/src/lib/io/gr_udp_source.h b/gnuradio-core/src/lib/io/gr_udp_source.h
new file mode 100644
index 000000000..56dcb3c0a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_source.h
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008,2009,2010 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_GR_UDP_SOURCE_H
+#define INCLUDED_GR_UDP_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gruel/thread.h>
+
+class gr_udp_source;
+typedef boost::shared_ptr<gr_udp_source> gr_udp_source_sptr;
+
+GR_CORE_API gr_udp_source_sptr gr_make_udp_source(size_t itemsize, const char *host,
+ unsigned short port,
+ int payload_size=1472,
+ bool eof=true, bool wait=true);
+
+/*!
+ * \brief Read stream from an UDP socket.
+ * \ingroup source_blk
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of the receiving host; can be
+ * NULL, None, or "0.0.0.0" to allow reading from any
+ * interface on the host
+ * \param port The port number on which to receive data; use 0 to
+ * have the system assign an unused port number
+ * \param payload_size UDP payload size by default set to 1472 =
+ * (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof Interpret zero-length packet as EOF (default: true)
+ * \param wait Wait for data if not immediately available
+ * (default: true)
+ *
+*/
+
+class GR_CORE_API gr_udp_source : public gr_sync_block
+{
+ friend GR_CORE_API gr_udp_source_sptr gr_make_udp_source(size_t itemsize,
+ const char *host,
+ unsigned short port,
+ int payload_size,
+ bool eof, bool wait);
+
+ private:
+ size_t d_itemsize;
+ int d_payload_size; // maximum transmission unit (packet length)
+ bool d_eof; // zero-length packet is EOF
+ bool d_wait; // wait if data if not immediately available
+ int d_socket; // handle to socket
+ char *d_temp_buff; // hold buffer between calls
+ ssize_t d_residual; // hold information about number of bytes stored in the temp buffer
+ size_t d_temp_offset; // point to temp buffer location offset
+
+ protected:
+ /*!
+ * \brief UDP Source Constructor
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of the receiving host; can be
+ * NULL, None, or "0.0.0.0" to allow reading from any
+ * interface on the host
+ * \param port The port number on which to receive data; use 0 to
+ * have the system assign an unused port number
+ * \param payload_size UDP payload size by default set to 1472 =
+ * (1500 MTU - (8 byte UDP header) - (20 byte IP header))
+ * \param eof Interpret zero-length packet as EOF (default: true)
+ * \param wait Wait for data if not immediately available
+ * (default: true)
+ */
+ gr_udp_source(size_t itemsize, const char *host, unsigned short port,
+ int payload_size, bool eof, bool wait);
+
+ public:
+ ~gr_udp_source();
+
+ /*! \brief return the PAYLOAD_SIZE of the socket */
+ int payload_size() { return d_payload_size; }
+
+ /*! \brief return the port number of the socket */
+ int get_port();
+
+ // should we export anything else?
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_UDP_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_udp_source.i b/gnuradio-core/src/lib/io/gr_udp_source.i
new file mode 100644
index 000000000..18823a356
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_udp_source.i
@@ -0,0 +1,41 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2010 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,udp_source)
+
+gr_udp_source_sptr
+gr_make_udp_source (size_t itemsize, const char *host,
+ unsigned short port, int payload_size=1472,
+ bool eof=true, bool wait=true) throw (std::runtime_error);
+
+class gr_udp_source : public gr_sync_block
+{
+ protected:
+ gr_udp_source (size_t itemsize, const char *host,
+ unsigned short port, int payload_size, bool eof, bool wait) throw (std::runtime_error);
+
+ public:
+ ~gr_udp_source ();
+
+ int payload_size() { return d_payload_size; }
+ int get_port();
+};
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_sink.cc b/gnuradio-core/src/lib/io/gr_wavfile_sink.cc
new file mode 100644
index 000000000..8526032f6
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_sink.cc
@@ -0,0 +1,280 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2007,2008,2009,2010,2011 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
+
+#include <gr_wavfile_sink.h>
+#include <gr_io_signature.h>
+#include <gri_wavfile.h>
+#include <stdexcept>
+#include <climits>
+#include <cstring>
+#include <cmath>
+#include <fcntl.h>
+#include <gruel/thread.h>
+#include <boost/math/special_functions/round.hpp>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+
+gr_wavfile_sink_sptr
+gr_make_wavfile_sink(const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample)
+{
+ return gnuradio::get_initial_sptr(new gr_wavfile_sink (filename,
+ n_channels,
+ sample_rate,
+ bits_per_sample));
+}
+
+gr_wavfile_sink::gr_wavfile_sink(const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample)
+ : gr_sync_block ("wavfile_sink",
+ gr_make_io_signature(1, n_channels, sizeof(float)),
+ gr_make_io_signature(0, 0, 0)),
+ d_sample_rate(sample_rate), d_nchans(n_channels),
+ d_fp(0), d_new_fp(0), d_updated(false)
+{
+ if (bits_per_sample != 8 && bits_per_sample != 16) {
+ throw std::runtime_error("Invalid bits per sample (supports 8 and 16)");
+ }
+ d_bytes_per_sample = bits_per_sample / 8;
+ d_bytes_per_sample_new = d_bytes_per_sample;
+
+ if (!open(filename)) {
+ throw std::runtime_error ("can't open file");
+ }
+
+ if (bits_per_sample == 8) {
+ d_max_sample_val = 0xFF;
+ d_min_sample_val = 0;
+ d_normalize_fac = d_max_sample_val/2;
+ d_normalize_shift = 1;
+ } else {
+ d_max_sample_val = 0x7FFF;
+ d_min_sample_val = -0x7FFF;
+ d_normalize_fac = d_max_sample_val;
+ d_normalize_shift = 0;
+ if (bits_per_sample != 16) {
+ fprintf(stderr, "Invalid bits per sample value requested, using 16");
+ }
+ }
+}
+
+
+bool
+gr_wavfile_sink::open(const char* filename)
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ // we use the open system call to get access to the O_LARGEFILE flag.
+ int fd;
+ if ((fd = ::open (filename,
+ O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY,
+ 0664)) < 0){
+ perror (filename);
+ return false;
+ }
+
+ if (d_new_fp) { // if we've already got a new one open, close it
+ fclose(d_new_fp);
+ d_new_fp = 0;
+ }
+
+ if ((d_new_fp = fdopen (fd, "wb")) == NULL) {
+ perror (filename);
+ ::close(fd); // don't leak file descriptor if fdopen fails.
+ return false;
+ }
+ d_updated = true;
+
+ if (!gri_wavheader_write(d_new_fp,
+ d_sample_rate,
+ d_nchans,
+ d_bytes_per_sample_new)) {
+ fprintf(stderr, "[%s] could not write to WAV file\n", __FILE__);
+ exit(-1);
+ }
+
+ return true;
+}
+
+
+void
+gr_wavfile_sink::close()
+{
+ gruel::scoped_lock guard(d_mutex);
+
+ if (!d_fp)
+ return;
+
+ close_wav();
+}
+
+void gr_wavfile_sink::close_wav()
+{
+ unsigned int byte_count = d_sample_count * d_bytes_per_sample;
+
+ gri_wavheader_complete(d_fp, byte_count);
+
+ fclose(d_fp);
+ d_fp = NULL;
+}
+
+
+gr_wavfile_sink::~gr_wavfile_sink ()
+{
+ if (d_new_fp) {
+ fclose(d_new_fp);
+ }
+
+ close();
+}
+
+
+int
+gr_wavfile_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float **in = (float **) &input_items[0];
+ int n_in_chans = input_items.size();
+
+ short int sample_buf_s;
+
+ int nwritten;
+
+ gruel::scoped_lock guard(d_mutex); // hold mutex for duration of this block
+ do_update(); // update: d_fp is reqd
+ if (!d_fp) // drop output on the floor
+ return noutput_items;
+
+ for (nwritten = 0; nwritten < noutput_items; nwritten++) {
+ for (int chan = 0; chan < d_nchans; chan++) {
+ // Write zeros to channels which are in the WAV file
+ // but don't have any inputs here
+ if (chan < n_in_chans) {
+ sample_buf_s =
+ convert_to_short(in[chan][nwritten]);
+ } else {
+ sample_buf_s = 0;
+ }
+
+ gri_wav_write_sample(d_fp, sample_buf_s, d_bytes_per_sample);
+
+ if (feof(d_fp) || ferror(d_fp)) {
+ fprintf(stderr, "[%s] file i/o error\n", __FILE__);
+ close();
+ exit(-1);
+ }
+ d_sample_count++;
+ }
+ }
+
+ return nwritten;
+}
+
+
+short int
+gr_wavfile_sink::convert_to_short(float sample)
+{
+ sample += d_normalize_shift;
+ sample *= d_normalize_fac;
+ if (sample > d_max_sample_val) {
+ sample = d_max_sample_val;
+ } else if (sample < d_min_sample_val) {
+ sample = d_min_sample_val;
+ }
+
+ return (short int) boost::math::iround(sample);
+}
+
+
+void
+gr_wavfile_sink::set_bits_per_sample(int bits_per_sample)
+{
+ gruel::scoped_lock guard(d_mutex);
+ if (bits_per_sample == 8 || bits_per_sample == 16) {
+ d_bytes_per_sample_new = bits_per_sample / 8;
+ }
+}
+
+
+void
+gr_wavfile_sink::set_sample_rate(unsigned int sample_rate)
+{
+ gruel::scoped_lock guard(d_mutex);
+ d_sample_rate = sample_rate;
+}
+
+
+void
+gr_wavfile_sink::do_update()
+{
+ if (!d_updated) {
+ return;
+ }
+
+ if (d_fp) {
+ close_wav();
+ }
+
+ d_fp = d_new_fp; // install new file pointer
+ d_new_fp = 0;
+ d_sample_count = 0;
+ d_bytes_per_sample = d_bytes_per_sample_new;
+
+ if (d_bytes_per_sample == 1) {
+ d_max_sample_val = UCHAR_MAX;
+ d_min_sample_val = 0;
+ d_normalize_fac = d_max_sample_val/2;
+ d_normalize_shift = 1;
+ } else if (d_bytes_per_sample == 2) {
+ d_max_sample_val = SHRT_MAX;
+ d_min_sample_val = SHRT_MIN;
+ d_normalize_fac = d_max_sample_val;
+ d_normalize_shift = 0;
+ }
+
+ d_updated = false;
+}
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_sink.h b/gnuradio-core/src/lib/io/gr_wavfile_sink.h
new file mode 100644
index 000000000..162151b7a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_sink.h
@@ -0,0 +1,138 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009 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_GR_WAVFILE_SINK_H
+#define INCLUDED_GR_WAVFILE_SINK_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <gr_file_sink_base.h>
+#include <boost/thread.hpp>
+
+class gr_wavfile_sink;
+typedef boost::shared_ptr<gr_wavfile_sink> gr_wavfile_sink_sptr;
+
+/*
+ * \p filename The .wav file to be opened
+ * \p n_channels Number of channels (2 = stereo or I/Q output)
+ * \p sample_rate Sample rate [S/s]
+ * \p bits_per_sample 16 or 8 bit, default is 16
+ */
+GR_CORE_API gr_wavfile_sink_sptr
+gr_make_wavfile_sink (const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample = 16);
+
+/*!
+ * \brief Write stream to a Microsoft PCM (.wav) file.
+ *
+ * Values must be floats within [-1;1].
+ * Check gr_make_wavfile_sink() for extra info.
+ *
+ * \ingroup sink_blk
+ */
+class GR_CORE_API gr_wavfile_sink : public gr_sync_block
+{
+private:
+ friend GR_CORE_API gr_wavfile_sink_sptr gr_make_wavfile_sink (const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample);
+
+ gr_wavfile_sink(const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample);
+
+ unsigned d_sample_rate;
+ int d_nchans;
+ unsigned d_sample_count;
+ int d_bytes_per_sample;
+ int d_bytes_per_sample_new;
+ int d_max_sample_val;
+ int d_min_sample_val;
+ int d_normalize_shift;
+ int d_normalize_fac;
+
+ FILE *d_fp;
+ FILE *d_new_fp;
+ bool d_updated;
+ boost::mutex d_mutex;
+
+ /*!
+ * \brief Convert a sample value within [-1;+1] to a corresponding
+ * short integer value
+ */
+ short convert_to_short(float sample);
+
+ /*!
+ * \brief If any file changes have occurred, update now. This is called
+ * internally by work() and thus doesn't usually need to be called by
+ * hand.
+ */
+ void do_update();
+
+ /*!
+ * \brief Writes information to the WAV header which is not available
+ * a-priori (chunk size etc.) and closes the file. Not thread-safe and
+ * assumes d_fp is a valid file pointer, should thus only be called by
+ * other methods.
+ */
+ void close_wav();
+
+public:
+ ~gr_wavfile_sink ();
+
+ /*!
+ * \brief Opens a new file and writes a WAV header. Thread-safe.
+ */
+ bool open(const char* filename);
+
+ /*!
+ * \brief Closes the currently active file and completes the WAV
+ * header. Thread-safe.
+ */
+ void close();
+
+ /*!
+ * \brief Set the sample rate. This will not affect the WAV file
+ * currently opened. Any following open() calls will use this new
+ * sample rate.
+ */
+ void set_sample_rate(unsigned int sample_rate);
+
+ /*!
+ * \brief Set bits per sample. This will not affect the WAV file
+ * currently opened (see set_sample_rate()). If the value is neither
+ * 8 nor 16, the call is ignored and the current value is kept.
+ */
+ void set_bits_per_sample(int bits_per_sample);
+
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+};
+
+#endif /* INCLUDED_GR_WAVFILE_SINK_H */
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_sink.i b/gnuradio-core/src/lib/io/gr_wavfile_sink.i
new file mode 100644
index 000000000..48d1130bd
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_sink.i
@@ -0,0 +1,47 @@
+/* -*- 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.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,wavfile_sink);
+
+gr_wavfile_sink_sptr
+gr_make_wavfile_sink (const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample = 16) throw (std::runtime_error);
+
+class gr_wavfile_sink : public gr_sync_block
+{
+protected:
+ gr_wavfile_sink(const char *filename,
+ int n_channels,
+ unsigned int sample_rate,
+ int bits_per_sample) throw (std::runtime_error);
+
+public:
+ ~gr_wavfile_sink ();
+ bool open(const char* filename);
+ void close();
+ void set_sample_rate(unsigned int sample_rate);
+ void set_bits_per_sample(int bits_per_sample);
+};
+
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_source.cc b/gnuradio-core/src/lib/io/gr_wavfile_source.cc
new file mode 100644
index 000000000..c8372868b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_source.cc
@@ -0,0 +1,171 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010 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
+
+#include <gr_wavfile_source.h>
+#include <gr_io_signature.h>
+#include <gri_wavfile.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+
+gr_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename, bool repeat)
+{
+ return gnuradio::get_initial_sptr(new gr_wavfile_source (filename, repeat));
+}
+
+
+gr_wavfile_source::gr_wavfile_source (const char *filename, bool repeat)
+ : gr_sync_block ("wavfile_source",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 2, sizeof(float))),
+ d_fp(NULL), d_repeat(repeat),
+ d_sample_rate(1), d_nchans(1), d_bytes_per_sample(2), d_first_sample_pos(0),
+ d_samples_per_chan(0), d_sample_idx(0)
+{
+ // we use "open" to use to the O_LARGEFILE flag
+
+ int fd;
+ if ((fd = open (filename, O_RDONLY | OUR_O_LARGEFILE | OUR_O_BINARY)) < 0) {
+ perror (filename);
+ throw std::runtime_error ("can't open file");
+ }
+
+ if ((d_fp = fdopen (fd, "rb")) == NULL) {
+ perror (filename);
+ throw std::runtime_error ("can't open file");
+ }
+
+ // Scan headers, check file validity
+ if (!gri_wavheader_parse(d_fp,
+ d_sample_rate,
+ d_nchans,
+ d_bytes_per_sample,
+ d_first_sample_pos,
+ d_samples_per_chan)) {
+ throw std::runtime_error("is not a valid wav file");
+ }
+
+ if (d_samples_per_chan == 0) {
+ throw std::runtime_error("WAV file does not contain any samples");
+ }
+
+ if (d_bytes_per_sample == 1) {
+ d_normalize_fac = 128;
+ d_normalize_shift = 1;
+ } else {
+ d_normalize_fac = 0x7FFF;
+ d_normalize_shift = 0;
+ }
+
+ // Re-set the output signature
+ set_output_signature(gr_make_io_signature(1, d_nchans, sizeof(float)));
+}
+
+
+gr_wavfile_source::~gr_wavfile_source ()
+{
+ fclose(d_fp);
+}
+
+
+int
+gr_wavfile_source::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float **out = (float **) &output_items[0];
+ int n_out_chans = output_items.size();
+
+ int i;
+ short sample;
+
+ for (i = 0; i < noutput_items; i++) {
+ if (d_sample_idx >= d_samples_per_chan) {
+ if (!d_repeat) {
+ // if nothing was read at all, say we're done.
+ return i ? i : -1;
+ }
+
+ if (fseek (d_fp, d_first_sample_pos, SEEK_SET) == -1) {
+ fprintf(stderr, "[%s] fseek failed\n", __FILE__);
+ exit(-1);
+ }
+
+ d_sample_idx = 0;
+ }
+
+ for (int chan = 0; chan < d_nchans; chan++) {
+ sample = gri_wav_read_sample(d_fp, d_bytes_per_sample);
+
+ if (chan < n_out_chans) {
+ out[chan][i] = convert_to_float(sample);
+ }
+ }
+
+ d_sample_idx++;
+
+ // OK, EOF is not necessarily an error. But we're not going to
+ // deal with handling corrupt wav files, so if they give us any
+ // trouble they won't be processed. Serves them bloody right.
+ if (feof(d_fp) || ferror(d_fp)) {
+ if (i == 0) {
+ fprintf(stderr, "[%s] WAV file has corrupted header or i/o error\n", __FILE__);
+ return -1;
+ }
+ return i;
+ }
+ }
+
+ return noutput_items;
+}
+
+
+float
+gr_wavfile_source::convert_to_float(short int sample)
+{
+ float sample_out = (float) sample;
+ sample_out /= d_normalize_fac;
+ sample_out -= d_normalize_shift;
+ return sample_out;
+}
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_source.h b/gnuradio-core/src/lib/io/gr_wavfile_source.h
new file mode 100644
index 000000000..02e6e3678
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_source.h
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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_GR_WAVFILE_SOURCE_H
+#define INCLUDED_GR_WAVFILE_SOURCE_H
+
+#include <gr_core_api.h>
+#include <gr_sync_block.h>
+#include <cstdio> // for FILE
+
+class gr_wavfile_source;
+typedef boost::shared_ptr<gr_wavfile_source> gr_wavfile_source_sptr;
+
+GR_CORE_API gr_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename, bool repeat = false);
+
+/*!
+ * \brief Read stream from a Microsoft PCM (.wav) file, output floats
+ *
+ * Unless otherwise called, values are within [-1;1].
+ * Check gr_make_wavfile_source() for extra info.
+ *
+ * \ingroup source_blk
+ */
+
+class GR_CORE_API gr_wavfile_source : public gr_sync_block
+{
+private:
+ friend GR_CORE_API gr_wavfile_source_sptr gr_make_wavfile_source (const char *filename,
+ bool repeat);
+ gr_wavfile_source(const char *filename, bool repeat);
+
+ FILE *d_fp;
+ bool d_repeat;
+
+ unsigned d_sample_rate;
+ int d_nchans;
+ int d_bytes_per_sample;
+ int d_first_sample_pos;
+ unsigned d_samples_per_chan;
+ unsigned d_sample_idx;
+ int d_normalize_shift;
+ int d_normalize_fac;
+
+ /*!
+ * \brief Convert an integer sample value to a float value within [-1;1]
+ */
+ float convert_to_float(short int sample);
+
+public:
+ ~gr_wavfile_source ();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ /*!
+ * \brief Read the sample rate as specified in the wav file header
+ */
+ unsigned int sample_rate() const { return d_sample_rate; };
+
+ /*!
+ * \brief Return the number of bits per sample as specified in the wav
+ * file header. Only 8 or 16 bit are supported here.
+ */
+ int bits_per_sample() const { return d_bytes_per_sample * 8; };
+
+ /*!
+ * \brief Return the number of channels in the wav file as specified in
+ * the wav file header. This is also the max number of outputs you can
+ * have.
+ */
+ int channels() const { return d_nchans; };
+};
+
+#endif /* INCLUDED_GR_WAVFILE_SOURCE_H */
diff --git a/gnuradio-core/src/lib/io/gr_wavfile_source.i b/gnuradio-core/src/lib/io/gr_wavfile_source.i
new file mode 100644
index 000000000..5af2224f1
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_wavfile_source.i
@@ -0,0 +1,42 @@
+/* -*- 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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,wavfile_source);
+
+gr_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename,
+ bool repeat = false) throw (std::runtime_error);
+
+class gr_wavfile_source : public gr_sync_block
+{
+private:
+ gr_wavfile_source(const char *filename,
+ bool repeat) throw (std::runtime_error);
+
+public:
+ ~gr_wavfile_source();
+
+ unsigned int sample_rate();
+ int bits_per_sample();
+ int channels();
+};
+
diff --git a/gnuradio-core/src/lib/io/gri_wavfile.cc b/gnuradio-core/src/lib/io/gri_wavfile.cc
new file mode 100644
index 000000000..277e6b7b0
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gri_wavfile.cc
@@ -0,0 +1,251 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2012 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
+
+#include <gri_wavfile.h>
+#include <cstring>
+#include <stdint.h>
+#include <boost/detail/endian.hpp> //BOOST_BIG_ENDIAN
+
+# define VALID_COMPRESSION_TYPE 0x0001
+
+// Basically, this is the opposite of htonx() and ntohx()
+// Define host to/from worknet (little endian) short and long
+#ifdef BOOST_BIG_ENDIAN
+
+ static inline uint16_t __gri_wav_bs16(uint16_t x)
+ {
+ return (x>>8) | (x<<8);
+ }
+
+ static inline uint32_t __gri_wav_bs32(uint32_t x)
+ {
+ return (uint32_t(__gri_wav_bs16(uint16_t(x&0xfffful)))<<16) | (__gri_wav_bs16(uint16_t(x>>16)));
+ }
+
+ #define htowl(x) __gri_wav_bs32(x)
+ #define wtohl(x) __gri_wav_bs32(x)
+ #define htows(x) __gri_wav_bs16(x)
+ #define wtohs(x) __gri_wav_bs16(x)
+
+#else
+
+ #define htowl(x) uint32_t(x)
+ #define wtohl(x) uint32_t(x)
+ #define htows(x) uint16_t(x)
+ #define wtohs(x) uint16_t(x)
+
+#endif // BOOST_BIG_ENDIAN
+
+// WAV files are always little-endian, so we need some byte switching macros
+static inline uint32_t host_to_wav(uint32_t x) { return htowl(x); }
+static inline uint16_t host_to_wav(uint16_t x) { return htows(x); }
+static inline int16_t host_to_wav(int16_t x) { return htows(x); }
+static inline uint32_t wav_to_host(uint32_t x) { return wtohl(x); }
+static inline uint16_t wav_to_host(uint16_t x) { return wtohs(x); }
+static inline int16_t wav_to_host(int16_t x) { return wtohs(x); }
+
+bool
+gri_wavheader_parse(FILE *fp,
+ unsigned int &sample_rate_o,
+ int &nchans_o,
+ int &bytes_per_sample_o,
+ int &first_sample_pos_o,
+ unsigned int &samples_per_chan_o)
+{
+ // _o variables take return values
+ char str_buf[8] = {0};
+
+ uint32_t file_size;
+ uint32_t fmt_hdr_skip;
+ uint16_t compression_type;
+ uint16_t nchans;
+ uint32_t sample_rate;
+ uint32_t avg_bytes_per_sec;
+ uint16_t block_align;
+ uint16_t bits_per_sample;
+ uint32_t chunk_size;
+
+ size_t fresult;
+
+ fresult = fread(str_buf, 1, 4, fp);
+ if (fresult != 4 || strncmp(str_buf, "RIFF", 4) || feof(fp)) {
+ return false;
+ }
+
+ fresult = fread(&file_size, 1, 4, fp);
+
+ fresult = fread(str_buf, 1, 8, fp);
+ if (fresult != 8 || strncmp(str_buf, "WAVEfmt ", 8) || feof(fp)) {
+ return false;
+ }
+
+ fresult = fread(&fmt_hdr_skip, 1, 4, fp);
+
+ fresult = fread(&compression_type, 1, 2, fp);
+ if (wav_to_host(compression_type) != VALID_COMPRESSION_TYPE) {
+ return false;
+ }
+
+ fresult = fread(&nchans, 1, 2, fp);
+ fresult = fread(&sample_rate, 1, 4, fp);
+ fresult = fread(&avg_bytes_per_sec, 1, 4, fp);
+ fresult = fread(&block_align, 1, 2, fp);
+ fresult = fread(&bits_per_sample, 1, 2, fp);
+
+ if (ferror(fp)) {
+ return false;
+ }
+
+ fmt_hdr_skip = wav_to_host(fmt_hdr_skip);
+ nchans = wav_to_host(nchans);
+ sample_rate = wav_to_host(sample_rate);
+ bits_per_sample = wav_to_host(bits_per_sample);
+
+ if (bits_per_sample != 8 && bits_per_sample != 16) {
+ return false;
+ }
+
+ fmt_hdr_skip -= 16;
+ if (fmt_hdr_skip) {
+ fseek(fp, fmt_hdr_skip, SEEK_CUR);
+ }
+
+ // data chunk
+ fresult = fread(str_buf, 1, 4, fp);
+ if (strncmp(str_buf, "data", 4)) {
+ return false;
+ }
+
+ fresult = fread(&chunk_size, 1, 4, fp);
+ if (ferror(fp)) {
+ return false;
+ }
+
+ // More byte swapping
+ chunk_size = wav_to_host(chunk_size);
+
+ // Output values
+ sample_rate_o = (unsigned) sample_rate;
+ nchans_o = (int) nchans;
+ bytes_per_sample_o = (int) (bits_per_sample / 8);
+ first_sample_pos_o = (int) ftell(fp);
+ samples_per_chan_o = (unsigned) (chunk_size / (bytes_per_sample_o * nchans));
+ return true;
+}
+
+
+short int
+gri_wav_read_sample(FILE *fp, int bytes_per_sample)
+{
+ int16_t buf_16bit;
+
+ if(!fread(&buf_16bit, bytes_per_sample, 1, fp)) {
+ return 0;
+ }
+ if(bytes_per_sample == 1) {
+ return (short) buf_16bit;
+ }
+ return (short)wav_to_host(buf_16bit);
+}
+
+
+bool
+gri_wavheader_write(FILE *fp,
+ unsigned int sample_rate,
+ int nchans,
+ int bytes_per_sample)
+{
+ const int header_len = 44;
+ char wav_hdr[header_len] = "RIFF\0\0\0\0WAVEfmt \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0data\0\0\0";
+ uint16_t nchans_f = (uint16_t) nchans;
+ uint32_t sample_rate_f = (uint32_t) sample_rate;
+ uint16_t block_align = bytes_per_sample * nchans;
+ uint32_t avg_bytes = sample_rate * block_align;
+ uint16_t bits_per_sample = bytes_per_sample * 8;
+
+ nchans_f = host_to_wav(nchans_f);
+ sample_rate_f = host_to_wav(sample_rate_f);
+ block_align = host_to_wav(block_align);
+ avg_bytes = host_to_wav(avg_bytes);
+ bits_per_sample = host_to_wav(bits_per_sample);
+
+ wav_hdr[16] = 0x10; // no extra bytes
+ wav_hdr[20] = 0x01; // no compression
+ memcpy((void *) (wav_hdr + 22), (void *) &nchans_f, 2);
+ memcpy((void *) (wav_hdr + 24), (void *) &sample_rate_f, 4);
+ memcpy((void *) (wav_hdr + 28), (void *) &avg_bytes, 4);
+ memcpy((void *) (wav_hdr + 32), (void *) &block_align, 2);
+ memcpy((void *) (wav_hdr + 34), (void *) &bits_per_sample, 2);
+
+ fwrite(&wav_hdr, 1, header_len, fp);
+ if (ferror(fp)) {
+ return false;
+ }
+
+ return true;
+}
+
+
+void
+gri_wav_write_sample(FILE *fp, short int sample, int bytes_per_sample)
+{
+ void *data_ptr;
+ unsigned char buf_8bit;
+ int16_t buf_16bit;
+
+ if (bytes_per_sample == 1) {
+ buf_8bit = (unsigned char) sample;
+ data_ptr = (void *) &buf_8bit;
+ } else {
+ buf_16bit = host_to_wav((int16_t) sample);
+ data_ptr = (void *) &buf_16bit;
+ }
+
+ fwrite(data_ptr, 1, bytes_per_sample, fp);
+}
+
+
+bool
+gri_wavheader_complete(FILE *fp, unsigned int byte_count)
+{
+ uint32_t chunk_size = (uint32_t) byte_count;
+ chunk_size = host_to_wav(chunk_size);
+
+ fseek(fp, 40, SEEK_SET);
+ fwrite(&chunk_size, 1, 4, fp);
+
+ chunk_size = (uint32_t) byte_count + 36; // fmt chunk and data header
+ chunk_size = host_to_wav(chunk_size);
+ fseek(fp, 4, SEEK_SET);
+
+ fwrite(&chunk_size, 1, 4, fp);
+
+ if (ferror(fp)) {
+ return false;
+ }
+
+ return true;
+}
diff --git a/gnuradio-core/src/lib/io/gri_wavfile.h b/gnuradio-core/src/lib/io/gri_wavfile.h
new file mode 100644
index 000000000..16280e34a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gri_wavfile.h
@@ -0,0 +1,96 @@
+/* -*- 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.
+ */
+
+// This file stores all the RIFF file type knowledge for the gr_wavfile_*
+// blocks.
+
+#include <gr_core_api.h>
+#include <cstdio>
+
+/*!
+ * \brief Read signal information from a given WAV file.
+ *
+ * \param[in] fp File pointer to an opened, empty file.
+ * \param[out] sample_rate Stores the sample rate [S/s]
+ * \param[out] nchans Number of channels
+ * \param[out] bytes_per_sample Bytes per sample, can either be 1 or 2 (corresponding o
+ * 8 or 16 bit samples, respectively)
+ * \param[out] first_sample_pos Number of the first byte containing a sample. Use this
+ * with fseek() to jump from the end of the file to the
+ * first sample when in repeat mode.
+ * \param[out] samples_per_chan Number of samples per channel
+ * \return True on a successful read, false if the file could not be read or is
+ * not a valid WAV file.
+ */
+bool
+gri_wavheader_parse(FILE *fp,
+ unsigned int &sample_rate,
+ int &nchans,
+ int &bytes_per_sample,
+ int &first_sample_pos,
+ unsigned int &samples_per_chan);
+
+
+/*!
+ * \brief Read one sample from an open WAV file at the current position.
+ *
+ * Takes care of endianness.
+ */
+short int
+gri_wav_read_sample(FILE *fp, int bytes_per_sample);
+
+
+/*!
+ * \brief Write a valid RIFF file header
+ *
+ * Note: Some header values are kept blank because they're usually not known
+ * a-priori (file and chunk lengths). Use gri_wavheader_complete() to fill
+ * these in.
+ */
+bool
+gri_wavheader_write(FILE *fp,
+ unsigned int sample_rate,
+ int nchans,
+ int bytes_per_sample);
+
+/*!
+ * \brief Write one sample to an open WAV file at the current position.
+ *
+ * Takes care of endianness.
+ */
+void
+gri_wav_write_sample(FILE *fp, short int sample, int bytes_per_sample);
+
+
+/*!
+ * \brief Complete a WAV header
+ *
+ * Note: The stream position is changed during this function. If anything
+ * needs to be written to the WAV file after calling this function (which
+ * shouldn't happen), you need to fseek() to the end of the file (or
+ * whereever).
+ *
+ * \param[in] fp File pointer to an open WAV file with a blank header
+ * \param[in] byte_count Length of all samples written to the file in bytes.
+ */
+bool
+gri_wavheader_complete(FILE *fp, unsigned int byte_count);
diff --git a/gnuradio-core/src/lib/io/i2c.cc b/gnuradio-core/src/lib/io/i2c.cc
new file mode 100644
index 000000000..02dd47b53
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c.cc
@@ -0,0 +1,28 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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 "i2c.h"
+
+i2c::~i2c ()
+{
+ // NOP
+}
diff --git a/gnuradio-core/src/lib/io/i2c.h b/gnuradio-core/src/lib/io/i2c.h
new file mode 100644
index 000000000..6b7f25a29
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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_I2C_H
+#define INCLUDED_I2C_H
+
+#include <gr_core_api.h>
+#include <boost/shared_ptr.hpp>
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling i2c bus
+ */
+class GR_CORE_API i2c {
+ public:
+
+ i2c () {}
+ virtual ~i2c ();
+
+ //! \returns true iff successful
+ virtual bool write (int addr, const unsigned char *buf, int nbytes) = 0;
+
+ //! \returns number of bytes read or -1 if error
+ virtual int read (int addr, unsigned char *buf, int max_bytes) = 0;
+};
+
+#endif /* INCLUDED_I2C_H */
+
diff --git a/gnuradio-core/src/lib/io/i2c_bbio.cc b/gnuradio-core/src/lib/io/i2c_bbio.cc
new file mode 100644
index 000000000..ddd00290d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio.cc
@@ -0,0 +1,29 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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 "i2c_bbio.h"
+
+i2c_bbio::~i2c_bbio ()
+{
+ // NOP
+}
+
diff --git a/gnuradio-core/src/lib/io/i2c_bbio.h b/gnuradio-core/src/lib/io/i2c_bbio.h
new file mode 100644
index 000000000..6bf47b9cd
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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_I2C_BBIO_H
+#define INCLUDED_I2C_BBIO_H
+
+#include <gr_core_api.h>
+#include <boost/shared_ptr.hpp>
+
+class i2c_bbio;
+typedef boost::shared_ptr<i2c_bbio> i2c_bbio_sptr;
+
+
+/*!
+ * \brief abstract class that implements bit banging i/o for i2c bus.
+ * \ingroup base
+ */
+class GR_CORE_API i2c_bbio {
+ public:
+
+ i2c_bbio () {}
+ virtual ~i2c_bbio ();
+
+ virtual void set_scl (bool state) = 0;
+ virtual void set_sda (bool state) = 0;
+ virtual bool get_sda () = 0;
+
+ virtual void lock () = 0;
+ virtual void unlock () = 0;
+};
+
+#endif /* INCLUDED_I2C_BBIO_H */
diff --git a/gnuradio-core/src/lib/io/i2c_bbio_pp.cc b/gnuradio-core/src/lib/io/i2c_bbio_pp.cc
new file mode 100644
index 000000000..382bb6b37
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio_pp.cc
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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 "i2c_bbio_pp.h"
+#include "microtune_eval_board_defs.h"
+
+i2c_bbio_pp::i2c_bbio_pp (ppio_sptr pp)
+{
+ d_pp = pp;
+ d_pp->lock ();
+ d_pp->write_control (d_pp->read_control () & ~UT_CP_MUST_BE_ZERO); // output, no interrupts
+ d_pp->unlock ();
+}
+
+i2c_bbio_sptr
+make_i2c_bbio_pp (ppio_sptr pp)
+{
+ return i2c_bbio_sptr (new i2c_bbio_pp (pp));
+}
+
+void
+i2c_bbio_pp::set_scl (bool state)
+{
+ int r = d_pp->read_control();
+
+ if (!state){ // active low
+ d_pp->write_control (r | UT_CP_TUNER_SCL);
+ }
+ else {
+ d_pp->write_control (r & ~UT_CP_TUNER_SCL);
+ }
+ d_pp->read_control (); // use for 1us delay
+ d_pp->read_control (); // use for 1us delay
+}
+
+void
+i2c_bbio_pp::set_sda (bool state)
+{
+ int r = d_pp->read_data ();
+
+ if (!state){ // active low
+ d_pp->write_data (r | UT_DP_TUNER_SDA_OUT);
+ }
+ else {
+ d_pp->write_data (r & ~UT_DP_TUNER_SDA_OUT);
+ }
+ d_pp->read_data (); // use for 1us delay
+ d_pp->read_data (); // use for 1us delay
+}
+
+bool
+i2c_bbio_pp::get_sda ()
+{
+ int r = d_pp->read_status ();
+ return (r & UT_SP_TUNER_SDA_IN) == 0; // eval board has an inverter on it
+}
+
+void
+i2c_bbio_pp::lock ()
+{
+ d_pp->lock ();
+}
+
+void
+i2c_bbio_pp::unlock ()
+{
+ d_pp->unlock ();
+}
diff --git a/gnuradio-core/src/lib/io/i2c_bbio_pp.h b/gnuradio-core/src/lib/io/i2c_bbio_pp.h
new file mode 100644
index 000000000..2391bc1fc
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bbio_pp.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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_I2C_BBIO_PP_H
+#define INCLUDED_I2C_BBIO_PP_H
+
+#include <gr_core_api.h>
+#include "i2c_bbio.h"
+#include "ppio.h"
+
+/*!
+ * \brief concrete class that bit bangs eval board i2c bus using parallel port
+ *
+ * \ingroup base
+ * This class talks to the i2c bus on the microtune eval board using
+ * the parallel port. This works for both the 4937 and 4702 boards.
+ */
+class GR_CORE_API i2c_bbio_pp : public i2c_bbio {
+ friend GR_CORE_API i2c_bbio_sptr make_i2c_bbio_pp (ppio_sptr pp);
+ i2c_bbio_pp (ppio_sptr pp);
+
+ public:
+
+ virtual void set_scl (bool state);
+ virtual void set_sda (bool state);
+ virtual bool get_sda ();
+
+ virtual void lock ();
+ virtual void unlock ();
+
+ private:
+ ppio_sptr d_pp;
+};
+
+GR_CORE_API i2c_bbio_sptr make_i2c_bbio_pp (ppio_sptr pp);
+
+
+#endif /* INCLUDED_I2C_BBIO_PP_H */
diff --git a/gnuradio-core/src/lib/io/i2c_bitbang.cc b/gnuradio-core/src/lib/io/i2c_bitbang.cc
new file mode 100644
index 000000000..eb801c68f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bitbang.cc
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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 "i2c_bitbang.h"
+
+i2c_bitbang::i2c_bitbang (i2c_bbio_sptr io)
+{
+ d_io = io;
+ d_io->lock ();
+
+ stop (); // get bus in known state
+
+ d_io->unlock ();
+}
+
+i2c_sptr
+make_i2c_bitbang (i2c_bbio_sptr io)
+{
+ return i2c_sptr (new i2c_bitbang (io));
+}
+
+
+// start:
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 0, SDA = 0
+
+void
+i2c_bitbang::start ()
+{
+ set_sda (1);
+ set_scl (1);
+ set_sda (0); // SDA high -> low while SCL high
+ set_scl (0);
+}
+
+
+// stop:
+// entry: SCL = X, SDA = X
+// exit: SCL = 1, SDA = 1
+
+void
+i2c_bitbang::stop ()
+{
+ set_scl (0);
+ set_sda (0);
+ set_scl (1);
+ set_sda (1); // SDA low -> high while SCL high
+}
+
+
+// write_bit:
+// entry: SCL = 0, SDA = X
+// exit: SCL = 0, SDA = X
+
+void
+i2c_bitbang::write_bit (bool bit)
+{
+ set_sda (bit);
+ set_scl (1);
+ set_scl (0);
+}
+
+
+// write_byte:
+// entry: SCL = 0, SDA = X
+// exit: SCL = 0, SDA = 1
+
+bool
+i2c_bitbang::write_byte (char t)
+{
+ int i;
+ bool ack_bit;
+
+ for (i = 0; i < 8; i++){
+ write_bit (t & 0x80);
+ t <<= 1;
+ }
+
+ // clock #9. This is the ACK bit.
+
+ set_sda (1); // tristate SDA
+ set_scl (1);
+ ack_bit = get_sda (); // slave should pull SDA line low
+ set_scl (0);
+
+ return ack_bit == 0;
+}
+
+
+// write: the high level entry point...
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 1, SDA = 1
+
+bool
+i2c_bitbang::write (int addr, const unsigned char *buf, int nbytes)
+{
+ bool ok = true;
+
+ d_io->lock ();
+ start ();
+ ok = write_byte ((addr << 1) | 0); // addr plus "read opcode"
+
+ for (int i = 0; i < nbytes; i++)
+ ok &= write_byte (buf[i]);
+
+ stop ();
+ d_io->unlock ();
+ return ok;
+}
+
+
+// read: the high level entry point...
+// entry: SCL = 1, SDA = 1
+// exit: SCL = 1, SDA = 1
+
+int
+i2c_bitbang::read (int addr, unsigned char *buf, int max_bytes)
+{
+ d_io->lock ();
+
+ // FIXME
+
+ d_io->unlock ();
+ return -1;
+}
diff --git a/gnuradio-core/src/lib/io/i2c_bitbang.h b/gnuradio-core/src/lib/io/i2c_bitbang.h
new file mode 100644
index 000000000..1d6fe5044
--- /dev/null
+++ b/gnuradio-core/src/lib/io/i2c_bitbang.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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_I2C_BITBANG_H
+#define INCLUDED_I2C_BITBANG_H
+
+#include <gr_core_api.h>
+#include <i2c.h>
+#include <i2c_bbio.h>
+
+/*!
+ * \brief class for controlling i2c bus
+ * \ingroup base
+ */
+class GR_CORE_API i2c_bitbang : public i2c {
+ friend GR_CORE_API i2c_sptr make_i2c_bitbang (i2c_bbio_sptr io);
+ i2c_bitbang (i2c_bbio_sptr io);
+
+ public:
+ ~i2c_bitbang () {}
+
+ //! \returns true iff successful
+ bool write (int addr, const unsigned char *buf, int nbytes);
+
+ //! \returns number of bytes read or -1 if error
+ int read (int addr, unsigned char *buf, int max_bytes);
+
+
+private:
+ void start ();
+ void stop ();
+ void write_bit (bool bit);
+ bool write_byte (char byte);
+
+ void set_sda (bool bit) { d_io->set_sda (bit); }
+ void set_scl (bool bit) { d_io->set_scl (bit); }
+ bool get_sda () { return d_io->get_sda (); }
+
+ i2c_bbio_sptr d_io;
+};
+
+GR_CORE_API i2c_sptr make_i2c_bitbang (i2c_bbio_sptr io);
+
+#endif /* INCLUDED_I2C_BITBANG_H */
+
+
diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i
new file mode 100644
index 000000000..e2de4eb97
--- /dev/null
+++ b/gnuradio-core/src/lib/io/io.i
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 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
+
+#include <gr_file_sink.h>
+#include <gr_file_source.h>
+#include <gr_file_descriptor_sink.h>
+#include <gr_file_descriptor_source.h>
+#include <gr_histo_sink_f.h>
+#include <microtune_4702_eval_board.h>
+#include <microtune_4937_eval_board.h>
+#include <sdr_1000.h>
+#include <gr_oscope_sink_x.h>
+#include <gr_oscope_sink_f.h>
+#include <ppio.h>
+#include <gr_message_source.h>
+#include <gr_message_burst_source.h>
+#include <gr_message_sink.h>
+#include <gr_udp_sink.h>
+#include <gr_udp_source.h>
+#include <gr_wavfile_sink.h>
+#include <gr_wavfile_source.h>
+#include <gr_tagged_file_sink.h>
+#include <gr_pdu_to_tagged_stream.h>
+#include <gr_tagged_stream_to_pdu.h>
+#include <gr_message_debug.h>
+#include <gr_pdu.h>
+#include <gr_tuntap_pdu.h>
+#include <gr_socket_pdu.h>
+%}
+
+%include "gr_file_sink_base.i"
+%include "gr_file_sink.i"
+%include "gr_file_source.i"
+%include "gr_file_descriptor_sink.i"
+%include "gr_file_descriptor_source.i"
+%include "gr_histo_sink.i"
+%include "microtune_xxxx_eval_board.i"
+%include "microtune_4702_eval_board.i"
+%include "microtune_4937_eval_board.i"
+%include "sdr_1000.i"
+%include "gr_oscope_sink.i"
+%include "ppio.i"
+%include "gr_message_source.i"
+%include "gr_message_burst_source.i"
+%include "gr_message_sink.i"
+%include "gr_udp_sink.i"
+%include "gr_udp_source.i"
+%include "gr_wavfile_sink.i"
+%include "gr_wavfile_source.i"
+%include "gr_tagged_file_sink.i"
+%include "gr_pdu_to_tagged_stream.i"
+%include "gr_tagged_stream_to_pdu.i"
+%include "gr_message_debug.i"
+%include "gr_pdu.i"
+%include "gr_tuntap_pdu.i"
+%include "gr_socket_pdu.i"
+
+
diff --git a/gnuradio-core/src/lib/io/microtune_4702.cc b/gnuradio-core/src/lib/io/microtune_4702.cc
new file mode 100644
index 000000000..3ec072d51
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702.cc
@@ -0,0 +1,183 @@
+/* -*- c++-*- */
+/*
+ * Copyright 2001,2003,2004 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 "microtune_4702.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include "i2c.h"
+
+static const double FIRST_IF = 36.00e6;
+
+// The tuner internally has 3 bands: VHF Low, VHF High & UHF.
+// These are the recommened boundaries
+static const double VHF_High_takeover = 174e6;
+static const double UHF_takeover = 470e6;
+
+static int PLL_I2C_ADDR = 0x60;
+
+static unsigned char
+control_byte_1 (bool prescaler, int reference_divisor)
+{
+ int c = 0x80;
+ //Note: Last two divider bits (bits 2 and 3 of this byte) determined later
+ if (prescaler)
+ c |= 0x10;
+
+ switch (reference_divisor){
+ case 2:
+ c |= 0x00; break;
+ case 4:
+ c |= 0x01; break;
+ case 8:
+ c |= 0x02; break;
+ case 16:
+ c |= 0x03; break;
+ case 32:
+ c |= 0x04; break;
+ case 64:
+ c |= 0x05; break;
+ case 128:
+ c |= 0x06; break;
+ case 256:
+ c |= 0x07; break;
+ case 24:
+ c |= 0x08; break;
+ case 5:
+ c |= 0x09; break;
+ case 10:
+ c |= 0x0A; break;
+ case 20:
+ c |= 0x0B; break;
+ case 40:
+ c |= 0x0C; break;
+ case 80:
+ c |= 0x0D; break;
+ case 160:
+ c |= 0x0E; break;
+ case 320:
+ c |= 0x0F; break;
+ default:
+ abort ();
+ }
+ return c;
+}
+
+static unsigned char
+control_byte_2 (double target_freq)
+{
+ int c;
+
+ if (target_freq < VHF_High_takeover) // VHF low
+ c = 0x8E;
+
+ else if (target_freq < UHF_takeover){ // VHF high
+ c = 0x05;
+ if (target_freq < 390e6)
+ c |= 0x40;
+ else
+ c |= 0x80;
+ }
+ else { // UHF
+ c = 0x03;
+ if (target_freq < 750e6)
+ c |= 0x80;
+ else
+ c |= 0xC0;
+ }
+
+ return c;
+}
+
+
+microtune_4702::microtune_4702 (i2c_sptr i2c, int i2c_addr)
+{
+ d_i2c = i2c;
+ d_i2c_addr = i2c_addr;
+ d_reference_divider = 320;
+ d_prescaler = false;
+}
+
+microtune_4702::~microtune_4702 ()
+{
+ // nop
+}
+
+/*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p target_freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+bool
+microtune_4702::set_RF_freq (double target_freq, double *p_actual_freq)
+{
+ unsigned char buf[4];
+
+ double target_f_osc = target_freq + FIRST_IF;
+
+ double f_ref = 4e6 / d_reference_divider;
+
+ //int divisor = (int) ((target_f_osc + (f_ref * 4)) / (f_ref * 8));
+
+ long int divisor = (long int) (target_f_osc / f_ref);
+ double actual_freq = (f_ref * divisor) - FIRST_IF;
+ if (p_actual_freq != 0)
+ *p_actual_freq = actual_freq;
+
+ if ((divisor & ~0x1ffff) != 0) // >17 bit divisor
+ return false;
+
+ buf[0] = ((divisor & 0x07f00) >> 8) & 0xff; // DB1
+ buf[1] = divisor & 0xff; // DB2
+ buf[2] = control_byte_1 (d_prescaler, d_reference_divider);
+ buf[2] = buf[2] | (((divisor & 0x18000) >> 10) & 0xff);
+ buf[3] = control_byte_2 (target_freq);
+
+ printf ("%x\n", PLL_I2C_ADDR);
+//#if 0
+ printf ("set_RF_freq: target: %g MHz actual: %g MHz %02x %02x %02x %02x\n",
+ target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]);
+//#endif
+
+ return d_i2c->write (d_i2c_addr, buf, sizeof (buf));
+}
+
+/*!
+ * \returns true iff PLL is locked
+ */
+bool
+microtune_4702::pll_locked_p ()
+{
+ // FIXME
+ return true;
+}
+
+/*!
+ * \returns the output frequency of the tuner in Hz.
+ */
+double
+microtune_4702::get_output_freq ()
+{
+ return FIRST_IF;
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4702.h b/gnuradio-core/src/lib/io/microtune_4702.h
new file mode 100644
index 000000000..ccc66db71
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003 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_MICROTUNE_4702_H
+#define INCLUDED_MICROTUNE_4702_H
+
+#include <gr_core_api.h>
+#include <microtune_xxxx.h>
+
+/*!
+ * \brief class for controlling microtune 4702 tuner module
+ * \ingroup hardware
+ */
+
+class GR_CORE_API microtune_4702 : public microtune_xxxx {
+public:
+ microtune_4702 (i2c_sptr i2c, int i2c_addr);
+
+ virtual ~microtune_4702 ();
+
+ /*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+ bool set_RF_freq (double freq, double *actual_freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+ private:
+
+ i2c_sptr d_i2c;
+ int d_i2c_addr;
+ int d_reference_divider;
+ bool d_prescaler; /* if set, higher charge pump current:
+ faster tuning, worse phase noise
+ for distance < 10kHz to the carrier */
+};
+
+#endif /* INCLUDED_MICROTUNE_4702_H */
+
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.cc b/gnuradio-core/src/lib/io/microtune_4702_eval_board.cc
new file mode 100644
index 000000000..f6c68726b
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702_eval_board.cc
@@ -0,0 +1,88 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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 "microtune_4702_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "ppio.h"
+#include "microtune_4702.h"
+
+static const int TUNER_I2C_ADDR = 0x60;
+
+microtune_4702_eval_board::microtune_4702_eval_board (int which_pp)
+ : microtune_xxxx_eval_board (which_pp)
+{
+ d_tuner = new microtune_4702 (d_i2c, TUNER_I2C_ADDR);
+}
+
+microtune_4702_eval_board::~microtune_4702_eval_board ()
+{
+ // default is OK
+}
+
+static const float RF_MIN_V = 1.0; // RF AGC control voltages
+static const float RF_MAX_V = 4.0;
+static const float IF_MIN_V = 2.0; // IF AGC control voltages
+static const float IF_MAX_V = 4.0;
+
+static const float MIN_AGC = 0; // bottom of synthetic range
+static const float MAX_AGC = 1000; // top of synthetic range
+
+static const float CUTOVER_POINT = 667;
+
+
+// linear is in the range MIN_AGC to MAX_AGC
+
+static float
+linear_to_RF_AGC_voltage (float linear)
+{
+ if (linear >= CUTOVER_POINT)
+ return RF_MAX_V;
+
+ float slope = (RF_MAX_V - RF_MIN_V) / CUTOVER_POINT;
+ return RF_MIN_V + linear * slope;
+}
+
+static float
+linear_to_IF_AGC_voltage (float linear)
+{
+ if (linear < CUTOVER_POINT)
+ return IF_MIN_V;
+
+ float slope = (IF_MAX_V - IF_MIN_V) / (MAX_AGC - CUTOVER_POINT);
+ return IF_MIN_V + (linear - CUTOVER_POINT) * slope;
+}
+
+void
+microtune_4702_eval_board::set_AGC (float v)
+{
+ if (v < MIN_AGC)
+ v = MIN_AGC;
+
+ if (v > MAX_AGC)
+ v = MAX_AGC;
+
+ float rf_agc_voltage = linear_to_RF_AGC_voltage (v);
+ float if_agc_voltage = linear_to_IF_AGC_voltage (v);
+
+ set_RF_AGC_voltage (rf_agc_voltage);
+ set_IF_AGC_voltage (if_agc_voltage);
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.h b/gnuradio-core/src/lib/io/microtune_4702_eval_board.h
new file mode 100644
index 000000000..d866a4b94
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702_eval_board.h
@@ -0,0 +1,49 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,2004 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_MICROTUNE_4702_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_4702_EVAL_BOARD_H
+
+#include <gr_core_api.h>
+#include "microtune_xxxx_eval_board.h"
+
+/*!
+ * \brief control microtune 4702 eval board
+ * \ingroup hardware
+ */
+
+class GR_CORE_API microtune_4702_eval_board : public microtune_xxxx_eval_board {
+public:
+ microtune_4702_eval_board (int which_pp = 0);
+ ~microtune_4702_eval_board ();
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000);
+};
+
+#endif /* INCLUDED_MICROTUNE_4702_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4702_eval_board.i b/gnuradio-core/src/lib/io/microtune_4702_eval_board.i
new file mode 100644
index 000000000..fc085a975
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4702_eval_board.i
@@ -0,0 +1,36 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,2004 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.
+ */
+
+class microtune_4702_eval_board : public microtune_xxxx_eval_board {
+public:
+ microtune_4702_eval_board (int which_pp = 0);
+ ~microtune_4702_eval_board ();
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000);
+};
diff --git a/gnuradio-core/src/lib/io/microtune_4937.cc b/gnuradio-core/src/lib/io/microtune_4937.cc
new file mode 100644
index 000000000..72ddd4bb6
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937.cc
@@ -0,0 +1,146 @@
+/* -*- c++-*- */
+/*
+ * Copyright 2001,2003 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 "microtune_4937.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <i2c.h>
+
+static const double first_IF = 43.75e6;
+
+// The tuner internally has 3 bands: VHF Low, VHF High & UHF.
+// These are the recommened boundaries
+static const double VHF_High_takeover = 158e6;
+static const double UHF_takeover = 464e6;
+
+
+static unsigned char
+control_byte_1 (bool fast_tuning_p, int reference_divisor)
+{
+ int c = 0x88;
+
+ if (fast_tuning_p)
+ c |= 0x40;
+
+ switch (reference_divisor){
+ case 512:
+ c |= 0x3 << 1; break;
+ case 640:
+ c |= 0x0 << 1; break;
+ case 1024:
+ c |= 0x1 << 1; break;
+ default:
+ abort ();
+ }
+ return c;
+}
+
+static unsigned char
+control_byte_2 (double target_freq, bool shutdown_tx_PGA)
+{
+ int c;
+
+ if (target_freq < VHF_High_takeover) // VHF low
+ c = 0xa0;
+ else if (target_freq < UHF_takeover) // VHF high
+ c = 0x90;
+ else // UHF
+ c = 0x30;
+
+ if (shutdown_tx_PGA)
+ c |= 0x08;
+
+ return c;
+}
+
+microtune_4937::microtune_4937 (i2c_sptr i2c, int i2c_addr)
+{
+ d_i2c = i2c;
+ d_i2c_addr = i2c_addr;
+ d_reference_divider = 640;
+ d_fast_tuning_p = false;
+}
+
+microtune_4937::~microtune_4937 ()
+{
+ // nop
+}
+
+/*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p target_freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+bool
+microtune_4937::set_RF_freq (double target_freq, double *p_actual_freq)
+{
+ unsigned char buf[4];
+
+ double target_f_osc = target_freq + first_IF;
+
+ double f_ref = 4e6 / d_reference_divider;
+
+ // f_osc = f_ref * 8 * divisor
+ // divisor = f_osc / (f_ref * 8)
+
+ int divisor = (int) ((target_f_osc + (f_ref * 4)) / (f_ref * 8));
+ double actual_freq = (f_ref * 8 * divisor) - first_IF;
+ if (p_actual_freq != 0)
+ *p_actual_freq = actual_freq;
+
+ if ((divisor & ~0x7fff) != 0) // 15 bit divisor
+ return false;
+
+ buf[0] = (divisor >> 8) & 0xff; // DB1
+ buf[1] = divisor & 0xff; // DB2
+ buf[2] = control_byte_1 (d_fast_tuning_p, d_reference_divider);
+ buf[3] = control_byte_2 (target_freq, true);
+
+#if 0
+ printf ("set_RF_freq: target: %g MHz actual: %g MHz %02x %02x %02x %02x\n",
+ target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]);
+#endif
+
+ return d_i2c->write (d_i2c_addr, buf, 4);
+}
+
+/*!
+ * \returns true iff PLL is locked
+ */
+bool
+microtune_4937::pll_locked_p ()
+{
+ // FIXME
+ return true;
+}
+
+/*!
+ * \returns the output frequency of the tuner in Hz.
+ */
+double
+microtune_4937::get_output_freq ()
+{
+ return 5.75e6; // 3x7702
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4937.h b/gnuradio-core/src/lib/io/microtune_4937.h
new file mode 100644
index 000000000..be8657c95
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937.h
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003 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_MICROTUNE_4937_H
+#define INCLUDED_MICROTUNE_4937_H
+
+#include <gr_core_api.h>
+#include <microtune_xxxx.h>
+
+/*!
+ * \brief class for controlling microtune 4937 tuner module
+ * \ingroup hardware
+ */
+class GR_CORE_API microtune_4937 : public microtune_xxxx {
+public:
+ microtune_4937 (i2c_sptr i2c, int i2c_addr = 0x61);
+ virtual ~microtune_4937 ();
+
+ /*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+ bool set_RF_freq (double freq, double *actual_freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+ private:
+
+ i2c_sptr d_i2c;
+ int d_i2c_addr;
+ int d_reference_divider;
+ bool d_fast_tuning_p; /* if set, higher charge pump current:
+ faster tuning, worse phase noise
+ for distance < 10kHz to the carrier */
+};
+
+#endif /* INCLUDED_MICROTUNE_4937_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.cc b/gnuradio-core/src/lib/io/microtune_4937_eval_board.cc
new file mode 100644
index 000000000..a25b8addf
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937_eval_board.cc
@@ -0,0 +1,97 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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 "microtune_4937_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "ppio.h"
+#include "microtune_4937.h"
+
+static const int TUNER_I2C_ADDR = 0x61;
+
+microtune_4937_eval_board::microtune_4937_eval_board (int which_pp)
+ : microtune_xxxx_eval_board (which_pp)
+{
+ d_tuner = new microtune_4937 (d_i2c, TUNER_I2C_ADDR);
+
+ // disable upstream amplifier
+ d_ppio->lock ();
+ int t = d_ppio->read_data ();
+ t &= ~(UT_DP_TX_ENABLE | UT_DP_TX_SDA | UT_DP_TX_SCL);
+ t |= UT_DP_TX_AS;
+ d_ppio->write_data (t);
+ d_ppio->unlock ();
+}
+
+microtune_4937_eval_board::~microtune_4937_eval_board ()
+{
+ // Default action is OK
+}
+
+
+static const float RF_MIN_V = 1.5; // RF AGC control voltages
+static const float RF_MAX_V = 4.0;
+static const float IF_MIN_V = 2.0; // IF AGC control voltages
+static const float IF_MAX_V = 4.0;
+
+static const float MIN_AGC = 0; // bottom of synthetic range
+static const float MAX_AGC = 1000; // top of synthetic range
+
+static const float CUTOVER_POINT = 667;
+
+
+// linear is in the range MIN_AGC to MAX_AGC
+
+static float
+linear_to_RF_AGC_voltage (float linear)
+{
+ if (linear >= CUTOVER_POINT)
+ return RF_MAX_V;
+
+ float slope = (RF_MAX_V - RF_MIN_V) / CUTOVER_POINT;
+ return RF_MIN_V + linear * slope;
+}
+
+static float
+linear_to_IF_AGC_voltage (float linear)
+{
+ if (linear < CUTOVER_POINT)
+ return IF_MIN_V;
+
+ float slope = (IF_MAX_V - IF_MIN_V) / (MAX_AGC - CUTOVER_POINT);
+ return IF_MIN_V + (linear - CUTOVER_POINT) * slope;
+}
+
+void
+microtune_4937_eval_board::set_AGC (float v)
+{
+ if (v < MIN_AGC)
+ v = MIN_AGC;
+
+ if (v > MAX_AGC)
+ v = MAX_AGC;
+
+ float rf_agc_voltage = linear_to_RF_AGC_voltage (v);
+ float if_agc_voltage = linear_to_IF_AGC_voltage (v);
+
+ set_RF_AGC_voltage (rf_agc_voltage);
+ set_IF_AGC_voltage (if_agc_voltage);
+}
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.h b/gnuradio-core/src/lib/io/microtune_4937_eval_board.h
new file mode 100644
index 000000000..3abd9084e
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937_eval_board.h
@@ -0,0 +1,50 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,2004 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_MICROTUNE_4937_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_4937_EVAL_BOARD_H
+
+#include <gr_core_api.h>
+#include "microtune_xxxx_eval_board.h"
+
+/*!
+ * \brief control microtune 4937 eval board
+ * \ingroup hardware
+ */
+
+class GR_CORE_API microtune_4937_eval_board : public microtune_xxxx_eval_board {
+public:
+ microtune_4937_eval_board (int which_pp = 0);
+ ~microtune_4937_eval_board ();
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000);
+};
+
+
+#endif /* INCLUDED_MICROTUNE_4937_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_4937_eval_board.i b/gnuradio-core/src/lib/io/microtune_4937_eval_board.i
new file mode 100644
index 000000000..e261416f7
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_4937_eval_board.i
@@ -0,0 +1,36 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,2004 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.
+ */
+
+class microtune_4937_eval_board : public microtune_xxxx_eval_board {
+public:
+ microtune_4937_eval_board (int which_pp = 0);
+ ~microtune_4937_eval_board ();
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000);
+};
diff --git a/gnuradio-core/src/lib/io/microtune_eval_board.i b/gnuradio-core/src/lib/io/microtune_eval_board.i
new file mode 100644
index 000000000..f77ef47b4
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_eval_board.i
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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.
+ */
+
+/*
+ * SWIG interface defs for Microtune 4937 and eval board with Eric's daughterboard
+ */
+
+/*!
+ * \brief abstract class for controlling microtune 4937 tuner module
+ */
+class microtune_4937 {
+public:
+ microtune_4937 ();
+
+ virtual ~microtune_4937 ();
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+
+ private:
+ //! \returns true iff successful
+ virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes) = 0;
+
+ //! \returns number of bytes read or -1 if error
+ virtual int i2c_read (int addr, unsigned char *buf, int max_bytes) = 0;
+
+ int d_reference_divider;
+ bool d_fast_tuning_p; /* if set, higher charge pump current:
+ faster tuning, worse phase noise
+ for distance < 10kHz to the carrier */
+};
+
+/*!
+ * \brief concrete class for controlling microtune 4937 eval board attached to parallel port
+ */
+class microtune_eval_board : public microtune_4937 {
+public:
+ microtune_eval_board (int which_pp = 0);
+ ~microtune_eval_board ();
+
+ //! is the eval board present?
+ bool board_present_p ();
+
+ /*!
+ * \brief set RF and IF AGC control voltages ([0, 5] volts)
+ */
+ void set_RF_AGC_voltage (float volts);
+ void set_IF_AGC_voltage (float volts);
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ void set_AGC (float value_0_1000);
+
+private:
+ //! \returns true iff successful
+ virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes);
+
+ //! \returns number of bytes read or -1 if error
+ virtual int i2c_read (int addr, unsigned char *buf, int max_bytes);
+};
diff --git a/gnuradio-core/src/lib/io/microtune_eval_board_defs.h b/gnuradio-core/src/lib/io/microtune_eval_board_defs.h
new file mode 100644
index 000000000..61c52364f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_eval_board_defs.h
@@ -0,0 +1,71 @@
+/* -*-C-*-
+*******************************************************************************
+*
+* File: microtune_eval_board_defs.h
+* Description: defines for parallel port control of eval board
+*
+*******************************************************************************
+*/
+
+/*
+ * Copyright 2001 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 _MICROTUNE_EVAL_BOARD_DEFS_H_
+#define _MICROTUNE_EVAL_BOARD_DEFS_H_
+
+/*
+ * The Microtune 4937DI5 cable modem tuner eval board is controlled
+ * by bit banging the PC parallel port. This file defines the relevant
+ * bits.
+ *
+ * The parallel port has an 8 bit data port (output),
+ * an 8 bit control port (output) and
+ * an 8 bit status port (input).
+ *
+ * Not all bits of the control and status ports may be arbitrarily used.
+ */
+
+
+// parallel port data port constants (output)
+
+static const int UT_DP_TX_SDA = 0x01; // upstream control bus
+static const int UT_DP_TX_SCL = 0x02; // upstream control bus
+static const int UT_DP_TX_AS = 0x04; // upstream control bus
+static const int UT_DP_TX_ENABLE = 0x08; // upstream h/w enable
+// bits 4,5,6 not used
+static const int UT_DP_TUNER_SDA_OUT = 0x80; // tuner i2c bus data
+
+// parallel port control port constants (output)
+
+static const int UT_CP_TUNER_SCL = 0x08; // tuner i2c bus clock
+static const int UT_CP_MUST_BE_ZERO = 0xf0; // must be zero
+
+// parallel port status port constants (input)
+
+// bits 0,1,2 not used
+static const int UT_SP_TUNER_SCL_LOOP_BACK= 0x08; // inverted SCL loop back
+static const int UT_SP_SHOULD_BE_ZERO = 0x10; // reads as zero
+static const int UT_SP_SHOULD_BE_ONE = 0x20; // reads as one
+// bit 6 not used
+static const int UT_SP_TUNER_SDA_IN = 0x80;
+
+
+#endif /* _MICROTUNE_EVAL_BOARD_DEFS_H_ */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx.cc b/gnuradio-core/src/lib/io/microtune_xxxx.cc
new file mode 100644
index 000000000..3d55f534a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx.cc
@@ -0,0 +1,41 @@
+/* -*- c++-*- */
+/*
+ * Copyright 2001,2003,2004 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 "microtune_xxxx.h"
+
+microtune_xxxx::~microtune_xxxx ()
+{
+ // nop
+}
+
+double
+microtune_xxxx::set_RF_freq (double target_freq)
+{
+ double actual_freq = 0.0;
+
+ if (set_RF_freq (target_freq, &actual_freq))
+ return actual_freq;
+
+ return 0.0;
+}
+
+
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx.h b/gnuradio-core/src/lib/io/microtune_xxxx.h
new file mode 100644
index 000000000..b2646d39f
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003,2004 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_MICROTUNE_XXXX_H
+#define INCLUDED_MICROTUNE_XXXX_H
+
+#include <gr_core_api.h>
+#include <boost/shared_ptr.hpp>
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling microtune {4937,4702} tuner modules
+ * \ingroup base
+ */
+class GR_CORE_API microtune_xxxx {
+public:
+ microtune_xxxx () {}
+ virtual ~microtune_xxxx ();
+
+ /*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+ virtual bool set_RF_freq (double freq, double *actual_freq) = 0;
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ virtual bool pll_locked_p () = 0;
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ virtual double get_output_freq () = 0;
+
+};
+
+#endif /* INCLUDED_MICROTUNE_XXXX_H */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc
new file mode 100644
index 000000000..35600ff06
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2004 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
+
+#include "microtune_xxxx_eval_board.h"
+#include "microtune_eval_board_defs.h"
+#include "microtune_xxxx.h"
+#include "ppio.h"
+#include "i2c_bitbang.h"
+#include "i2c_bbio_pp.h"
+#include <cmath>
+
+static int AGC_DAC_I2C_ADDR = 0x2C;
+
+microtune_xxxx_eval_board::microtune_xxxx_eval_board (int which_pp)
+{
+ d_ppio = make_ppio (which_pp);
+ d_i2c = make_i2c_bitbang (make_i2c_bbio_pp (d_ppio));
+ d_tuner = 0;
+}
+
+microtune_xxxx_eval_board::~microtune_xxxx_eval_board ()
+{
+ delete d_tuner;
+ d_tuner = 0;
+}
+
+
+//! is the eval board present?
+bool
+microtune_xxxx_eval_board::board_present_p ()
+{
+ bool result = true;
+ d_ppio->lock ();
+
+ int t = d_ppio->read_status ();
+ if ((t & UT_SP_SHOULD_BE_ZERO) != 0
+ || (t & UT_SP_SHOULD_BE_ONE) != UT_SP_SHOULD_BE_ONE)
+ result = false;
+
+ // could also see if SCL is looped back or not, but that seems like overkill
+
+ d_ppio->unlock ();
+ return result;
+}
+
+/*
+ * ----------------------------------------------------------------
+ * AGC stuff
+ *
+ * We're using a MAX518 8-bit 5V dual dac for setting the AGC's
+ * ----------------------------------------------------------------
+ */
+void
+microtune_xxxx_eval_board::write_dac (int which, int value)
+{
+ unsigned char cmd[2];
+ cmd[0] = which & 1;
+ cmd[1] = value;
+ d_i2c->write (AGC_DAC_I2C_ADDR, cmd, sizeof (cmd));
+}
+
+void
+microtune_xxxx_eval_board::write_both_dacs (int value0, int value1)
+{
+ unsigned char cmd[4];
+ cmd[0] = 0;
+ cmd[1] = value0;
+ cmd[2] = 1;
+ cmd[3] = value1;
+ d_i2c->write (AGC_DAC_I2C_ADDR, cmd, sizeof (cmd));
+}
+
+static int scale_volts (float volts)
+{
+ int n;
+ n = (int) rint (volts * (256 / 5.0));
+ if (n < 0)
+ n = 0;
+ if (n > 255)
+ n = 255;
+
+ return n;
+}
+
+void
+microtune_xxxx_eval_board::set_RF_AGC_voltage (float volts)
+{
+ write_dac (0, scale_volts (volts));
+}
+
+void
+microtune_xxxx_eval_board::set_IF_AGC_voltage (float volts)
+{
+ write_dac (1, scale_volts (volts));
+}
+
+// delegate to tuner
+
+bool
+microtune_xxxx_eval_board::set_RF_freq (double freq, double *actual_freq)
+{
+ return d_tuner->set_RF_freq (freq, actual_freq);
+}
+
+double
+microtune_xxxx_eval_board::set_RF_freq (double freq)
+{
+ return d_tuner->set_RF_freq (freq);
+}
+
+bool
+microtune_xxxx_eval_board::pll_locked_p ()
+{
+ return d_tuner->pll_locked_p ();
+}
+
+double
+microtune_xxxx_eval_board::get_output_freq ()
+{
+ return d_tuner->get_output_freq ();
+}
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h
new file mode 100644
index 000000000..7fd784ade
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.h
@@ -0,0 +1,98 @@
+/* -*- C++ -*- */
+/*
+ * Copyright 2001,2004 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_MICROTUNE_XXXX_EVAL_BOARD_H
+#define INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H
+
+#include <gr_core_api.h>
+#include <boost/shared_ptr.hpp>
+
+class microtune_xxxx;
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+class i2c;
+typedef boost::shared_ptr<i2c> i2c_sptr;
+
+/*!
+ * \brief abstract class for controlling microtune xxxx eval board
+ * \ingroup hardware
+ */
+class GR_CORE_API microtune_xxxx_eval_board {
+public:
+ microtune_xxxx_eval_board (int which_pp = 0);
+ virtual ~microtune_xxxx_eval_board ();
+
+ //! is the eval board present?
+ bool board_present_p ();
+
+ /*!
+ * \brief set RF and IF AGC control voltages ([0, 5] volts)
+ */
+ void set_RF_AGC_voltage (float volts);
+ void set_IF_AGC_voltage (float volts);
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000) = 0;
+
+ /*!
+ * \brief select RF frequency to be tuned to output frequency.
+ * \p freq is the requested frequency in Hz, \p actual_freq
+ * is set to the actual frequency tuned. It takes about 100 ms
+ * for the PLL to settle.
+ *
+ * \returns true iff sucessful.
+ */
+ bool set_RF_freq (double freq, double *actual_freq);
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+
+
+private:
+ void write_dac (int which, int value);
+ void write_both_dacs (int val0, int val1);
+
+protected:
+ ppio_sptr d_ppio;
+ i2c_sptr d_i2c;
+ microtune_xxxx *d_tuner;
+};
+
+#endif /* INCLUDED_MICROTUNE_XXXX_EVAL_BOARD_H */
diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i
new file mode 100644
index 000000000..8a8a59742
--- /dev/null
+++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.i
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+class microtune_xxxx_eval_board {
+public:
+ microtune_xxxx_eval_board (int which_pp = 0);
+ virtual ~microtune_xxxx_eval_board ();
+
+ //! is the eval board present?
+ bool board_present_p ();
+
+ /*!
+ * \brief set RF and IF AGC control voltages ([0, 5] volts)
+ */
+ void set_RF_AGC_voltage (float volts);
+ void set_IF_AGC_voltage (float volts);
+
+ /*!
+ * \brief set RF and IF AGC levels together (scale [0, 1000])
+ *
+ * This provides a simple linear interface for adjusting both
+ * the RF and IF gain in consort. This is the easy to use interface.
+ * 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
+ */
+ virtual void set_AGC (float value_0_1000) = 0;
+
+ // returns actual freq or 0 if error (easier interface for SWIG)
+ double set_RF_freq (double freq);
+
+ /*!
+ * \returns true iff PLL is locked
+ */
+ bool pll_locked_p ();
+
+ /*!
+ * \returns the output frequency (IF center freq) of the tuner in Hz.
+ */
+ double get_output_freq ();
+};
diff --git a/gnuradio-core/src/lib/io/ppio.cc b/gnuradio-core/src/lib/io/ppio.cc
new file mode 100644
index 000000000..a5edc539c
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio.cc
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 <ppio.h>
+#include <ppio_ppdev.h>
+
+ppio::~ppio ()
+{
+}
+
+// Factory method.
+//
+// Right now, we've only got one subclass we like. If there were more,
+// we'd instantiate the "right one" here.
+
+ppio_sptr
+make_ppio (int which_pp)
+{
+ return make_ppio_ppdev (which_pp);
+}
diff --git a/gnuradio-core/src/lib/io/ppio.h b/gnuradio-core/src/lib/io/ppio.h
new file mode 100644
index 000000000..d99f7bf79
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003 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_PPIO_H
+#define INCLUDED_PPIO_H
+
+#include <gr_core_api.h>
+#include <boost/shared_ptr.hpp>
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+
+/*!
+ * \brief abstract class that provides low level access to parallel port bits
+ * \ingroup hardware
+ */
+
+class GR_CORE_API ppio {
+ public:
+ ppio () {}
+ virtual ~ppio ();
+
+ virtual void write_data (unsigned char v) = 0;
+ virtual unsigned char read_data () = 0;
+ virtual void write_control (unsigned char v) = 0;
+ virtual unsigned char read_control () = 0;
+ virtual unsigned char read_status () = 0;
+
+ virtual void lock () = 0;
+ virtual void unlock () = 0;
+};
+
+/*!
+ * \brief Factory method.
+ *
+ * Split out from class to make life easier for SWIG
+ */
+
+GR_CORE_API ppio_sptr make_ppio (int which_pp);
+
+
+#endif /* INCLUDED_PPIO_H */
+
diff --git a/gnuradio-core/src/lib/io/ppio.i b/gnuradio-core/src/lib/io/ppio.i
new file mode 100644
index 000000000..6b95dcf88
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio.i
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+%template(ppio_sptr) boost::shared_ptr<ppio>;
+
+/*!
+ * \brief abstract class that provides low level access to parallel port bits
+ */
+
+class ppio {
+ public:
+ ppio () {}
+ virtual ~ppio ();
+
+ virtual void write_data (unsigned char v) = 0;
+ virtual unsigned char read_data () = 0;
+ virtual void write_control (unsigned char v) = 0;
+ virtual unsigned char read_control () = 0;
+ virtual unsigned char read_status () = 0;
+
+ virtual void lock () = 0;
+ virtual void unlock () = 0;
+};
+
+
+ppio_sptr make_ppio (int which_pp);
diff --git a/gnuradio-core/src/lib/io/ppio_ppdev.cc b/gnuradio-core/src/lib/io/ppio_ppdev.cc
new file mode 100644
index 000000000..f52845958
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio_ppdev.cc
@@ -0,0 +1,321 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003,2004,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
+#include <ppio_ppdev.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <iostream>
+#include <errno.h>
+#include <stdio.h>
+#include <stdexcept>
+#if defined(HAVE_LINUX_PPDEV_H)
+#include <sys/ioctl.h>
+#include <linux/ppdev.h>
+#include <linux/parport.h>
+#include <sstream>
+#elif defined(HAVE_DEV_PPBUS_PPI_H)
+#include <sys/ioctl.h>
+#include <dev/ppbus/ppi.h>
+#include <dev/ppbus/ppbconf.h>
+#include <sstream>
+#else
+// #warn "ppio_ppdev is not functional on this platform"
+#endif
+
+// These control port bits are active low.
+// We toggle them so that this weirdness doesn't get get propagated
+// through our interface.
+
+static int CP_ACTIVE_LOW_BITS = 0x0B;
+
+// These status port bits are active low.
+// We toggle them so that this weirdness doesn't get get propagated
+// through our interface.
+
+static int SP_ACTIVE_LOW_BITS = 0x80;
+
+#if defined(HAVE_LINUX_PPDEV_H)
+
+// The real Linux code...
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::ostringstream filename;
+ filename << "/dev/parport" << which;
+ const char *c_filename = filename.str().c_str();
+
+ if ((d_fd = open (c_filename, O_RDWR)) < 0){
+ int my_errno = errno;
+ perror (c_filename);
+ if (my_errno == ENOENT){
+ std::cerr << "Does the device file " << c_filename << " exist?\n";
+ std::cerr << "If not, as root execute: \n";
+ std::cerr << " # mknod " << c_filename << " c 99 0\n";
+ std::cerr << " # chmod 666 " << c_filename << std::endl;
+ }
+ throw std::runtime_error ("open");
+ }
+
+ int mode = IEEE1284_MODE_COMPAT;
+ if (ioctl (d_fd, PPSETMODE, &mode) != 0){
+ perror ("ppio_ppdev: PPSETMODE");
+ close (d_fd);
+ throw std::runtime_error ("PPSETMODE");
+ }
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+ close (d_fd);
+}
+
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+ if (ioctl (d_fd, PPWDATA, &v) != 0){
+ perror ("ppio_ppdev: PPWDATA");
+ throw std::runtime_error ("PPWDATA");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ unsigned char v;
+
+ if (ioctl (d_fd, PPRDATA, &v) != 0){
+ perror ("ppio_ppdev: PPRDATA");
+ throw std::runtime_error ("PPRDATA");
+ }
+ return v;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+ unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
+ if (ioctl (d_fd, PPWCONTROL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPWCONTROL");
+ throw std::runtime_error ("PPWCONTROL");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ unsigned char ctrl;
+ if (ioctl (d_fd, PPRCONTROL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPRCONTROL");
+ throw std::runtime_error ("PPRCONTROL");
+ }
+
+ return ctrl ^ CP_ACTIVE_LOW_BITS;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ unsigned char status;
+ if (ioctl (d_fd, PPRSTATUS, &status) != 0){
+ perror ("ppio_ppdev: PPRSTATUS");
+ throw std::runtime_error ("PPRSTATUS");
+ }
+
+ return status ^ SP_ACTIVE_LOW_BITS;
+}
+
+void
+ppio_ppdev::lock ()
+{
+ if (ioctl (d_fd, PPCLAIM) != 0){
+ perror ("ppio_ppdev: PPCLAIM");
+ throw std::runtime_error ("PPCLAIM");
+ }
+}
+
+void
+ppio_ppdev::unlock ()
+{
+ if (ioctl (d_fd, PPRELEASE) != 0){
+ perror ("ppio_ppdev: PPRELEASE");
+ throw std::runtime_error ("PPRELEASE");
+ }
+}
+
+#elif defined(HAVE_DEV_PPBUS_PPI_H)
+
+// The real FreeBSD code... (Could work on other BSDs as well)
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::ostringstream filename;
+ filename << "/dev/ppi" << which;
+ const char *c_filename = filename.str().c_str();
+ if ((d_fd = open (c_filename, O_RDWR)) < 0){
+ int my_errno = errno;
+ perror (c_filename);
+ throw std::runtime_error ("open");
+ }
+
+#if 0
+ int mode = IEEE1284_MODE_COMPAT;
+ if (ioctl (d_fd, PPSETMODE, &mode) != 0){
+ perror ("ppio_ppdev: PPSETMODE");
+ close (d_fd);
+ throw std::runtime_error ("PPSETMODE");
+ }
+#endif
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+ close (d_fd);
+}
+
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+ if (ioctl (d_fd, PPISDATA, &v) != 0){
+ perror ("ppio_ppdev: PPISDATA");
+ throw std::runtime_error ("PPISDATA");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ unsigned char v;
+
+ if (ioctl (d_fd, PPIGDATA, &v) != 0){
+ perror ("ppio_ppdev: PPIGDATA");
+ throw std::runtime_error ("PPIGDATA");
+ }
+ return v;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+ unsigned char ctrl = v ^ CP_ACTIVE_LOW_BITS;
+ if (ioctl (d_fd, PPISCTRL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPISCTRL");
+ throw std::runtime_error ("PPISCTRL");
+ }
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ unsigned char ctrl;
+ if (ioctl (d_fd, PPIGCTRL, &ctrl) != 0){
+ perror ("ppio_ppdev: PPIGCTRL");
+ throw std::runtime_error ("PPIGCTRL");
+ }
+
+ return ctrl ^ CP_ACTIVE_LOW_BITS;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ unsigned char status;
+ if (ioctl (d_fd, PPIGSTATUS, &status) != 0){
+ perror ("ppio_ppdev: PPIGSTATUS");
+ throw std::runtime_error ("PPIGSTATUS");
+ }
+ return status ^ SP_ACTIVE_LOW_BITS;
+}
+
+void
+ppio_ppdev::lock ()
+{
+}
+
+void
+ppio_ppdev::unlock ()
+{
+}
+#else
+/* Apparently, non real code */
+
+ppio_ppdev::ppio_ppdev (int which)
+{
+ std::cerr << "ppio_ppdev: Not implemented on this platform\n";
+ throw std::runtime_error ("not implmeneted");
+}
+
+ppio_ppdev::~ppio_ppdev ()
+{
+}
+
+void
+ppio_ppdev::write_data (unsigned char v)
+{
+}
+
+unsigned char
+ppio_ppdev::read_data ()
+{
+ return 0;
+}
+
+void
+ppio_ppdev::write_control (unsigned char v)
+{
+}
+
+unsigned char
+ppio_ppdev::read_control ()
+{
+ return 0;
+}
+
+unsigned char
+ppio_ppdev::read_status ()
+{
+ return 0;
+}
+
+void
+ppio_ppdev::lock ()
+{
+}
+
+void
+ppio_ppdev::unlock ()
+{
+}
+
+#endif
+
+ppio_ppdev_sptr
+make_ppio_ppdev (int which)
+{
+ return ppio_ppdev_sptr (new ppio_ppdev (which));
+}
diff --git a/gnuradio-core/src/lib/io/ppio_ppdev.h b/gnuradio-core/src/lib/io/ppio_ppdev.h
new file mode 100644
index 000000000..1f86d7e04
--- /dev/null
+++ b/gnuradio-core/src/lib/io/ppio_ppdev.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2001,2003 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_PPIO_PPDEV_H
+#define INCLUDED_PPIO_PPDEV_H
+
+#include <gr_core_api.h>
+#include <ppio.h>
+
+class ppio_ppdev;
+typedef boost::shared_ptr<ppio_ppdev> ppio_ppdev_sptr;
+
+/*!
+ * \brief access to parallel port bits using the linux ppdev interface
+ * \ingroup hardware
+ */
+
+class GR_CORE_API ppio_ppdev : public ppio {
+ friend GR_CORE_API ppio_ppdev_sptr make_ppio_ppdev (int which = 0);
+ ppio_ppdev (int which = 0);
+
+ public:
+ virtual ~ppio_ppdev ();
+
+ virtual void write_data (unsigned char v);
+ virtual unsigned char read_data ();
+ virtual void write_control (unsigned char v);
+ virtual unsigned char read_control ();
+ virtual unsigned char read_status ();
+
+ virtual void lock ();
+ virtual void unlock ();
+
+ private:
+ int d_fd;
+};
+
+ppio_ppdev_sptr
+make_ppio_ppdev (int which);
+
+
+#endif /* INCLUDED_PPIO_PPDEV_H */
+
diff --git a/gnuradio-core/src/lib/io/sdr_1000.cc b/gnuradio-core/src/lib/io/sdr_1000.cc
new file mode 100644
index 000000000..a8c2555e0
--- /dev/null
+++ b/gnuradio-core/src/lib/io/sdr_1000.cc
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 <sdr_1000.h>
+#include <ppio.h>
+
+sdr_1000_base::sdr_1000_base (int which_pp)
+{
+ d_ppio = make_ppio (which_pp);
+ d_shadow[0] = 0;
+ d_shadow[1] = 0;
+ d_shadow[2] = 0;
+ d_shadow[3] = 0;
+ reset ();
+}
+
+sdr_1000_base::~sdr_1000_base ()
+{
+}
+
+void
+sdr_1000_base::reset ()
+{
+ d_ppio->lock ();
+ d_ppio->write_control (0x0F);
+ d_ppio->unlock ();
+ write_latch (L_EXT, 0x00, 0xff);
+ write_latch (L_BAND, 0x00, 0xff);
+ write_latch (L_DDS0, 0x80, 0xff); // hold DDS in reset
+ write_latch (L_DDS1, 0x00, 0xff);
+}
+
+
+void
+sdr_1000_base::write_latch (int which, int value, int mask)
+{
+ if (!(0 <= which && which <= 3))
+ return;
+
+ d_ppio->lock ();
+ d_shadow[which] = (d_shadow[which] & ~mask) | (value & mask);
+ d_ppio->write_data (d_shadow[which]);
+ d_ppio->write_control (0x0F ^ (1 << which));
+ d_ppio->write_control (0x0F);
+ d_ppio->unlock ();
+}
diff --git a/gnuradio-core/src/lib/io/sdr_1000.h b/gnuradio-core/src/lib/io/sdr_1000.h
new file mode 100644
index 000000000..c00608a3a
--- /dev/null
+++ b/gnuradio-core/src/lib/io/sdr_1000.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2004 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_SDR_1000_H
+#define INCLUDED_SDR_1000_H
+
+#include <gr_core_api.h>
+#include <boost/shared_ptr.hpp>
+
+class ppio;
+typedef boost::shared_ptr<ppio> ppio_sptr;
+
+
+enum { L_EXT = 0, L_BAND = 1, L_DDS0 = 2, L_DDS1 = 3 };
+
+/*!
+ * \brief Very low level interface to SDR 1000 xcvr hardware
+ * \sa sdr_1000.py for a higher level interface.
+ * \ingroup hardware
+ */
+class GR_CORE_API sdr_1000_base {
+ ppio_sptr d_ppio;
+ int d_shadow[4]; // shadow latches
+
+public:
+
+ sdr_1000_base (int which_pp);
+ ~sdr_1000_base ();
+
+ void reset ();
+ void write_latch (int which, int value, int mask);
+};
+
+#endif /* INCLUDED_SDR_1000_H */
diff --git a/gnuradio-core/src/lib/io/sdr_1000.i b/gnuradio-core/src/lib/io/sdr_1000.i
new file mode 100644
index 000000000..c9b1ef560
--- /dev/null
+++ b/gnuradio-core/src/lib/io/sdr_1000.i
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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.
+ */
+
+const int L_EXT = 0;
+const int L_BAND = 1;
+const int L_DDS0 = 2;
+const int L_DDS1 = 3;
+
+class sdr_1000_base {
+public:
+
+ sdr_1000_base (int which_pp);
+ ~sdr_1000_base ();
+
+ void reset ();
+ void write_latch (int which, int value, int mask);
+};