From c4763fb9f73df6832a015d84111cd2573a7b9bc6 Mon Sep 17 00:00:00 2001
From: jcorgan
Date: Fri, 12 Sep 2008 02:54:22 +0000
Subject: Merged -r9556:9560 from jcorgan/scr into trunk.  Adds gr.scrambler_bb
 and gr.descrambler_bb, using updated gri_lfsr.

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9561 221aa14e-8319-0410-a670-987f0aec2ac5
---
 gnuradio-core/src/lib/general/Makefile.am          | 12 +++-
 gnuradio-core/src/lib/general/general.i            |  4 ++
 gnuradio-core/src/lib/general/gr_descrambler_bb.cc | 56 +++++++++++++++
 gnuradio-core/src/lib/general/gr_descrambler_bb.h  | 57 +++++++++++++++
 gnuradio-core/src/lib/general/gr_descrambler_bb.i  | 31 ++++++++
 gnuradio-core/src/lib/general/gr_scrambler_bb.cc   | 56 +++++++++++++++
 gnuradio-core/src/lib/general/gr_scrambler_bb.h    | 57 +++++++++++++++
 gnuradio-core/src/lib/general/gr_scrambler_bb.i    | 31 ++++++++
 gnuradio-core/src/lib/general/gri_lfsr.h           | 43 +++++++++--
 gnuradio-core/src/lib/general/qa_gri_lfsr.cc       | 84 ++++++++++++++++++++++
 gnuradio-core/src/lib/general/qa_gri_lfsr.h        |  4 ++
 11 files changed, 425 insertions(+), 10 deletions(-)
 create mode 100644 gnuradio-core/src/lib/general/gr_descrambler_bb.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_descrambler_bb.h
 create mode 100644 gnuradio-core/src/lib/general/gr_descrambler_bb.i
 create mode 100644 gnuradio-core/src/lib/general/gr_scrambler_bb.cc
 create mode 100644 gnuradio-core/src/lib/general/gr_scrambler_bb.h
 create mode 100644 gnuradio-core/src/lib/general/gr_scrambler_bb.i

(limited to 'gnuradio-core/src/lib')

diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am
index 8ee900183..024363253 100644
--- a/gnuradio-core/src/lib/general/Makefile.am
+++ b/gnuradio-core/src/lib/general/Makefile.am
@@ -163,7 +163,9 @@ libgeneral_la_SOURCES = 		\
 	gri_short_to_float.cc		\
 	gri_uchar_to_float.cc		\
 	malloc16.c			\
-	gr_unpack_k_bits_bb.cc
+	gr_unpack_k_bits_bb.cc		\
+	gr_descrambler_bb.cc		\
+	gr_scrambler_bb.cc
 
 libgeneral_qa_la_SOURCES = 		\
 	qa_general.cc			\
@@ -320,7 +322,9 @@ grinclude_HEADERS = 			\
 	gri_uchar_to_float.h		\
 	malloc16.h			\
 	random.h			\
-	gr_unpack_k_bits_bb.h
+	gr_unpack_k_bits_bb.h		\
+	gr_descrambler_bb.h		\
+	gr_scrambler_bb.h
 
 
 noinst_HEADERS = 			\
@@ -448,7 +452,9 @@ swiginclude_HEADERS =			\
 	gri_agc_cc.i			\
 	gri_agc_ff.i			\
 	gri_agc2_cc.i			\
-	gri_agc2_ff.i			
+	gri_agc2_ff.i			\
+	gr_descrambler_bb.i		\
+	gr_scrambler_bb.i
 
 
 CLEANFILES = $(BUILT_SOURCES) *.pyc
diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i
index 435271f79..8326b27b0 100644
--- a/gnuradio-core/src/lib/general/general.i
+++ b/gnuradio-core/src/lib/general/general.i
@@ -129,6 +129,8 @@
 #include <gr_cpfsk_bc.h>
 #include <gr_encode_ccsds_27_bb.h>
 #include <gr_decode_ccsds_27_fb.h>
