summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-digital/include/gnuradio/digital/additive_scrambler_bb.h8
-rw-r--r--gr-digital/lib/additive_scrambler_bb_impl.cc61
-rw-r--r--gr-digital/lib/additive_scrambler_bb_impl.h13
-rwxr-xr-xgr-digital/python/digital/qa_scrambler.py39
4 files changed, 104 insertions, 17 deletions
diff --git a/gr-digital/include/gnuradio/digital/additive_scrambler_bb.h b/gr-digital/include/gnuradio/digital/additive_scrambler_bb.h
index 73fd395d67..e88ac5a48c 100644
--- a/gr-digital/include/gnuradio/digital/additive_scrambler_bb.h
+++ b/gr-digital/include/gnuradio/digital/additive_scrambler_bb.h
@@ -57,15 +57,17 @@ namespace gr {
* \param mask Polynomial mask for LFSR
* \param seed Initial shift register contents
* \param len Shift register length
- * \param count Number of bits after which shift register is reset, 0=never
- *
+ * \param count Number of bytes after which shift register is reset, 0=never
+ * \param bits_per_byte Number of bits per byte
+ * \param reset_tag When a tag with this key is detected, the shift register is reset (when this is set, count is ignored!)
*/
- static sptr make(int mask, int seed, int len, int count=0);
+ static sptr make(int mask, int seed, int len, int count=0, int bits_per_byte=1, const std::string &reset_tag_key="");
virtual int mask() const = 0;
virtual int seed() const = 0;
virtual int len() const = 0;
virtual int count() const = 0;
+ virtual int bits_per_byte() = 0;
};
} /* namespace digital */
diff --git a/gr-digital/lib/additive_scrambler_bb_impl.cc b/gr-digital/lib/additive_scrambler_bb_impl.cc
index 8f2229e6b6..96e1fbbc25 100644
--- a/gr-digital/lib/additive_scrambler_bb_impl.cc
+++ b/gr-digital/lib/additive_scrambler_bb_impl.cc
@@ -31,23 +31,35 @@ namespace gr {
namespace digital {
additive_scrambler_bb::sptr
- additive_scrambler_bb::make(int mask, int seed, int len, int count)
+ additive_scrambler_bb::make (int mask, int seed,
+ int len, int count,
+ int bits_per_byte,
+ const std::string &reset_tag_key)
{
return gnuradio::get_initial_sptr(new additive_scrambler_bb_impl
- (mask, seed, len, count));
+ (mask, seed, len, count, bits_per_byte, reset_tag_key));
}
additive_scrambler_bb_impl::additive_scrambler_bb_impl(int mask,
int seed,
int len,
- int count)
+ int count,
+ int bits_per_byte,
+ const std::string &reset_tag_key)
: sync_block("additive_scrambler_bb",
io_signature::make(1, 1, sizeof(unsigned char)),
io_signature::make(1, 1, sizeof(unsigned char))),
d_lfsr(mask, seed, len),
- d_count(count),
- d_bits(0), d_len(len), d_seed(seed)
+ d_count(reset_tag_key.empty() ? count : -1),
+ d_bytes(0), d_len(len), d_seed(seed),
+ d_bits_per_byte(bits_per_byte), d_reset_tag_key(pmt::string_to_symbol(reset_tag_key))
{
+ if (d_count < -1) {
+ throw std::invalid_argument("count must be non-negative!");
+ }
+ if (d_bits_per_byte < 1 || d_bits_per_byte > 8) {
+ throw std::invalid_argument("bits_per_byte must be in [1, 8]");
+ }
}
additive_scrambler_bb_impl::~additive_scrambler_bb_impl()
@@ -78,6 +90,28 @@ namespace gr {
return d_count;
}
+ int additive_scrambler_bb_impl::_get_next_reset_index(int noutput_items, int last_reset_index /* = -1 */)
+ {
+ int reset_index = noutput_items; // This is a value that gets never reached in the for loop
+ if (d_count == -1) {
+ std::vector<gr::tag_t> tags;
+ get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+noutput_items, d_reset_tag_key);
+ for (unsigned i = 0; i < tags.size(); i++) {
+ int reset_pos = tags[i].offset - nitems_read(0);
+ if (reset_pos < reset_index && reset_pos > last_reset_index) {
+ reset_index = reset_pos;
+ };
+ }
+ } else {
+ if (last_reset_index == -1) {
+ reset_index = d_count - d_bytes;
+ } else {
+ reset_index = last_reset_index + d_count;
+ }
+ }
+ return reset_index;
+ }
+
int
additive_scrambler_bb_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
@@ -85,14 +119,19 @@ namespace gr {
{
const unsigned char *in = (const unsigned char *)input_items[0];
unsigned char *out = (unsigned char *)output_items[0];
+ int reset_index = _get_next_reset_index(noutput_items);
for(int i = 0; i < noutput_items; i++) {
- out[i] = in[i]^d_lfsr.next_bit();
- if(d_count > 0) {
- if(++d_bits == d_count) {
- d_lfsr.reset();
- d_bits = 0;
- }
+ unsigned char scramble_byte = 0x00;
+ for (int k = 0; k < d_bits_per_byte; k++) {
+ scramble_byte ^= (d_lfsr.next_bit() << k);
+ }
+ out[i] = in[i] ^ scramble_byte;
+ d_bytes++;
+ if (i == reset_index) {
+ d_lfsr.reset();
+ d_bytes = 0;
+ reset_index = _get_next_reset_index(noutput_items, reset_index);
}
}
diff --git a/gr-digital/lib/additive_scrambler_bb_impl.h b/gr-digital/lib/additive_scrambler_bb_impl.h
index b621637e67..5f28203709 100644
--- a/gr-digital/lib/additive_scrambler_bb_impl.h
+++ b/gr-digital/lib/additive_scrambler_bb_impl.h
@@ -34,20 +34,27 @@ namespace gr {
{
private:
digital::lfsr d_lfsr;
- int d_count;
- int d_bits;
+ int d_count; //! Reset the LFSR after this many bytes (not bits)
+ int d_bytes; //! Count the processed bytes
int d_len;
int d_seed;
+ int d_bits_per_byte;
+ pmt::pmt_t d_reset_tag_key;
+
+ int _get_next_reset_index(int noutput_items, int last_reset_index=-1);
public:
additive_scrambler_bb_impl(int mask, int seed,
- int len, int count=0);
+ int len, int count=0,
+ int bits_per_byte=1, const std::string &reset_tag_key="");
~additive_scrambler_bb_impl();
int mask() const;
int seed() const;
int len() const;
int count() const;
+ int bits_per_byte() { return d_bits_per_byte; };
+
int work(int noutput_items,
gr_vector_const_void_star &input_items,
diff --git a/gr-digital/python/digital/qa_scrambler.py b/gr-digital/python/digital/qa_scrambler.py
index 05daebd389..e19e963cd3 100755
--- a/gr-digital/python/digital/qa_scrambler.py
+++ b/gr-digital/python/digital/qa_scrambler.py
@@ -21,6 +21,7 @@
#
from gnuradio import gr, gr_unittest, digital, blocks
+import pmt
class test_scrambler(gr_unittest.TestCase):
@@ -60,5 +61,43 @@ class test_scrambler(gr_unittest.TestCase):
self.tb.run()
self.assertEqual(src_data, dst.data())
+ def test_additive_scrambler_reset_3bpb(self):
+ src_data = (5,)*2000
+ src = blocks.vector_source_b(src_data, False)
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100, 3)
+ descrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100, 3)
+ dst = blocks.vector_sink_b()
+ dst2 = blocks.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.connect(scrambler, dst2)
+ self.tb.run()
+ if not (src_data == dst.data()):
+ self.fail('Not equal.')
+ self.assertEqual(src_data, src_data)
+
+ def test_additive_scrambler_tags(self):
+ print 'tags'
+ src_data = (1,)*1000
+ src = blocks.vector_source_b(src_data, False)
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+ descrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+ reset_tag_key = 'reset_lfsr'
+ reset_tag1 = gr.tag_t()
+ reset_tag1.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag1.offset = 17
+ reset_tag2 = gr.tag_t()
+ reset_tag2.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag2.offset = 110
+ reset_tag3 = gr.tag_t()
+ reset_tag3.key = pmt.string_to_symbol(reset_tag_key)
+ reset_tag3.offset = 523
+ src = blocks.vector_source_b(src_data, False, 1, (reset_tag1, reset_tag2, reset_tag3))
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100, 1, reset_tag_key)
+ descrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100, 1, reset_tag_key)
+ dst = blocks.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.run()
+ self.assertEqual(src_data, dst.data())
+
if __name__ == '__main__':
gr_unittest.run(test_scrambler, "test_scrambler.xml")