From 1ae689ff9238dcffbf65881b8ca03aa8df3844aa Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Sun, 21 Mar 2010 16:17:15 -0700 Subject: [PATCH] Add new block gr.additive_scrambler_bb() This block performs scrambling by XORing the input sequence with the output of an LFSR. Repeating this operation restores the original sequence. (This differs from gr.scrambler_bb(), which convolves the input sequence with the LFSR output.) The additive scrambler allows an optional bit count after which the LFSR is reset to its initial seed. This allows use with, e.g., packetized fixed length payloads. --- gnuradio-core/src/lib/general/Makefile.am | 3 + gnuradio-core/src/lib/general/general.i | 2 + .../lib/general/gr_additive_scrambler_bb.cc | 65 ++++++++++++++++++ .../lib/general/gr_additive_scrambler_bb.h | 67 +++++++++++++++++++ .../lib/general/gr_additive_scrambler_bb.i | 31 +++++++++ gnuradio-core/src/lib/general/gri_lfsr.h | 12 +++- .../src/python/gnuradio/gr/qa_scrambler.py | 20 ++++++ grc/blocks/Makefile.am | 1 + grc/blocks/block_tree.xml | 1 + grc/blocks/gr_additive_scrambler_bb.xml | 44 ++++++++++++ 10 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc create mode 100644 gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h create mode 100644 gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i create mode 100644 grc/blocks/gr_additive_scrambler_bb.xml diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index ecef7d6e..b5f5c346 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -34,6 +34,7 @@ EXTRA_DIST = \ gr_constants.cc.in libgeneral_la_SOURCES = \ + gr_additive_scrambler_bb.cc \ gr_agc_cc.cc \ gr_agc_ff.cc \ gr_agc2_cc.cc \ @@ -188,6 +189,7 @@ libgeneral_qa_la_SOURCES = \ qa_gri_lfsr.cc grinclude_HEADERS = \ + gr_additive_scrambler_bb.h \ gr_agc_cc.h \ gr_agc_ff.h \ gr_agc2_cc.h \ @@ -360,6 +362,7 @@ noinst_HEADERS = \ if PYTHON swiginclude_HEADERS = \ general.i \ + gr_additive_scrambler_bb.i \ gr_agc_cc.i \ gr_agc_ff.i \ gr_agc2_cc.i \ diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index 2c26b59c..6929f1e6 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -141,6 +141,7 @@ #include #include #include +#include %} %include "gr_nop.i" @@ -262,3 +263,4 @@ %include "gr_wvps_ff.i" %include "gr_copy.i" %include "gr_fll_band_edge_cc.i" +%include "gr_additive_scrambler_bb.i" diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc new file mode 100644 index 00000000..91e02c2d --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.cc @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 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 +#include + +gr_additive_scrambler_bb_sptr +gr_make_additive_scrambler_bb(int mask, int seed, int len, int count) +{ + return gr_additive_scrambler_bb_sptr(new gr_additive_scrambler_bb(mask, seed, len, count)); +} + +gr_additive_scrambler_bb::gr_additive_scrambler_bb(int mask, int seed, int len, int count) + : gr_sync_block("additive_scrambler_bb", + gr_make_io_signature (1, 1, sizeof (unsigned char)), + gr_make_io_signature (1, 1, sizeof (unsigned char))), + d_lfsr(mask, seed, len), + d_count(count), + d_bits(0) +{ +} + +int +gr_additive_scrambler_bb::work(int noutput_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]; + + 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; + } + } + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h new file mode 100644 index 00000000..6c949305 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 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. + */ +#ifndef INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H +#define INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H + +#include +#include "gri_lfsr.h" + +class gr_additive_scrambler_bb; +typedef boost::shared_ptr gr_additive_scrambler_bb_sptr; + +gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count=0); + +/*! + * Scramble an input stream using an LFSR. This block works on the LSB only + * of the input data stream, i.e., on an "unpacked binary" stream, and + * produces the same format on its output. + * + * \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 + * + * The scrambler works by XORing the incoming bit stream by the output of + * the LFSR. Optionally, after 'count' bits have been processed, the shift + * register is reset to the seed value. This allows processing fixed length + * vectors of samples. + * + * \ingroup coding_blk + */ + +class gr_additive_scrambler_bb : public gr_sync_block +{ + friend gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count); + + gri_lfsr d_lfsr; + int d_count; + int d_bits; + + gr_additive_scrambler_bb(int mask, int seed, int len, int count); + +public: + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H */ diff --git a/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i new file mode 100644 index 00000000..0ca9c1cd --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_additive_scrambler_bb.i @@ -0,0 +1,31 @@ +/* -*- c++ -*- */ +/* + * Copyright 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,additive_scrambler_bb); + +gr_additive_scrambler_bb_sptr gr_make_additive_scrambler_bb(int mask, int seed, int len, int count=0); + +class gr_additive_scrambler_bb : public gr_sync_block +{ +private: + gr_additive_scrambler_bb(int mask, int seed, int len, int count); +}; diff --git a/gnuradio-core/src/lib/general/gri_lfsr.h b/gnuradio-core/src/lib/general/gri_lfsr.h index 715da78a..f691e36e 100644 --- a/gnuradio-core/src/lib/general/gri_lfsr.h +++ b/gnuradio-core/src/lib/general/gri_lfsr.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008 Free Software Foundation, Inc. + * Copyright 2008,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -86,6 +86,7 @@ class gri_lfsr private: uint32_t d_shift_register; uint32_t d_mask; + uint32_t d_seed; uint32_t d_shift_register_length; // less than 32 static uint32_t @@ -99,7 +100,10 @@ class gri_lfsr public: gri_lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len) - : d_shift_register(seed), d_mask(mask), d_shift_register_length(reg_len) + : d_shift_register(seed), + d_mask(mask), + d_seed(seed), + d_shift_register_length(reg_len) { if (reg_len > 31) throw std::invalid_argument("reg_len must be <= 31"); @@ -126,6 +130,10 @@ class gri_lfsr return output; } + /*! + * Reset shift register to initial seed value + */ + void reset() { d_shift_register = d_seed; } /*! * Rotate the register through x number of bits diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py b/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py index 76b0e62f..aecf4929 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_scrambler.py @@ -40,5 +40,25 @@ class test_scrambler(gr_unittest.TestCase): self.tb.run() self.assertEqual(tuple(src_data[:-8]), dst.data()[8:]) # skip garbage during synchronization + def test_additive_scrambler(self): + src_data = (1,)*1000 + src = gr.vector_source_b(src_data, False) + scrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7) + descrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7) + dst = gr.vector_sink_b() + self.tb.connect(src, scrambler, descrambler, dst) + self.tb.run() + self.assertEqual(src_data, dst.data()) + + def test_additive_scrambler_reset(self): + src_data = (1,)*1000 + src = gr.vector_source_b(src_data, False) + scrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7, 100) + descrambler = gr.additive_scrambler_bb(0x8a, 0x7f, 7, 100) + dst = gr.vector_sink_b() + self.tb.connect(src, scrambler, descrambler, dst) + self.tb.run() + self.assertEqual(src_data, dst.data()) + if __name__ == '__main__': gr_unittest.main () diff --git a/grc/blocks/Makefile.am b/grc/blocks/Makefile.am index a284d6d8..4e3839d2 100644 --- a/grc/blocks/Makefile.am +++ b/grc/blocks/Makefile.am @@ -67,6 +67,7 @@ dist_ourdata_DATA = \ const_source_x.xml \ gr_add_const_vxx.xml \ gr_add_xx.xml \ + gr_additive_scrambler_bb.xml \ gr_agc2_xx.xml \ gr_agc_xx.xml \ gr_and_xx.xml \ diff --git a/grc/blocks/block_tree.xml b/grc/blocks/block_tree.xml index ba597756..04568e19 100644 --- a/grc/blocks/block_tree.xml +++ b/grc/blocks/block_tree.xml @@ -259,6 +259,7 @@ Line Coding gr_scrambler_bb gr_descrambler_bb + gr_additive_scrambler_bb Vocoders diff --git a/grc/blocks/gr_additive_scrambler_bb.xml b/grc/blocks/gr_additive_scrambler_bb.xml new file mode 100644 index 00000000..a15d6eef --- /dev/null +++ b/grc/blocks/gr_additive_scrambler_bb.xml @@ -0,0 +1,44 @@ + + + + Additive Scrambler + gr_additive_scrambler_bb + from gnuradio import gr + gr.additive_scrambler_bb($mask, $seed, $len, $count) + + Mask + mask + 0x8A + hex + + + Seed + seed + 0x7F + hex + + + Length + len + 7 + int + + + Count + count + 0 + int + + + in + byte + + + out + byte + + -- 2.39.5