+#include <gr_descrambler_bb.h>
+#include <gr_scrambler_bb.h>
 %}
 
 %include "gr_nop.i"
@@ -238,3 +240,5 @@
 %include "gr_cpfsk_bc.i"
 %include "gr_encode_ccsds_27_bb.i"
 %include "gr_decode_ccsds_27_fb.i"
+%include "gr_descrambler_bb.i"
+%include "gr_scrambler_bb.i"
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.cc b/gnuradio-core/src/lib/general/gr_descrambler_bb.cc
new file mode 100644
index 000000000..e173a8a22
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_descrambler_bb.cc
@@ -0,0 +1,56 @@
+/* -*- 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_descrambler_bb.h>
+#include <gr_io_signature.h>
+
+gr_descrambler_bb_sptr
+gr_make_descrambler_bb(int mask, int seed, int len)
+{
+  return gr_descrambler_bb_sptr(new gr_descrambler_bb(mask, seed, len));
+}
+
+gr_descrambler_bb::gr_descrambler_bb(int mask, int seed, int len)
+  : gr_sync_block("descrambler_bb",
+		  gr_make_io_signature (1, 1, sizeof (unsigned char)),
+		  gr_make_io_signature (1, 1, sizeof (unsigned char))),
+    d_lfsr(mask, seed, len)
+{
+}
+
+int
+gr_descrambler_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] = d_lfsr.next_bit_descramble(in[i]);
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.h b/gnuradio-core/src/lib/general/gr_descrambler_bb.h
new file mode 100644
index 000000000..4fd8f4a0f
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_descrambler_bb.h
@@ -0,0 +1,57 @@
+/* -*- 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.
+ */
+#ifndef INCLUDED_GR_DESCRAMBLER_BB_H
+#define INCLUDED_GR_DESCRAMBLER_BB_H
+
+#include <gr_sync_block.h>
+#include "gri_lfsr.h"
+
+class gr_descrambler_bb;
+typedef boost::shared_ptr<gr_descrambler_bb> gr_descrambler_bb_sptr;
+
+gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
+
+/*!
+ * \brief Descramble an input stream using an LFSR
+ * 
+ * \param mask     Polynomial mask for LFSR
+ * \param seed     Initial shift register contents
+ * \param len      Shift register length
+ *
+ * \ingroup misc
+ */
+
+class gr_descrambler_bb : public gr_sync_block
+{
+  friend gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
+
+  gri_lfsr d_lfsr;
+
+  gr_descrambler_bb(int mask, int seed, int len);
+
+public:
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_DESCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_descrambler_bb.i b/gnuradio-core/src/lib/general/gr_descrambler_bb.i
new file mode 100644
index 000000000..e93c50c1a
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_descrambler_bb.i
@@ -0,0 +1,31 @@
+/* -*- 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,descrambler_bb);
+
+gr_descrambler_bb_sptr gr_make_descrambler_bb(int mask, int seed, int len);
+
+class gr_descrambler_bb : public gr_sync_block
+{
+private:
+  gr_descrambler_bb(int mask, int seed, int len);
+};
diff --git a/gnuradio-core/src/lib/general/gr_scrambler_bb.cc b/gnuradio-core/src/lib/general/gr_scrambler_bb.cc
new file mode 100644
index 000000000..42f70901b
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_scrambler_bb.cc
@@ -0,0 +1,56 @@
+/* -*- 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_scrambler_bb.h>
+#include <gr_io_signature.h>
+
+gr_scrambler_bb_sptr
+gr_make_scrambler_bb(int mask, int seed, int len)
+{
+  return gr_scrambler_bb_sptr(new gr_scrambler_bb(mask, seed, len));
+}
+
+gr_scrambler_bb::gr_scrambler_bb(int mask, int seed, int len)
+  : gr_sync_block("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)
+{
+}
+
+int
+gr_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] = d_lfsr.next_bit_scramble(in[i]);
+  
+  return noutput_items;
+}
diff --git a/gnuradio-core/src/lib/general/gr_scrambler_bb.h b/gnuradio-core/src/lib/general/gr_scrambler_bb.h
new file mode 100644
index 000000000..a01b08dd6
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_scrambler_bb.h
@@ -0,0 +1,57 @@
+/* -*- 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.
+ */
+#ifndef INCLUDED_GR_SCRAMBLER_BB_H
+#define INCLUDED_GR_SCRAMBLER_BB_H
+
+#include <gr_sync_block.h>
+#include "gri_lfsr.h"
+
+class gr_scrambler_bb;
+typedef boost::shared_ptr<gr_scrambler_bb> gr_scrambler_bb_sptr;
+
+gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
+
+/*!
+ * \brief Scramble an input stream using an LFSR
+ * 
+ * \param mask     Polynomial mask for LFSR
+ * \param seed     Initial shift register contents
+ * \param len      Shift register length
+ *
+ * \ingroup misc
+ */
+
+class gr_scrambler_bb : public gr_sync_block
+{
+  friend gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
+
+  gri_lfsr d_lfsr;
+
+  gr_scrambler_bb(int mask, int seed, int len);
+
+public:
+  int work(int noutput_items,
+	   gr_vector_const_void_star &input_items,
+	   gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_SCRAMBLER_BB_H */
diff --git a/gnuradio-core/src/lib/general/gr_scrambler_bb.i b/gnuradio-core/src/lib/general/gr_scrambler_bb.i
new file mode 100644
index 000000000..9a607c4b1
--- /dev/null
+++ b/gnuradio-core/src/lib/general/gr_scrambler_bb.i
@@ -0,0 +1,31 @@
+/* -*- 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,scrambler_bb);
+
+gr_scrambler_bb_sptr gr_make_scrambler_bb(int mask, int seed, int len);
+
+class gr_scrambler_bb : public gr_sync_block
+{
+private:
+  gr_scrambler_bb(int mask, int seed, int len);
+};
diff --git a/gnuradio-core/src/lib/general/gri_lfsr.h b/gnuradio-core/src/lib/general/gri_lfsr.h
index 29873698c..b6eee7679 100644
--- a/gnuradio-core/src/lib/general/gri_lfsr.h
+++ b/gnuradio-core/src/lib/general/gri_lfsr.h
@@ -58,15 +58,29 @@
  *
  *
  *
- *  next_bit() - performs once cycle of the lfsr,
- *               generating the new high order bit from the mask
- *               and returning the low order bit which has been
- *               shifted out of the register.
+ *  next_bit() - Standard LFSR operation
+ * 
+ *      Perform one cycle of the LFSR.  The output bit is taken from
+ *      the shift register LSB.  The shift register MSB is assigned from
+ *      the modulo 2 sum of the masked shift register.
+ *             
+ *  next_bit_scramble(unsigned char input) - Scramble an input stream
+ * 
+ *      Perform one cycle of the LFSR.  The output bit is taken from
+ *      the shift register LSB.  The shift register MSB is assigned from
+ *      the modulo 2 sum of the masked shift register and the input LSB.
+ *
+ *  next_bit_descramble(unsigned char input) - Descramble an input stream
  *
+ *      Perform one cycle of the LFSR.  The output bit is taken from 
+ *      the modulo-2 sum of the masked shift register and the input LSB.
+ *      The shift register MSB is assigned from the LSB of the input.
+ *
+ * See http://en.wikipedia.org/wiki/Scrambler for operation of these
+ * last two functions (see multiplicative scrambler.)
  *
  */
 
-
 class gri_lfsr
 {
  private:
@@ -92,12 +106,27 @@ class gri_lfsr
   }
 
   unsigned char next_bit() {
-    unsigned char bit = d_shift_register & 1;
+    unsigned char output = d_shift_register & 1;
     unsigned char newbit = popCount( d_shift_register & d_mask )%2;
     d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length));
-    return bit;
+    return output;
+  }
+
+  unsigned char next_bit_scramble(unsigned char input) {
+    unsigned char output = d_shift_register & 1;
+    unsigned char newbit = (popCount( d_shift_register & d_mask )%2)^(input & 1);
+    d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length));
+    return output;
+  }
+
+  unsigned char next_bit_descramble(unsigned char input) {
+    unsigned char output = (popCount( d_shift_register & d_mask )%2)^(input & 1);
+    unsigned char newbit = input & 1;
+    d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length));
+    return output;
   }
 
