diff options
-rw-r--r-- | gr-digital/include/gnuradio/digital/additive_scrambler_bb.h | 8 | ||||
-rw-r--r-- | gr-digital/lib/additive_scrambler_bb_impl.cc | 61 | ||||
-rw-r--r-- | gr-digital/lib/additive_scrambler_bb_impl.h | 13 | ||||
-rwxr-xr-x | gr-digital/python/digital/qa_scrambler.py | 39 |
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") |