diff options
author | Martin Braun <martin.braun@kit.edu> | 2013-10-04 15:04:28 -0400 |
---|---|---|
committer | Martin Braun <martin.braun@kit.edu> | 2013-10-06 15:57:27 -0400 |
commit | 2199253ad90ad9def601d3eacb6449461e86385d (patch) | |
tree | 5469886d97bded4d19215e6d828275d78a366860 | |
parent | b7406ba96df3f3949e17e723213bbce559594260 (diff) |
digital: packet_header_default now comes with an 8-Bit CRC
4 files changed, 41 insertions, 31 deletions
diff --git a/gr-digital/include/gnuradio/digital/packet_header_default.h b/gr-digital/include/gnuradio/digital/packet_header_default.h index 0654a32a63..6567dd7626 100644 --- a/gr-digital/include/gnuradio/digital/packet_header_default.h +++ b/gr-digital/include/gnuradio/digital/packet_header_default.h @@ -25,6 +25,7 @@ #include <gnuradio/tags.h> #include <gnuradio/digital/api.h> #include <boost/enable_shared_from_this.hpp> +#include <boost/crc.hpp> namespace gr { namespace digital { @@ -69,12 +70,15 @@ namespace gr { * * Uses the following header format: * Bits 0-11: The packet length (what was stored in the tag with key \p len_tag_key) - * Bits 12-27: The header number (counts up everytime this function is called) - * Bit 28: Even parity bit + * Bits 12-23: The header number (counts up everytime this function is called) + * Bit 24-31: 8-Bit CRC * All other bits: Are set to zero * - * If the header length is smaller than 29, bits are simply left out. For this + * If the header length is smaller than 32, bits are simply left out. For this * reason, they always start with the LSB. + * + * However, it is recommended to stay above 32 Bits, in order to have a working + * CRC. */ virtual bool header_formatter( long packet_len, @@ -104,6 +108,7 @@ namespace gr { int d_bits_per_byte; unsigned d_header_number; unsigned d_mask; + boost::crc_optimal<8, 0x07, 0xFF, 0x00, false, false> d_crc_impl; }; } // namespace digital diff --git a/gr-digital/lib/packet_header_default.cc b/gr-digital/lib/packet_header_default.cc index ef5f39dc97..12b8613b6d 100644 --- a/gr-digital/lib/packet_header_default.cc +++ b/gr-digital/lib/packet_header_default.cc @@ -69,27 +69,28 @@ namespace gr { ) { packet_len &= 0x0FFF; + d_crc_impl.reset(); + d_crc_impl.process_bytes((void const *) &packet_len, 2); + d_crc_impl.process_bytes((void const *) &d_header_number, 2); + unsigned char crc = d_crc_impl(); memset(out, 0x00, d_header_len); - int parity = 0; int k = 0; // Position in out for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) { out[k] = (unsigned char) ((packet_len >> i) & d_mask); - parity += out[k]; } - for (int i = 0; i < 16 && k < d_header_len; i += d_bits_per_byte, k++) { + for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) { out[k] = (unsigned char) ((d_header_number >> i) & d_mask); - parity += out[k]; } - if (k < d_header_len) { - out[k] = (unsigned char) (parity % 2); + for (int i = 0; i < 8 && k < d_header_len; i += d_bits_per_byte, k++) { + out[k] = (unsigned char) ((crc >> i) & d_mask); } d_header_number++; + d_header_number &= 0x0FFF; return true; } - bool packet_header_default::header_parser( const unsigned char *in, std::vector<tag_t> &tags) @@ -109,25 +110,30 @@ namespace gr { return true; } if (d_num_tag_key == pmt::PMT_NIL) { - k += 16; + k += 12; } else { - for (int i = 0; i < 16 && k < d_header_len; i += d_bits_per_byte, k++) { + for (int i = 0; i < 12 && k < d_header_len; i += d_bits_per_byte, k++) { header_num |= (((int) in[k]) & d_mask) << i; } tag.key = d_num_tag_key; tag.value = pmt::from_long(header_num); tags.push_back(tag); } - if (k >= d_header_len) { return true; } - int parity = in[k]; - for (int i = 0; i < 28; i++) { - parity += in[i]; + d_crc_impl.reset(); + d_crc_impl.process_bytes((void const *) &header_len, 2); + d_crc_impl.process_bytes((void const *) &header_num, 2); + unsigned char crc_calcd = d_crc_impl(); + for (int i = 0; i < 8 && k < d_header_len; i += d_bits_per_byte, k++) { + if ( (((int) in[k]) & d_mask) != (((int) crc_calcd >> i) & d_mask) ) { + return false; + } } - return !(parity % 2); + + return true; } } /* namespace digital */ diff --git a/gr-digital/python/digital/qa_packet_headergenerator_bb.py b/gr-digital/python/digital/qa_packet_headergenerator_bb.py index 3697bd1eb7..bec0828e4b 100755 --- a/gr-digital/python/digital/qa_packet_headergenerator_bb.py +++ b/gr-digital/python/digital/qa_packet_headergenerator_bb.py @@ -81,10 +81,10 @@ class qa_packet_headergenerator_bb (gr_unittest.TestCase): self.tb.connect(src, header, sink) self.tb.run() expected_data = ( - # | Number of symbols | Packet number | Parity - 0, 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, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + # | Number of symbols | Packet number | CRC + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1 ) self.assertEqual(sink.data(), expected_data) diff --git a/gr-digital/python/digital/qa_packet_headerparser_b.py b/gr-digital/python/digital/qa_packet_headerparser_b.py index 7754a7304c..1844991bc0 100755 --- a/gr-digital/python/digital/qa_packet_headerparser_b.py +++ b/gr-digital/python/digital/qa_packet_headerparser_b.py @@ -38,13 +38,13 @@ class qa_packet_headerparser_b (gr_unittest.TestCase): """ First header: Packet length 4, packet num 0 Second header: Packet 2, packet num 1 - Third header: Invalid (parity bit does not check) (would be len 4, num 2) + Third header: Invalid (CRC does not check) (would be len 4, num 2) """ encoded_headers = ( - # | Number of bytes | Packet number | Parity - 0, 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, 1, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 + # | Number of bytes | Packet number | CRC + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ) packet_len_tagname = "packet_len" random_tag = gr.tag_t() @@ -99,9 +99,9 @@ class qa_packet_headerparser_b (gr_unittest.TestCase): 2 bits per complex symbol, 32 carriers => 64 bits = 8 bytes per OFDM symbol """ encoded_headers = ( - # | Number of bytes | Packet number | Parity - 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + # | Number of bytes | Packet number | CRC + 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, ) packet_len_tagname = "packet_len" frame_len_tagname = "frame_len" @@ -165,7 +165,6 @@ class qa_packet_headerparser_b (gr_unittest.TestCase): self.assertEqual(msg, {'packet_len': packet_length, 'packet_num': 1, 'frame_len': 4}) if __name__ == '__main__': - #gr_unittest.run(qa_packet_headerparser_b, "qa_packet_headerparser_b.xml") - gr_unittest.run(qa_packet_headerparser_b) + gr_unittest.run(qa_packet_headerparser_b, "qa_packet_headerparser_b.xml") |