summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrej Rode <mail@andrejro.de>2017-10-31 18:57:22 +0100
committerMarcus Müller <marcus@hostalia.de>2018-07-12 20:35:33 +0200
commit84193bf1b00def9789e4aff16edaa030de17a0d7 (patch)
tree2595fa0f1ea193cea761259c3cf77516796a4b60
parentb9cbf90def0ce9e96a3ab75362ff9e9c5873b7b2 (diff)
digital: handle unpacked bytes correctly in CRC32_bb
-rw-r--r--gr-digital/lib/crc32_bb_impl.cc29
-rw-r--r--gr-digital/lib/crc32_bb_impl.h1
-rw-r--r--gr-digital/python/digital/qa_crc32_bb.py49
3 files changed, 66 insertions, 13 deletions
diff --git a/gr-digital/lib/crc32_bb_impl.cc b/gr-digital/lib/crc32_bb_impl.cc
index afb5e32716..fc88e7f215 100644
--- a/gr-digital/lib/crc32_bb_impl.cc
+++ b/gr-digital/lib/crc32_bb_impl.cc
@@ -65,6 +65,26 @@ namespace gr {
}
}
+ unsigned int
+ crc32_bb_impl::calculate_crc32(const unsigned char* in, size_t packet_length){
+ unsigned int crc = 0;
+ d_crc_impl.reset();
+ if (!d_packed){
+ const size_t n_packed_length = 1 + ((packet_length - 1) / 8);
+ unsigned char packed_buffer[n_packed_length];
+ memset(packed_buffer, 0, n_packed_length);
+ for (size_t bit = 0; bit < packet_length; bit++){
+ packed_buffer[bit/8] |= (in[bit] << (bit % 8));
+ }
+ d_crc_impl.process_bytes(packed_buffer, n_packed_length);
+ crc = d_crc_impl();
+ } else{
+ d_crc_impl.process_bytes(in, packet_length);
+ crc = d_crc_impl();
+ }
+ return crc;
+ }
+
int
crc32_bb_impl::work(int noutput_items,
gr_vector_int &ninput_items,
@@ -72,14 +92,13 @@ namespace gr {
gr_vector_void_star &output_items) {
const unsigned char *in = (const unsigned char *) input_items[0];
unsigned char *out = (unsigned char *) output_items[0];
- long packet_length = ninput_items[0];
+ size_t packet_length = ninput_items[0];
int packet_size_diff = d_check ? -d_crc_length : d_crc_length;
unsigned int crc;
if (d_check) {
- d_crc_impl.reset();
d_crc_impl.process_bytes(in, packet_length - d_crc_length);
- crc = d_crc_impl();
+ crc = calculate_crc32(in, packet_length - d_crc_length);
if (d_packed) {
if (crc != *(unsigned int *) (in + packet_length - d_crc_length)) { // Drop package
d_nfail++;
@@ -97,9 +116,7 @@ namespace gr {
d_npass++;
memcpy((void *) out, (const void *) in, packet_length - d_crc_length);
} else {
- d_crc_impl.reset();
- d_crc_impl.process_bytes(in, packet_length);
- crc = d_crc_impl();
+ crc = calculate_crc32(in, packet_length);
memcpy((void *) out, (const void *) in, packet_length);
if (d_packed) {
memcpy((void *) (out + packet_length), &crc, d_crc_length); // FIXME big-endian/little-endian, this might be wrong
diff --git a/gr-digital/lib/crc32_bb_impl.h b/gr-digital/lib/crc32_bb_impl.h
index 642da07e50..185958d5cf 100644
--- a/gr-digital/lib/crc32_bb_impl.h
+++ b/gr-digital/lib/crc32_bb_impl.h
@@ -37,6 +37,7 @@ namespace gr {
boost::crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> d_crc_impl;
int d_crc_length;
char *d_unpacked_crc;
+ unsigned int calculate_crc32(const unsigned char* in, size_t packet_length);
public:
crc32_bb_impl(bool check, const std::string& lengthtagname, bool packed);
diff --git a/gr-digital/python/digital/qa_crc32_bb.py b/gr-digital/python/digital/qa_crc32_bb.py
index 53ea6f3deb..7ffccb6355 100644
--- a/gr-digital/python/digital/qa_crc32_bb.py
+++ b/gr-digital/python/digital/qa_crc32_bb.py
@@ -194,6 +194,35 @@ class qa_crc32_bb (gr_unittest.TestCase):
# Check that the packets after crc_check are the same as input.
self.assertEqual(data, sink.data()[0])
+ def test_002_crc_equal_unpacked (self):
+ """ Test unpacked operation with packed operation
+ """
+ data = (0, 1, 2, 3, 4, 5, 6, 7, 8)
+ src = blocks.vector_source_b(data)
+ unpack1 = blocks.repack_bits_bb(8, 1, self.tsb_key, False, gr.GR_LSB_FIRST)
+ unpack2 = blocks.repack_bits_bb(8, 1, self.tsb_key, False, gr.GR_LSB_FIRST)
+ crc_unpacked = digital.crc32_bb(False, self.tsb_key, False)
+ crc_packed = digital.crc32_bb(False, self.tsb_key, True)
+ sink1 = blocks.tsb_vector_sink_b(tsb_key=self.tsb_key)
+ sink2 = blocks.tsb_vector_sink_b(tsb_key=self.tsb_key)
+
+ self.tb.connect(
+ src,
+ blocks.stream_to_tagged_stream(gr.sizeof_char, 1, len(data), self.tsb_key),
+ crc_packed,
+ unpack1,
+ sink1
+ )
+ self.tb.connect(
+ src,
+ blocks.stream_to_tagged_stream(gr.sizeof_char, 1, len(data), self.tsb_key),
+ unpack2,
+ crc_unpacked,
+ sink2
+ )
+ self.tb.run()
+ self.assertEqual(sink1.data(), sink2.data())
+
def test_008_crc_correct_lentag (self):
tag_name = "length"
pack_len = 8
@@ -264,13 +293,19 @@ class qa_crc32_bb (gr_unittest.TestCase):
def test_0010_tag_propagation (self):
""" Make sure tags on the CRC aren't lost. """
# Data with precalculated CRC
- data = (
- 0, 1, 2, 3, 4, 5, 6, 7, 8,
- 0, 1, 0, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 0, 1, 0,
- 1, 0, 0, 0, 0, 1, 1, 1,
- 0, 0, 1, 1, 1, 1, 0, 1
- ) # 2, 67, 225, 188
+ data = (0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0,
+ 1, 0, 1, 0, 0, 0, 0, 0,
+ 0, 1, 1, 0, 0, 0, 0, 0,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 0, 1)
testtag = gr.tag_t()
testtag.offset = len(data)-1
testtag.key = pmt.string_to_symbol('tag1')