summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@kit.edu>2013-10-04 15:04:28 -0400
committerMartin Braun <martin.braun@kit.edu>2013-10-06 15:57:27 -0400
commit2199253ad90ad9def601d3eacb6449461e86385d (patch)
tree5469886d97bded4d19215e6d828275d78a366860
parentb7406ba96df3f3949e17e723213bbce559594260 (diff)
digital: packet_header_default now comes with an 8-Bit CRC
-rw-r--r--gr-digital/include/gnuradio/digital/packet_header_default.h11
-rw-r--r--gr-digital/lib/packet_header_default.cc34
-rwxr-xr-xgr-digital/python/digital/qa_packet_headergenerator_bb.py8
-rwxr-xr-xgr-digital/python/digital/qa_packet_headerparser_b.py19
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")