+
   /*!
    * Rotate the register through x number of bits
    * where we are just throwing away the results to get queued up correctly
diff --git a/gnuradio-core/src/lib/general/qa_gri_lfsr.cc b/gnuradio-core/src/lib/general/qa_gri_lfsr.cc
index 9a72bf8d9..2d4346ace 100644
--- a/gnuradio-core/src/lib/general/qa_gri_lfsr.cc
+++ b/gnuradio-core/src/lib/general/qa_gri_lfsr.cc
@@ -54,3 +54,87 @@ qa_gri_lfsr::test_lfsr ()
   CPPUNIT_ASSERT_THROW(gri_lfsr(mask, seed, 32), std::invalid_argument);
 }
 
+void
+qa_gri_lfsr::test_scrambler()
+{
+  // CCSDS 7-bit scrambler
+  int mask = 0x8A; // 1+x^4+X^6 
+  int seed = 0x7F;
+  int length = 7;
+
+  gri_lfsr scrambler(mask, seed, length);
+
+  // Impulse (1 and 126 more zeroes)
+  unsigned char src[] = 
+    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0 }; // flush bits
+  
+  // Impulse response (including leading bits)
+  unsigned char expected[] =
+    { 1, 1, 1, 1, 1, 1, 1, 
+      0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 
+      0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 
+      0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 
+      0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 
+      1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 
+      0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 
+      1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 
+      1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, };
+
+  int len = sizeof(src);
+  unsigned char actual[len];
+
+  for (int i = 0; i < len; i++)
+    actual[i] = scrambler.next_bit_scramble(src[i]);
+
+  CPPUNIT_ASSERT(memcmp(expected, actual, len) == 0);
+}
+
+void
+qa_gri_lfsr::test_descrambler()
+{
+  // CCSDS 7-bit scrambler
+  int mask = 0x8A;
+  int seed = 0x7F;
+  int length = 7;
+
+  gri_lfsr descrambler(mask, seed, length);
+
+  // Scrambled sequence (impulse response)
+  unsigned char src[] =
+    { 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 
+      0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 
+      0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 
+      0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 
+      1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 
+      0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 
+      1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 
+      1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0 }; 
+
+  // Original (garbage while synchronizing, them impulse)
+  unsigned char expected[] = 
+    { 0, 1, 0, 0, 1, 0,
+      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  
+  int len = sizeof(src);
+  unsigned char actual[len];
+
+  for (int i = 0; i < len; i++)
+    actual[i] = descrambler.next_bit_descramble(src[i]);
+
+  CPPUNIT_ASSERT(memcmp(expected, actual, len) == 0);
+}
diff --git a/gnuradio-core/src/lib/general/qa_gri_lfsr.h b/gnuradio-core/src/lib/general/qa_gri_lfsr.h
index f65943a90..2a1b92e9c 100644
--- a/gnuradio-core/src/lib/general/qa_gri_lfsr.h
+++ b/gnuradio-core/src/lib/general/qa_gri_lfsr.h
@@ -29,10 +29,14 @@ class qa_gri_lfsr : public CppUnit::TestCase {
 
   CPPUNIT_TEST_SUITE(qa_gri_lfsr);
   CPPUNIT_TEST(test_lfsr);
+  CPPUNIT_TEST(test_scrambler);
+  CPPUNIT_TEST(test_descrambler);
   CPPUNIT_TEST_SUITE_END();
 
  private:
   void test_lfsr();
+  void test_scrambler();
+  void test_descrambler();
 };
 
 #endif /* _QA_GRI_LFSR_H_ */
-- 
cgit