summaryrefslogtreecommitdiff
path: root/gr-blocks
diff options
context:
space:
mode:
authorTom Rondeau <trondeau@vt.edu>2013-03-16 10:29:20 -0400
committerTom Rondeau <trondeau@vt.edu>2013-03-16 10:29:20 -0400
commit57720572843fe89aaf6edc02a50859780b349b6c (patch)
tree3d36e7f8c3c4194ab6ee238213a67ed181876e14 /gr-blocks
parent3d38e82e7d87dfc01132b199e33b53add8a706fa (diff)
parent4412cb10077cb40659ab5bc9c4dc814ca88a380b (diff)
Merge branch 'next' of gnuradio.org:gnuradio into next
Diffstat (limited to 'gr-blocks')
-rw-r--r--gr-blocks/CMakeLists.txt1
-rw-r--r--gr-blocks/grc/blocks_block_tree.xml1
-rw-r--r--gr-blocks/grc/blocks_repack_bits_bb.xml46
-rw-r--r--gr-blocks/grc/blocks_tagged_stream_mux.xml65
-rw-r--r--gr-blocks/include/blocks/CMakeLists.txt6
-rw-r--r--gr-blocks/include/blocks/message_sink.h5
-rw-r--r--gr-blocks/include/blocks/message_source.h2
-rw-r--r--gr-blocks/include/blocks/repack_bits_bb.h65
-rw-r--r--gr-blocks/include/blocks/tagged_stream_mux.h61
-rw-r--r--gr-blocks/lib/CMakeLists.txt7
-rw-r--r--gr-blocks/lib/message_sink_impl.cc79
-rw-r--r--gr-blocks/lib/message_sink_impl.h6
-rw-r--r--gr-blocks/lib/message_source_impl.cc100
-rw-r--r--gr-blocks/lib/message_source_impl.h6
-rw-r--r--gr-blocks/lib/repack_bits_bb_impl.cc123
-rw-r--r--gr-blocks/lib/repack_bits_bb_impl.h58
-rw-r--r--gr-blocks/lib/tagged_stream_mux_impl.cc93
-rw-r--r--gr-blocks/lib/tagged_stream_mux_impl.h54
-rw-r--r--gr-blocks/python/qa_message_tags.py27
-rwxr-xr-xgr-blocks/python/qa_repack_bits_bb.py127
-rwxr-xr-xgr-blocks/python/qa_tagged_stream_mux.py111
-rw-r--r--gr-blocks/swig/blocks_swig.i12
-rw-r--r--gr-blocks/tests/CMakeLists.txt2
23 files changed, 998 insertions, 59 deletions
diff --git a/gr-blocks/CMakeLists.txt b/gr-blocks/CMakeLists.txt
index 9772803705..98f73d2177 100644
--- a/gr-blocks/CMakeLists.txt
+++ b/gr-blocks/CMakeLists.txt
@@ -34,6 +34,7 @@ GR_REGISTER_COMPONENT("gr-blocks" ENABLE_GR_BLOCKS
GR_SET_GLOBAL(GR_BLOCKS_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/lib
${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_BINARY_DIR}/lib
${CMAKE_CURRENT_BINARY_DIR}/include
)
diff --git a/gr-blocks/grc/blocks_block_tree.xml b/gr-blocks/grc/blocks_block_tree.xml
index 42adc804a8..90d94bdb29 100644
--- a/gr-blocks/grc/blocks_block_tree.xml
+++ b/gr-blocks/grc/blocks_block_tree.xml
@@ -97,6 +97,7 @@
<block>blocks_int_to_float</block>
<block>blocks_interleaved_short_to_complex</block>
<block>blocks_short_to_char</block>
+ <block>blocks_repack_bits_bb</block>
<block>blocks_short_to_float</block>
<block>blocks_uchar_to_float</block>
</cat>
diff --git a/gr-blocks/grc/blocks_repack_bits_bb.xml b/gr-blocks/grc/blocks_repack_bits_bb.xml
new file mode 100644
index 0000000000..4ad5ec631b
--- /dev/null
+++ b/gr-blocks/grc/blocks_repack_bits_bb.xml
@@ -0,0 +1,46 @@
+<block>
+ <name>Repack Bits</name>
+ <key>blocks_repack_bits_bb</key>
+ <import>from gnuradio import blocks</import>
+ <make>blocks.repack_bits_bb($k, $l, $len_tag_key, $align_output)</make>
+ <param>
+ <name>Bits per input byte</name>
+ <key>k</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Bits per output byte</name>
+ <key>l</key>
+ <value>8</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Length Tag Key</name>
+ <key>len_tag_key</key>
+ <value>""</value>
+ <type>string</type>
+ </param>
+ <param>
+ <name>Packet Alignment</name>
+ <key>align_output</key>
+ <value>False</value>
+ <type>enum</type>
+ <option>
+ <name>Output</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Input</name>
+ <key>False</key>
+ </option>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-blocks/grc/blocks_tagged_stream_mux.xml b/gr-blocks/grc/blocks_tagged_stream_mux.xml
new file mode 100644
index 0000000000..40d98a3346
--- /dev/null
+++ b/gr-blocks/grc/blocks_tagged_stream_mux.xml
@@ -0,0 +1,65 @@
+<block>
+ <name>Tagged Stream Mux</name>
+ <key>blocks_tagged_stream_mux</key>
+ <category>Stream Operations</category>
+ <import>from gnuradio import blocks</import>
+ <make>blocks.tagged_stream_mux($type.size*$vlen, $lengthtagname)</make>
+ <param>
+ <name>IO Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>size:gr.sizeof_gr_complex</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>size:gr.sizeof_float</opt>
+ </option>
+ <option>
+ <name>Int</name>
+ <key>int</key>
+ <opt>size:gr.sizeof_int</opt>
+ </option>
+ <option>
+ <name>Short</name>
+ <key>short</key>
+ <opt>size:gr.sizeof_short</opt>
+ </option>
+ <option>
+ <name>Byte</name>
+ <key>byte</key>
+ <opt>size:gr.sizeof_char</opt>
+ </option>
+ </param>
+ <param>
+ <name>Number of inputs</name>
+ <key>ninputs</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Length tag names</name>
+ <key>lengthtagname</key>
+ <type>string</type>
+ </param>
+ <param>
+ <name>Vector Length</name>
+ <key>vlen</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ <vlen>$vlen</vlen>
+ <nports>$ninputs</nports>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type</type>
+ <vlen>$vlen</vlen>
+ </source>
+</block>
+
diff --git a/gr-blocks/include/blocks/CMakeLists.txt b/gr-blocks/include/blocks/CMakeLists.txt
index 82d4179c72..0f158ff473 100644
--- a/gr-blocks/include/blocks/CMakeLists.txt
+++ b/gr-blocks/include/blocks/CMakeLists.txt
@@ -65,8 +65,8 @@ endmacro(expand_h)
# Invoke macro to generate various sources
########################################################################
expand_h(add_XX ss ii cc)
-expand_h(add_const_XX ss ii ff cc)
-expand_h(add_const_vXX ss ii ff cc)
+expand_h(add_const_XX bb ss ii ff cc)
+expand_h(add_const_vXX bb ss ii ff cc)
expand_h(and_XX bb ss ii)
expand_h(and_const_XX bb ss ii)
expand_h(argmax_XX fs is ss)
@@ -156,6 +156,7 @@ install(FILES
random_pdu.h
probe_rate.h
regenerate_bb.h
+ repack_bits_bb.h
repeat.h
rms_cf.h
rms_ff.h
@@ -175,6 +176,7 @@ install(FILES
throttle.h
transcendental.h
tuntap_pdu.h
+ tagged_stream_mux.h
uchar_to_float.h
udp_sink.h
udp_source.h
diff --git a/gr-blocks/include/blocks/message_sink.h b/gr-blocks/include/blocks/message_sink.h
index 5d14836dd4..5d3084d02d 100644
--- a/gr-blocks/include/blocks/message_sink.h
+++ b/gr-blocks/include/blocks/message_sink.h
@@ -40,7 +40,10 @@ namespace gr {
// gr::blocks::message_sink::sptr
typedef boost::shared_ptr<message_sink> sptr;
- static sptr make (size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+ static sptr make(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+ static sptr make(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block,
+ const std::string& lengthtagname);
+
};
} /* namespace blocks */
diff --git a/gr-blocks/include/blocks/message_source.h b/gr-blocks/include/blocks/message_source.h
index 5b55191880..cf4bafc22b 100644
--- a/gr-blocks/include/blocks/message_source.h
+++ b/gr-blocks/include/blocks/message_source.h
@@ -42,6 +42,8 @@ namespace gr {
static sptr make(size_t itemsize, int msgq_limit=0);
static sptr make(size_t itemsize, gr_msg_queue_sptr msgq);
+ static sptr make(size_t itemsize, gr_msg_queue_sptr msgq,
+ const std::string& lengthtagname);
virtual gr_msg_queue_sptr msgq() const = 0;
};
diff --git a/gr-blocks/include/blocks/repack_bits_bb.h b/gr-blocks/include/blocks/repack_bits_bb.h
new file mode 100644
index 0000000000..9ade0a4353
--- /dev/null
+++ b/gr-blocks/include/blocks/repack_bits_bb.h
@@ -0,0 +1,65 @@
+/* -*- 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_BLOCKS_REPACK_BITS_BB_H
+#define INCLUDED_BLOCKS_REPACK_BITS_BB_H
+
+#include <blocks/api.h>
+#include <gr_tagged_stream_block.h>
+
+namespace gr {
+ namespace blocks {
+
+ /*!
+ * \brief Pack \p k bits from the input stream onto \p k bits of the output stream.
+ * \ingroup blocks
+ *
+ * No bits are lost here; any value for k and l (within [1, 8]) is allowed.
+ * On every fresh input byte, it starts reading on the LSB, and starts copying
+ * to the LSB as well.
+ *
+ * If a packet length tag is given, this block assumes a tagged stream.
+ * In this case, the tag with the packet length is updated accordingly.
+ * Also, the number of input bits is padded with zeros if the number of input
+ * bits is not an integer multiple of \p l, or bits are truncated from the input
+ * if \p align_output is set to true.
+ */
+ class BLOCKS_API repack_bits_bb : virtual public gr_tagged_stream_block
+ {
+ public:
+ typedef boost::shared_ptr<repack_bits_bb> sptr;
+
+ /*!
+ * \param k Number of relevant bits on the input stream
+ * \param l Number of relevant bits on the output stream
+ * \param len_tag_key If not empty, this is the key for the length tag.
+ * \param align_output If len_tag_key is given, this controls if the input
+ * or the output is aligned.
+ */
+ static sptr make(int k, int l=8, const std::string &len_tag_key="", bool align_output=false);
+ };
+
+ } // namespace blocks
+} // namespace gr
+
+#endif /* INCLUDED_BLOCKS_REPACK_BITS_BB_H */
+
diff --git a/gr-blocks/include/blocks/tagged_stream_mux.h b/gr-blocks/include/blocks/tagged_stream_mux.h
new file mode 100644
index 0000000000..23e8a94403
--- /dev/null
+++ b/gr-blocks/include/blocks/tagged_stream_mux.h
@@ -0,0 +1,61 @@
+/* -*- 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_TAGGED_STREAM_MUX_H
+#define INCLUDED_TAGGED_STREAM_MUX_H
+
+#include <blocks/api.h>
+#include <gr_tagged_stream_block.h>
+
+namespace gr {
+ namespace blocks {
+
+ /*!
+ * \brief Combines tagged streams.
+ *
+ * \description
+ * Takes N streams as input. Each stream is tagged with packet lengths.
+ * Packets are output sequentially from each input stream.
+ *
+ * The output signal has a new length tag, which is the sum of all
+ * individual length tags.
+ *
+ * All other tags are propagated as expected, i.e. they stay associated
+ * with the same input item.
+ *
+ * \ingroup blocks
+ */
+ class BLOCKS_API tagged_stream_mux : virtual public gr_tagged_stream_block
+ {
+ public:
+ typedef boost::shared_ptr<tagged_stream_mux> sptr;
+
+ /* \param itemsize Items size (number of bytes per item)
+ * \param lengthtagname Length tag key
+ */
+ static sptr make(size_t itemsize, const std::string &lengthtagname);
+ };
+
+ } // namespace blocks
+} // namespace gr
+
+#endif /* INCLUDED_TAGGED_STREAM_MUX_H */
+
diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt
index c7a7b6362f..de73a8a308 100644
--- a/gr-blocks/lib/CMakeLists.txt
+++ b/gr-blocks/lib/CMakeLists.txt
@@ -91,8 +91,8 @@ endmacro(expand_cc_h_impl)
# Invoke macro to generate various sources
########################################################################
expand_cc_h_impl(add_XX ss ii cc)
-expand_cc_h_impl(add_const_XX ss ii ff cc)
-expand_cc_h_impl(add_const_vXX ss ii ff cc)
+expand_cc_h_impl(add_const_XX bb ss ii ff cc)
+expand_cc_h_impl(add_const_vXX bb ss ii ff cc)
expand_cc_h_impl(and_XX bb ss ii)
expand_cc_h_impl(and_const_XX bb ss ii)
expand_cc_h_impl(argmax_XX fs is ss)
@@ -200,6 +200,7 @@ list(APPEND gr_blocks_sources
random_pdu_impl.cc
probe_rate_impl.cc
regenerate_bb_impl.cc
+ repack_bits_bb_impl.cc
repeat_impl.cc
rms_cf_impl.cc
rms_ff_impl.cc
@@ -220,6 +221,7 @@ list(APPEND gr_blocks_sources
transcendental_impl.cc
tcp_connection.cc
tuntap_pdu_impl.cc
+ tagged_stream_mux_impl.cc
uchar_array_to_float.cc
uchar_to_float_impl.cc
udp_sink_impl.cc
@@ -251,6 +253,7 @@ list(APPEND blocks_libs
volk
${Boost_LIBRARIES}
${BLOCKS_LIBRARIES}
+ ${LOG4CPP_LIBRARIES}
)
add_library(gnuradio-blocks SHARED ${gr_blocks_sources})
diff --git a/gr-blocks/lib/message_sink_impl.cc b/gr-blocks/lib/message_sink_impl.cc
index a8dbfb4c71..fbc7b27d58 100644
--- a/gr-blocks/lib/message_sink_impl.cc
+++ b/gr-blocks/lib/message_sink_impl.cc
@@ -44,11 +44,30 @@ namespace gr {
(new message_sink_impl(itemsize, msgq, dont_block));
}
+ message_sink::sptr
+ message_sink::make(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block,
+ const std::string& lengthtagname)
+ {
+ return gnuradio::get_initial_sptr
+ (new message_sink_impl(itemsize, msgq, dont_block, lengthtagname));
+ }
+
message_sink_impl::message_sink_impl(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)
+ d_itemsize(itemsize), d_msgq(msgq), d_dont_block(dont_block),
+ d_tags(false), d_items_read(0)
+ {
+ }
+
+ message_sink_impl::message_sink_impl(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block,
+ const std::string& lengthtagname)
+ : 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),
+ d_tags(true), d_lengthtagname(lengthtagname), d_items_read(0)
{
}
@@ -61,23 +80,53 @@ namespace gr {
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);
+ const char *in = (const char *) input_items[0];
- d_msgq->handle(msg); // send it
+ if (d_tags) {
+ long packet_length = 0;
+ std::vector<gr_tag_t> tags;
+ this->get_tags_in_range(tags, 0, d_items_read, d_items_read+1);
+ //const size_t ninput_items = noutput_items; //assumption for sync block, this can change
+ for (unsigned int i = 0; i < tags.size(); i++) {
+ if (pmt::symbol_to_string(tags[i].key) == d_lengthtagname) {
+ packet_length = pmt::to_long(tags[i].value);
+ }
+ }
+ assert(packet_length != 0);
+
+ // FIXME run this multiple times if input_items >= N * packet_length
+ if (noutput_items >= packet_length ) {
+ // If the message queue is full we drop the packet.
+ if (!d_msgq->full_p()) {
+ gr_message_sptr msg = gr_make_message(0, // msg type
+ d_itemsize, // arg1 for other end
+ packet_length, // arg2 for other end (redundant)
+ packet_length * d_itemsize); // len of msg
+ memcpy(msg->msg(), in, packet_length * d_itemsize);
+ d_msgq->handle(msg); // send it
+ }
+ d_items_read += packet_length;
+ return packet_length;
+ } else {
+ return 0;
+ }
+ } else {
+ // If the queue if full we drop all the data we got.
+ if (!d_msgq->full_p()) {
+ // 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;
+ return noutput_items;
+ }
}
} /* namespace blocks */
} /* namespace gr */
+
diff --git a/gr-blocks/lib/message_sink_impl.h b/gr-blocks/lib/message_sink_impl.h
index a3106bc058..280a46765e 100644
--- a/gr-blocks/lib/message_sink_impl.h
+++ b/gr-blocks/lib/message_sink_impl.h
@@ -34,9 +34,15 @@ namespace gr {
size_t d_itemsize;
gr_msg_queue_sptr d_msgq;
bool d_dont_block;
+ bool d_tags;
+ std::string d_lengthtagname;
+ uint64_t d_items_read;
public:
message_sink_impl(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block);
+ message_sink_impl(size_t itemsize, gr_msg_queue_sptr msgq, bool dont_block,
+ const std::string& lengthtagname);
+
~message_sink_impl();
int work(int noutput_items,
diff --git a/gr-blocks/lib/message_source_impl.cc b/gr-blocks/lib/message_source_impl.cc
index cda4fc16c0..818cd336f1 100644
--- a/gr-blocks/lib/message_source_impl.cc
+++ b/gr-blocks/lib/message_source_impl.cc
@@ -51,12 +51,20 @@ namespace gr {
(new message_source_impl(itemsize, msgq));
}
+ message_source::sptr
+ message_source::make(size_t itemsize, gr_msg_queue_sptr msgq,
+ const std::string& lengthtagname)
+ {
+ return gnuradio::get_initial_sptr
+ (new message_source_impl(itemsize, msgq, lengthtagname));
+ }
+
message_source_impl::message_source_impl(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)
+ d_msg_offset(0), d_eof(false), d_tags(false)
{
}
@@ -65,7 +73,17 @@ namespace gr {
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)
+ d_msg_offset(0), d_eof(false), d_tags(false)
+ {
+ }
+
+ message_source_impl::message_source_impl(size_t itemsize, gr_msg_queue_sptr msgq,
+ const std::string& lengthtagname)
+ : 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),
+ d_tags(true), d_lengthtagname(lengthtagname)
{
}
@@ -82,42 +100,48 @@ namespace gr {
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");
- }
+ 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);
+
+ if (d_tags && (d_msg_offset == 0)) {
+ const uint64_t offset = this->nitems_written(0) + nn;
+ pmt::pmt_t key = pmt::string_to_symbol(d_lengthtagname);
+ pmt::pmt_t value = pmt::from_long(d_msg->length());
+ this->add_item_tag(0, offset, key, value);
+ }
+ 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/gr-blocks/lib/message_source_impl.h b/gr-blocks/lib/message_source_impl.h
index c420704478..8fbd209e0a 100644
--- a/gr-blocks/lib/message_source_impl.h
+++ b/gr-blocks/lib/message_source_impl.h
@@ -37,10 +37,16 @@ namespace gr {
gr_message_sptr d_msg;
unsigned d_msg_offset;
bool d_eof;
+ bool d_tags;
+ // FIXME: Is this adequate tagname length.
+ std::string d_lengthtagname;
public:
message_source_impl(size_t itemsize, int msgq_limit);
message_source_impl(size_t itemsize, gr_msg_queue_sptr msgq);
+ message_source_impl(size_t itemsize, gr_msg_queue_sptr msgq,
+ const std::string& lengthtagname);
+
~message_source_impl();
gr_msg_queue_sptr msgq() const { return d_msgq; }
diff --git a/gr-blocks/lib/repack_bits_bb_impl.cc b/gr-blocks/lib/repack_bits_bb_impl.cc
new file mode 100644
index 0000000000..c7ed054c8a
--- /dev/null
+++ b/gr-blocks/lib/repack_bits_bb_impl.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 <gr_io_signature.h>
+#include "repack_bits_bb_impl.h"
+
+namespace gr {
+ namespace blocks {
+
+ repack_bits_bb::sptr
+ repack_bits_bb::make(int k, int l, const std::string &len_tag_key, bool align_output)
+ {
+ return gnuradio::get_initial_sptr (new repack_bits_bb_impl(k, l, len_tag_key, align_output));
+ }
+
+ repack_bits_bb_impl::repack_bits_bb_impl(int k, int l, const std::string &len_tag_key, bool align_output)
+ : gr_tagged_stream_block("repack_bits_bb",
+ gr_make_io_signature(1, 1, sizeof (char)),
+ gr_make_io_signature(1, 1, sizeof (char)),
+ len_tag_key),
+ d_k(k), d_l(l),
+ d_packet_mode(!len_tag_key.empty()),
+ d_in_index(0), d_out_index(0),
+ d_align_output(align_output)
+ {
+ if (d_k > 8 || d_k < 1 || d_l > 8 || d_l < 1) {
+ throw std::invalid_argument("k and l must be in [1, 8]");
+ }
+
+ set_relative_rate((double) d_k / d_l);
+ }
+
+ repack_bits_bb_impl::~repack_bits_bb_impl()
+ {
+ }
+
+ int
+ repack_bits_bb_impl::calculate_output_stream_length(const gr_vector_int &ninput_items)
+ {
+ int n_out_bytes_required = (ninput_items[0] * d_k) / d_l;
+ if ((ninput_items[0] * d_k) % d_l && (!d_packet_mode || (d_packet_mode && !d_align_output))) {
+ n_out_bytes_required++;
+ }
+
+ return n_out_bytes_required;
+ }
+
+ int
+ repack_bits_bb_impl::work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+ int bytes_to_write = noutput_items;
+
+ if (d_packet_mode) { // noutput_items could be larger than necessary
+ int bytes_to_read = ninput_items[0];
+ bytes_to_write = bytes_to_read * d_k / d_l;
+ if (!d_align_output && (((bytes_to_read * d_k) % d_l) != 0)) {
+ bytes_to_write++;
+ }
+ }
+
+ int n_read = 0;
+ int n_written = 0;
+ while(n_written < bytes_to_write && n_read < ninput_items[0]) {
+ if (d_out_index == 0) { // Starting a fresh byte
+ out[n_written] = 0;
+ }
+ out[n_written] |= ((in[n_read] >> d_in_index) & 0x01) << d_out_index;
+
+ d_in_index = (d_in_index + 1) % d_k;
+ d_out_index = (d_out_index + 1) % d_l;
+ if (d_in_index == 0) {
+ n_read++;
+ d_in_index = 0;
+ }
+ if (d_out_index == 0) {
+ n_written++;
+ d_out_index = 0;
+ }
+ }
+
+ if (d_packet_mode) {
+ if (d_out_index) {
+ n_written++;
+ d_out_index = 0;
+ }
+ } else {
+ consume_each(n_read);
+ }
+
+ return n_written;
+ }
+
+ } /* namespace blocks */
+} /* namespace gr */
+
diff --git a/gr-blocks/lib/repack_bits_bb_impl.h b/gr-blocks/lib/repack_bits_bb_impl.h
new file mode 100644
index 0000000000..bf39f8cb0f
--- /dev/null
+++ b/gr-blocks/lib/repack_bits_bb_impl.h
@@ -0,0 +1,58 @@
+/* -*- 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_BLOCKS_REPACK_BITS_BB_IMPL_H
+#define INCLUDED_BLOCKS_REPACK_BITS_BB_IMPL_H
+
+#include <blocks/repack_bits_bb.h>
+
+namespace gr {
+ namespace blocks {
+
+ class repack_bits_bb_impl : public repack_bits_bb
+ {
+ private:
+ const int d_k; //! Bits on input stream
+ const int d_l; //! Bits on output stream
+ const bool d_packet_mode;
+ int d_in_index; // Current bit of input byte
+ int d_out_index; // Current bit of output byte
+ bool d_align_output; //! true if the output shall be aligned, false if the input shall be aligned
+
+ protected:
+ int calculate_output_stream_length(const gr_vector_int &ninput_items);
+
+ public:
+ repack_bits_bb_impl(int k, int l, const std::string &len_tag_key, bool align_output);
+ ~repack_bits_bb_impl();
+
+ int work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } // namespace blocks
+} // namespace gr
+
+#endif /* INCLUDED_BLOCKS_REPACK_BITS_BB_IMPL_H */
+
diff --git a/gr-blocks/lib/tagged_stream_mux_impl.cc b/gr-blocks/lib/tagged_stream_mux_impl.cc
new file mode 100644
index 0000000000..59e36fa07e
--- /dev/null
+++ b/gr-blocks/lib/tagged_stream_mux_impl.cc
@@ -0,0 +1,93 @@
+/* -*- 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_io_signature.h>
+#include "tagged_stream_mux_impl.h"
+
+namespace gr {
+ namespace blocks {
+
+ tagged_stream_mux::sptr
+ tagged_stream_mux::make(size_t itemsize, const std::string &lengthtagname)
+ {
+ return gnuradio::get_initial_sptr (new tagged_stream_mux_impl(itemsize, lengthtagname));
+ }
+
+ tagged_stream_mux_impl::tagged_stream_mux_impl(size_t itemsize, const std::string &lengthtagname)
+ : gr_tagged_stream_block("tagged_stream_mux",
+ gr_make_io_signature(1, -1, itemsize),
+ gr_make_io_signature(1, 1, itemsize),
+ lengthtagname),
+ d_itemsize(itemsize)
+ {
+ set_tag_propagation_policy(TPP_DONT);
+ }
+
+ tagged_stream_mux_impl::~tagged_stream_mux_impl()
+ {
+ }
+
+ int
+ tagged_stream_mux_impl::calculate_output_stream_length(const gr_vector_int &ninput_items)
+ {
+ int nout = 0;
+ for (unsigned i = 0; i < ninput_items.size(); i++) {
+ nout += ninput_items[i];
+ }
+ return nout;
+ }
+
+ int
+ tagged_stream_mux_impl::work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ unsigned char *out = (unsigned char *) output_items[0];
+ int n_produced = 0;
+
+ set_relative_rate(ninput_items.size());
+
+ for (unsigned int i = 0; i < input_items.size(); i++) {
+ const unsigned char *in = (const unsigned char *) input_items[i];
+
+ std::vector<gr_tag_t> tags;
+ get_tags_in_range(tags, i, nitems_read(i), nitems_read(i)+ninput_items[i]);
+ for (unsigned int j = 0; j < tags.size(); j++) {
+ const uint64_t offset = tags[j].offset - nitems_read(i) + nitems_written(0) + n_produced;
+ add_item_tag(0, offset, tags[j].key, tags[j].value);
+ }
+ memcpy((void *) out, (const void *) in, ninput_items[i] * d_itemsize);
+ out += ninput_items[i] * d_itemsize;
+ n_produced += ninput_items[i];
+ }
+
+ return n_produced;
+ }
+
+ } /* namespace blocks */
+} /* namespace gr */
+
diff --git a/gr-blocks/lib/tagged_stream_mux_impl.h b/gr-blocks/lib/tagged_stream_mux_impl.h
new file mode 100644
index 0000000000..19862e6868
--- /dev/null
+++ b/gr-blocks/lib/tagged_stream_mux_impl.h
@@ -0,0 +1,54 @@
+/* -*- 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_TAGGED_STREAM_MUX_IMPL_H
+#define INCLUDED_TAGGED_STREAM_MUX_IMPL_H
+
+#include <vector>
+#include <blocks/tagged_stream_mux.h>
+
+namespace gr {
+ namespace blocks {
+
+ class tagged_stream_mux_impl : public tagged_stream_mux
+ {
+ private:
+ size_t d_itemsize;
+
+ protected:
+ int calculate_output_stream_length(const std::vector<int> &ninput_items);
+
+ public:
+ tagged_stream_mux_impl(size_t itemsize, const std::string &lengthtagname);
+ ~tagged_stream_mux_impl();
+
+ int work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } // namespace blocks
+} // namespace gr
+
+#endif
+
diff --git a/gr-blocks/python/qa_message_tags.py b/gr-blocks/python/qa_message_tags.py
new file mode 100644
index 0000000000..0ab857b1aa
--- /dev/null
+++ b/gr-blocks/python/qa_message_tags.py
@@ -0,0 +1,27 @@
+import time
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+
+class test_message_tags (gr_unittest.TestCase):
+
+ def test_1 (self):
+ data = ('hello', 'you', 'there')
+ tx_msgq = gr.msg_queue ()
+ rx_msgq = gr.msg_queue ()
+ for d in data:
+ tx_msgq.insert_tail(gr.message_from_string(d))
+ tb = gr.top_block()
+ src = blocks.message_source(gr.sizeof_char, tx_msgq, "packet_length")
+ snk = blocks.message_sink(gr.sizeof_char, rx_msgq, False, "packet_length")
+ tb.connect(src, snk)
+ tb.start()
+ time.sleep(1)
+ tb.stop()
+ for d in data:
+ msg = rx_msgq.delete_head()
+ contents = msg.to_string()
+ self.assertEqual(d, contents)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_message_tags, "test_message_tags.xml")
diff --git a/gr-blocks/python/qa_repack_bits_bb.py b/gr-blocks/python/qa_repack_bits_bb.py
new file mode 100755
index 0000000000..3f88df4a68
--- /dev/null
+++ b/gr-blocks/python/qa_repack_bits_bb.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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.
+#
+
+import random
+from gnuradio import gr, gr_unittest
+import pmt
+import blocks_swig as blocks
+
+class qa_repack_bits_bb (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001_simple (self):
+ """ Very simple test, 2 bits -> 1 """
+ src_data = (0b11, 0b01, 0b10)
+ expected_data = (0b1, 0b1, 0b1, 0b0, 0b0, 0b1)
+ k = 2
+ l = 1
+ src = gr.vector_source_b(src_data, False, 1)
+ repack = blocks.repack_bits_bb(k, l)
+ sink = gr.vector_sink_b()
+ self.tb.connect(src, repack, sink)
+ self.tb.run ()
+ self.assertEqual(sink.data(), expected_data)
+
+ def test_002_three (self):
+ """ 8 -> 3 """
+ src_data = (0b11111101, 0b11111111, 0b11111111)
+ expected_data = (0b101,) + (0b111,) * 7
+ k = 8
+ l = 3
+ src = gr.vector_source_b(src_data, False, 1)
+ repack = blocks.repack_bits_bb(k, l)
+ sink = gr.vector_sink_b()
+ self.tb.connect(src, repack, sink)
+ self.tb.run ()
+ self.assertEqual(sink.data(), expected_data)
+
+ def test_003_lots_of_bytes (self):
+ """ Lots and lots of bytes, multiple packer stages """
+ src_data = tuple([random.randint(0, 255) for x in range(3*5*7*8 * 10)])
+ src = gr.vector_source_b(src_data, False, 1)
+ repack1 = blocks.repack_bits_bb(8, 3)
+ repack2 = blocks.repack_bits_bb(3, 5)
+ repack3 = blocks.repack_bits_bb(5, 7)
+ repack4 = blocks.repack_bits_bb(7, 8)
+ sink = gr.vector_sink_b()
+ self.tb.connect(src, repack1, repack2, repack3, repack4, sink)
+ self.tb.run ()
+ self.assertEqual(sink.data(), src_data)
+
+ def test_004_three_with_tags (self):
+ """ 8 -> 3 """
+ src_data = (0b11111101, 0b11111111)
+ expected_data = (0b101,) + (0b111,) * 4 + (0b001,)
+ k = 8
+ l = 3
+ tag_name = "len"
+ tag = gr.gr_tag_t()
+ tag.offset = 0
+ tag.key = pmt.string_to_symbol(tag_name)
+ tag.value = pmt.from_long(len(src_data))
+ src = gr.vector_source_b(src_data, False, 1, (tag,))
+ repack = blocks.repack_bits_bb(k, l, tag_name)
+ sink = gr.vector_sink_b()
+ self.tb.connect(src, repack, sink)
+ self.tb.run ()
+ self.assertEqual(sink.data(), expected_data)
+ try:
+ out_tag = sink.tags()[0]
+ except:
+ self.assertFail()
+ self.assertEqual(out_tag.offset, 0)
+ self.assertEqual(pmt.symbol_to_string(out_tag.key), tag_name)
+ self.assertEqual(pmt.to_long(out_tag.value), len(expected_data))
+
+ def test_005_three_with_tags_trailing (self):
+ """ 3 -> 8, trailing bits """
+ src_data = (0b101,) + (0b111,) * 4 + (0b001,)
+ expected_data = (0b11111101, 0b11111111)
+ k = 3
+ l = 8
+ tag_name = "len"
+ tag = gr.gr_tag_t()
+ tag.offset = 0
+ tag.key = pmt.string_to_symbol(tag_name)
+ tag.value = pmt.from_long(len(src_data))
+ src = gr.vector_source_b(src_data, False, 1, (tag,))
+ repack = blocks.repack_bits_bb(k, l, tag_name, True)
+ sink = gr.vector_sink_b()
+ self.tb.connect(src, repack, sink)
+ self.tb.run ()
+ self.assertEqual(sink.data(), expected_data)
+ try:
+ out_tag = sink.tags()[0]
+ except:
+ self.assertFail()
+ self.assertEqual(out_tag.offset, 0)
+ self.assertEqual(pmt.symbol_to_string(out_tag.key), tag_name)
+ self.assertEqual(pmt.to_long(out_tag.value), len(expected_data))
+
+if __name__ == '__main__':
+ gr_unittest.run(qa_repack_bits_bb, "qa_repack_bits_bb.xml")
+
diff --git a/gr-blocks/python/qa_tagged_stream_mux.py b/gr-blocks/python/qa_tagged_stream_mux.py
new file mode 100755
index 0000000000..e39f8cac29
--- /dev/null
+++ b/gr-blocks/python/qa_tagged_stream_mux.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import pmt
+import blocks_swig as blocks
+import numpy
+
+def make_len_tags(tupl, key):
+ tags = []
+ tag = gr.gr_tag_t()
+ tag.key = pmt.string_to_symbol(key)
+ n_read = 0
+ for element in tupl:
+ tag.offset = n_read
+ n_read += len(element)
+ tag.value = pmt.to_pmt(len(element))
+ tags.append(tag)
+ return tags
+
+def make_len_tag(offset, key, value):
+ tag = gr.gr_tag_t()
+ tag.offset = offset
+ tag.key = pmt.string_to_symbol(key)
+ tag.value = pmt.to_pmt(value)
+ return tag
+
+
+class qa_tagged_stream_mux (gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_1(self):
+ datas = (
+ 0, 1, 2, 5, 6, 10, 14, 15, 16,
+ 3, 4, 7, 8, 9, 11, 12, 13, 17
+ )
+ expected = tuple(range(18))
+
+ tagname = "packet_length"
+ len_tags_0 = (
+ make_len_tag(0, tagname, 3),
+ make_len_tag(3, tagname, 2),
+ make_len_tag(5, tagname, 1),
+ make_len_tag(6, tagname, 3)
+ )
+ len_tags_1 = (
+ make_len_tag(0, tagname, 2),
+ make_len_tag(2, tagname, 3),
+ make_len_tag(5, tagname, 3),
+ make_len_tag(8, tagname, 1)
+ )
+ test_tag_0 = gr.gr_tag_t()
+ test_tag_0.key = pmt.string_to_symbol('spam')
+ test_tag_0.offset = 4 # On the second '1'
+ test_tag_0.value = pmt.to_pmt(42)
+ test_tag_1 = gr.gr_tag_t()
+ test_tag_1.key = pmt.string_to_symbol('eggs')
+ test_tag_1.offset = 3 # On the first '3' of the 2nd stream
+ test_tag_1.value = pmt.to_pmt(23)
+
+ src0 = gr.vector_source_b(datas[0:9], False, 1, len_tags_0 + (test_tag_0,))
+ src1 = gr.vector_source_b(datas[9:], False, 1, len_tags_1 + (test_tag_1,))
+ tagged_stream_mux = blocks.tagged_stream_mux(gr.sizeof_char, tagname)
+ snk = gr.vector_sink_b()
+ self.tb.connect(src0, (tagged_stream_mux, 0))
+ self.tb.connect(src1, (tagged_stream_mux, 1))
+ self.tb.connect(tagged_stream_mux, snk)
+ self.tb.run()
+
+ self.assertEqual(expected, snk.data())
+
+ tags = [gr.tag_to_python(x) for x in snk.tags()]
+ tags = sorted([(x.offset, x.key, x.value) for x in tags])
+ tags_expected = [
+ (0, 'packet_length', 5),
+ (5, 'packet_length', 5),
+ (6, 'spam', 42),
+ (8, 'eggs', 23),
+ (10, 'packet_length', 4),
+ (14, 'packet_length', 4)
+ ]
+ self.assertEqual(tags, tags_expected)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(qa_tagged_stream_mux, "qa_tagged_stream_mux.xml")
+
diff --git a/gr-blocks/swig/blocks_swig.i b/gr-blocks/swig/blocks_swig.i
index b12f26bad9..5245721b68 100644
--- a/gr-blocks/swig/blocks_swig.i
+++ b/gr-blocks/swig/blocks_swig.i
@@ -36,10 +36,12 @@
#include "blocks/add_ii.h"
#include "blocks/add_cc.h"
#include "blocks/add_const_ff.h"
+#include "blocks/add_const_bb.h"
#include "blocks/add_const_ss.h"
#include "blocks/add_const_ii.h"
#include "blocks/add_const_cc.h"
#include "blocks/add_const_vff.h"
+#include "blocks/add_const_vbb.h"
#include "blocks/add_const_vss.h"
#include "blocks/add_const_vii.h"
#include "blocks/add_const_vcc.h"
@@ -151,6 +153,7 @@
#include "blocks/or_ii.h"
#include "blocks/random_pdu.h"
#include "blocks/regenerate_bb.h"
+#include "blocks/repack_bits_bb.h"
#include "blocks/repeat.h"
#include "blocks/rms_cf.h"
#include "blocks/rms_ff.h"
@@ -173,6 +176,7 @@
#include "blocks/sub_cc.h"
#include "blocks/tag_debug.h"
#include "blocks/tagged_file_sink.h"
+#include "blocks/tagged_stream_mux.h"
#include "blocks/tagged_stream_to_pdu.h"
#include "blocks/threshold_ff.h"
#include "blocks/throttle.h"
@@ -200,10 +204,12 @@
%include "blocks/add_ii.h"
%include "blocks/add_cc.h"
%include "blocks/add_const_ff.h"
+%include "blocks/add_const_bb.h"
%include "blocks/add_const_ss.h"
%include "blocks/add_const_ii.h"
%include "blocks/add_const_cc.h"
%include "blocks/add_const_vff.h"
+%include "blocks/add_const_vbb.h"
%include "blocks/add_const_vss.h"
%include "blocks/add_const_vii.h"
%include "blocks/add_const_vcc.h"
@@ -316,6 +322,7 @@
%include "blocks/random_pdu.h"
%include "blocks/probe_rate.h"
%include "blocks/regenerate_bb.h"
+%include "blocks/repack_bits_bb.h"
%include "blocks/repeat.h"
%include "blocks/rms_cf.h"
%include "blocks/rms_ff.h"
@@ -337,6 +344,7 @@
%include "blocks/sub_ii.h"
%include "blocks/sub_cc.h"
%include "blocks/tagged_file_sink.h"
+%include "blocks/tagged_stream_mux.h"
%include "blocks/tagged_stream_to_pdu.h"
%include "blocks/threshold_ff.h"
%include "blocks/throttle.h"
@@ -363,10 +371,12 @@ GR_SWIG_BLOCK_MAGIC2(blocks, add_ss);
GR_SWIG_BLOCK_MAGIC2(blocks, add_ii);
GR_SWIG_BLOCK_MAGIC2(blocks, add_cc);
GR_SWIG_BLOCK_MAGIC2(blocks, add_const_ff);
+GR_SWIG_BLOCK_MAGIC2(blocks, add_const_bb);
GR_SWIG_BLOCK_MAGIC2(blocks, add_const_ss);
GR_SWIG_BLOCK_MAGIC2(blocks, add_const_ii);
GR_SWIG_BLOCK_MAGIC2(blocks, add_const_cc);
GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vff);
+GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vbb);
GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vss);
GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vii);
GR_SWIG_BLOCK_MAGIC2(blocks, add_const_vcc);
@@ -476,6 +486,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, probe_signal_vi);
GR_SWIG_BLOCK_MAGIC2(blocks, probe_signal_vf);
GR_SWIG_BLOCK_MAGIC2(blocks, probe_signal_vc);
GR_SWIG_BLOCK_MAGIC2(blocks, regenerate_bb);
+GR_SWIG_BLOCK_MAGIC2(blocks, repack_bits_bb);
GR_SWIG_BLOCK_MAGIC2(blocks, repeat);
GR_SWIG_BLOCK_MAGIC2(blocks, rms_cf);
GR_SWIG_BLOCK_MAGIC2(blocks, rms_ff);
@@ -498,6 +509,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, sub_ii);
GR_SWIG_BLOCK_MAGIC2(blocks, sub_cc);
GR_SWIG_BLOCK_MAGIC2(blocks, tag_debug);
GR_SWIG_BLOCK_MAGIC2(blocks, tagged_file_sink);
+GR_SWIG_BLOCK_MAGIC2(blocks, tagged_stream_mux);
GR_SWIG_BLOCK_MAGIC2(blocks, tagged_stream_to_pdu);
GR_SWIG_BLOCK_MAGIC2(blocks, threshold_ff);
GR_SWIG_BLOCK_MAGIC2(blocks, throttle);
diff --git a/gr-blocks/tests/CMakeLists.txt b/gr-blocks/tests/CMakeLists.txt
index 6a4f9d4c54..ec17c017f1 100644
--- a/gr-blocks/tests/CMakeLists.txt
+++ b/gr-blocks/tests/CMakeLists.txt
@@ -51,6 +51,6 @@ set(tests_not_run #single source per test
foreach(test_not_run_src ${tests_not_run})
get_filename_component(name ${test_not_run_src} NAME_WE)
add_executable(${name} ${test_not_run_src})
- target_link_libraries(${name} test-gnuradio-core gnuradio-blocks)
+ target_link_libraries(${name} test-gnuradio-core gnuradio-blocks ${LOG4CPP_LIBRARIES})
endforeach(test_not_run_src)