[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 24/24: digital: fixed up some header_buffer
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 24/24: digital: fixed up some header_buffer issues and added QA. |
Date: |
Tue, 14 Jun 2016 00:41:02 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script.
jcorgan pushed a commit to branch packet2
in repository gnuradio.
commit 93acb5ba759b64ddbbc7c5c9dd1a810a9842285b
Author: Tom Rondeau <address@hidden>
Date: Fri Apr 29 15:20:59 2016 -0400
digital: fixed up some header_buffer issues and added QA.
---
.../include/gnuradio/digital/header_buffer.h | 67 ++--
gr-digital/lib/CMakeLists.txt | 1 +
gr-digital/lib/header_buffer.cc | 47 +--
gr-digital/lib/header_format_crc.cc | 4 +-
gr-digital/lib/header_format_default.cc | 2 +-
gr-digital/lib/header_format_ofdm.cc | 4 +-
gr-digital/lib/qa_digital.cc | 2 +
gr-digital/lib/qa_header_buffer.cc | 364 +++++++++++++++++++++
gr-digital/lib/qa_header_buffer.h | 59 ++++
9 files changed, 494 insertions(+), 56 deletions(-)
diff --git a/gr-digital/include/gnuradio/digital/header_buffer.h
b/gr-digital/include/gnuradio/digital/header_buffer.h
index b3f3e2c..ddcc2a8 100644
--- a/gr-digital/include/gnuradio/digital/header_buffer.h
+++ b/gr-digital/include/gnuradio/digital/header_buffer.h
@@ -24,6 +24,7 @@
#include <gnuradio/digital/api.h>
#include <vector>
+#include <stdint.h>
namespace gr {
namespace digital {
@@ -60,11 +61,9 @@ namespace gr {
* digital::header_format_default::header_nbytes().
*
* Each field is a specific length of 8, 16, 32, or 64 bits that
- * are to be transmitted in network byte order (bit
- * endian). Generally, data passed to the add_field[N] calls are
- * formatted little endian, so the data is first converted to big
- * endian and then added to the back of the buffer. If the data
- * are already big endian, set the \p be flag to true.
+ * are to be transmitted in network byte order. We can adjust the
+ * direction of the bytes by setting the byte-swap flag, \p bs, to
+ * true or false.
*
* The length argument (\p len) for all add_field[N] calls is the
* number of bytes actually accounted for in the data
@@ -117,8 +116,8 @@ namespace gr {
* current header is, in bits, using the call to length(). If the
* header is of the appropriate length, we can then start
* extracting the fields from it. When we are done with the
- * current header, call clear_input() to reset the internal buffer
- * to empty, which will mean that length() returns 0.
+ * current header, call clear() to reset the internal buffer to
+ * empty, which will mean that length() returns 0.
*
* The header fields are extracted using the extract_field[N]
* functions. Like the add_field[N] functions, we specify the size
@@ -191,6 +190,19 @@ namespace gr {
~header_buffer();
/*!
+ * Clears the header.
+ *
+ * In transmit mode, this resets the current offset so new
+ * add_field functions start adding data to the start of the
+ * buffer.
+ *
+ * In receive mode, this clears the buffer that we have inserted
+ * bits in to.
+ */
+ void clear();
+
+
+ /*!
* In transmit mode, this returns the length of the data in
* the buffer (not the allocated buffer length).
*
@@ -209,36 +221,36 @@ namespace gr {
*
* \param data The 8-bit data item.
* \param len Length (in bits) of \p data.
- * \param be Set to 'true' if data is already big endian.
+ * \param bs Set to 'true' to byte swap the data.
*/
- void add_field8(uint8_t data, int len=8, bool be=false);
+ void add_field8(uint8_t data, int len=8, bool bs=false);
/*!
* Add an 16-bit field to the header.
*
* \param data The 16-bit data item.
* \param len Length (in bits) of \p data.
- * \param be Set to 'true' if data is already big endian.
+ * \param bs Set to 'true' to byte swap the data.
*/
- void add_field16(uint16_t data, int len=16, bool be=false);
+ void add_field16(uint16_t data, int len=16, bool bs=false);
/*!
* Add an 32-bit field to the header.
*
* \param data The 32-bit data item.
* \param len Length (in bits) of \p data.
- * \param be Set to 'true' if data is already big endian.
+ * \param bs Set to 'true' to byte swap the data.
*/
- void add_field32(uint32_t data, int len=32, bool be=false);
+ void add_field32(uint32_t data, int len=32, bool bs=false);
/*!
* Add an 64-bit field to the header.
*
* \param data The 64-bit data item.
* \param len Length (in bits) of \p data.
- * \param be Set to 'true' if data is already big endian.
+ * \param bs Set to 'true' to byte swap the data.
*/
- void add_field64(uint64_t data, int len=64, bool be=false);
+ void add_field64(uint64_t data, int len=64, bool bs=false);
@@ -247,52 +259,49 @@ namespace gr {
*****************************************************/
/*!
- * Insert a new bit on the back of the input buffer.
+ * Insert a new bit on the back of the input buffer. This
+ * function is used in receive mode to add new bits as they are
+ * received for later use of the extract_field functions.
*
* \param bit New bit to add.
*/
void insert_bit(int bit);
/*!
- * Clears the input buffer; sets size to 0.
- */
- void clear_input();
-
- /*!
* Returns up to an 8-bit field in the packet header.
*
* \param pos Bit position of the start of the field.
* \param len The number of bits in the field.
- * \param be Set to 'true' to get the field as big endian.
+ * \param bs Set to 'true' to byte swap the data.
*/
- uint8_t extract_field8(int pos, int len=8, bool be=false);
+ uint8_t extract_field8(int pos, int len=8, bool bs=false);
/*!
* Returns up to a 16-bit field in the packet header.
*
* \param pos Bit position of the start of the field.
* \param len The number of bits in the field.
- * \param be Set to 'true' to get the field as big endian.
+ * \param bs Set to 'true' to byte swap the data.
*/
- uint16_t extract_field16(int pos, int len=16, bool be=false);
+ uint16_t extract_field16(int pos, int len=16, bool bs=false);
/*!
* Returns up to a 32-bit field in the packet header.
*
* \param pos Bit position of the start of the field.
* \param len The number of bits in the field.
- * \param be Set to 'true' to get the field as big endian.
+ * \param bs Set to 'true' to byte swap the data.
*/
- uint32_t extract_field32(int pos, int len=32, bool be=false);
+ uint32_t extract_field32(int pos, int len=32, bool bs=false);
/*!
* Returns up to a 64-bit field in the packet header.
*
* \param pos Bit position of the start of the field.
* \param len The number of bits in the field.
- * \param be Set to 'true' to get the field as big endian.
+ * \param bs Set to 'true' to byte swap the data.
*/
- uint64_t extract_field64(int pos, int len=64, bool be=false);
+ uint64_t extract_field64(int pos, int len=64, bool bs=false);
};
} // namespace digital
diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt
index 7e9ebed..84f53ec 100644
--- a/gr-digital/lib/CMakeLists.txt
+++ b/gr-digital/lib/CMakeLists.txt
@@ -215,6 +215,7 @@ if(ENABLE_TESTING)
${CMAKE_CURRENT_SOURCE_DIR}/test_gr_digital.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_digital.cc
${CMAKE_CURRENT_SOURCE_DIR}/qa_header_format.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_header_buffer.cc
)
add_executable(test-gr-digital ${test_gr_digital_sources})
diff --git a/gr-digital/lib/header_buffer.cc b/gr-digital/lib/header_buffer.cc
index 8cb0b17..04233da 100644
--- a/gr-digital/lib/header_buffer.cc
+++ b/gr-digital/lib/header_buffer.cc
@@ -42,12 +42,21 @@ namespace gr {
{
}
+ void
+ header_buffer::clear()
+ {
+ if(d_buffer) // TX mode
+ d_offset = 0;
+ else // RX mode
+ d_input.clear();
+ }
+
size_t
header_buffer::length() const
{
- if(d_buffer)
+ if(d_buffer) // TX mode
return d_offset;
- else
+ else // RX mode
return d_input.size();
}
@@ -58,7 +67,7 @@ namespace gr {
}
void
- header_buffer::add_field8(uint8_t data, int len, bool be)
+ header_buffer::add_field8(uint8_t data, int len, bool bs)
{
int nbytes = len/8;
if(d_buffer) {
@@ -68,12 +77,12 @@ namespace gr {
}
void
- header_buffer::add_field16(uint16_t data, int len, bool be)
+ header_buffer::add_field16(uint16_t data, int len, bool bs)
{
int nbytes = len/8;
if(d_buffer) {
uint16_t x = data;
- if(!be) {
+ if(!bs) {
volk_16u_byteswap(&x, 1);
x = x >> (16-len);
}
@@ -83,12 +92,12 @@ namespace gr {
}
void
- header_buffer::add_field32(uint32_t data, int len, bool be)
+ header_buffer::add_field32(uint32_t data, int len, bool bs)
{
int nbytes = len/8;
if(d_buffer) {
uint32_t x = data;
- if(!be) {
+ if(!bs) {
volk_32u_byteswap(&x, 1);
x = x >> (32-len);
}
@@ -98,12 +107,12 @@ namespace gr {
}
void
- header_buffer::add_field64(uint64_t data, int len, bool be)
+ header_buffer::add_field64(uint64_t data, int len, bool bs)
{
int nbytes = len/8;
if(d_buffer) {
uint64_t x = data;
- if(!be) {
+ if(!bs) {
volk_64u_byteswap(&x, 1);
x = x >> (64-len);
}
@@ -118,14 +127,8 @@ namespace gr {
d_input.push_back(bit);
}
- void
- header_buffer::clear_input()
- {
- d_input.clear();
- }
-
uint8_t
- header_buffer::extract_field8(int pos, int len, bool be)
+ header_buffer::extract_field8(int pos, int len, bool bs)
{
if(len > 8) {
throw std::runtime_error("header_buffer::extract_field for "
@@ -142,7 +145,7 @@ namespace gr {
}
uint16_t
- header_buffer::extract_field16(int pos, int len, bool be)
+ header_buffer::extract_field16(int pos, int len, bool bs)
{
if(len > 16) {
throw std::runtime_error("header_buffer::extract_field for "
@@ -155,7 +158,7 @@ namespace gr {
field = (field << 1) | ((*itr) & 0x1);
}
- if(be) {
+ if(bs) {
volk_16u_byteswap(&field, 1);
}
@@ -163,7 +166,7 @@ namespace gr {
}
uint32_t
- header_buffer::extract_field32(int pos, int len, bool be)
+ header_buffer::extract_field32(int pos, int len, bool bs)
{
if(len > 32) {
throw std::runtime_error("header_buffer::extract_field for "
@@ -176,7 +179,7 @@ namespace gr {
field = (field << 1) | ((*itr) & 0x1);
}
- if(be) {
+ if(bs) {
volk_32u_byteswap(&field, 1);
}
@@ -184,7 +187,7 @@ namespace gr {
}
uint64_t
- header_buffer::extract_field64(int pos, int len, bool be)
+ header_buffer::extract_field64(int pos, int len, bool bs)
{
if(len > 64) {
throw std::runtime_error("header_buffer::extract_field for "
@@ -197,7 +200,7 @@ namespace gr {
field = (field << 1) | ((*itr) & 0x1);
}
- if(be) {
+ if(bs) {
volk_64u_byteswap(&field, 1);
}
diff --git a/gr-digital/lib/header_format_crc.cc
b/gr-digital/lib/header_format_crc.cc
index 73d95df..7594449 100644
--- a/gr-digital/lib/header_format_crc.cc
+++ b/gr-digital/lib/header_format_crc.cc
@@ -104,11 +104,11 @@ namespace gr {
int payload_len = header_payload();
enter_have_header(payload_len);
info.push_back(d_info);
- d_hdr_reg.clear_input();
+ d_hdr_reg.clear();
return true;
}
else {
- d_hdr_reg.clear_input();
+ d_hdr_reg.clear();
return false;
}
break;
diff --git a/gr-digital/lib/header_format_default.cc
b/gr-digital/lib/header_format_default.cc
index 2ddc729..1b7a60e 100644
--- a/gr-digital/lib/header_format_default.cc
+++ b/gr-digital/lib/header_format_default.cc
@@ -187,7 +187,7 @@ namespace gr {
header_format_default::enter_have_sync()
{
d_state = STATE_HAVE_SYNC;
- d_hdr_reg.clear_input();
+ d_hdr_reg.clear();
}
inline void
diff --git a/gr-digital/lib/header_format_ofdm.cc
b/gr-digital/lib/header_format_ofdm.cc
index adc217d..acaf53b 100644
--- a/gr-digital/lib/header_format_ofdm.cc
+++ b/gr-digital/lib/header_format_ofdm.cc
@@ -122,11 +122,11 @@ namespace gr {
int payload_len = header_payload();
enter_have_header(payload_len);
info.push_back(d_info);
- d_hdr_reg.clear_input();
+ d_hdr_reg.clear();
return true;
}
else {
- d_hdr_reg.clear_input();
+ d_hdr_reg.clear();
return false;
}
break;
diff --git a/gr-digital/lib/qa_digital.cc b/gr-digital/lib/qa_digital.cc
index 07e19f4..2888d21 100644
--- a/gr-digital/lib/qa_digital.cc
+++ b/gr-digital/lib/qa_digital.cc
@@ -27,6 +27,7 @@
#include "qa_digital.h"
#include "qa_header_format.h"
+#include "qa_header_buffer.h"
CppUnit::TestSuite *
qa_digital::suite()
@@ -34,6 +35,7 @@ qa_digital::suite()
CppUnit::TestSuite *s = new CppUnit::TestSuite("gr-digital");
s->addTest(qa_header_format::suite());
+ s->addTest(qa_header_buffer::suite());
return s;
}
diff --git a/gr-digital/lib/qa_header_buffer.cc
b/gr-digital/lib/qa_header_buffer.cc
new file mode 100644
index 0000000..321e901
--- /dev/null
+++ b/gr-digital/lib/qa_header_buffer.cc
@@ -0,0 +1,364 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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 <volk/volk.h>
+#include <gnuradio/attributes.h>
+
+#include <stdio.h>
+#include <cppunit/TestAssert.h>
+
+#include "qa_header_buffer.h"
+#include <gnuradio/digital/header_buffer.h>
+
+void
+qa_header_buffer::test_add8()
+{
+ size_t len = sizeof(uint8_t);
+ uint8_t *buf = (uint8_t*)volk_malloc(len, volk_get_alignment());
+
+ gr::digital::header_buffer header(buf);
+ header.add_field8(0xAF);
+
+ CPPUNIT_ASSERT_EQUAL(len, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xAF, header.header()[0]);
+
+ header.clear();
+ CPPUNIT_ASSERT_EQUAL((size_t)0, header.length());
+
+ volk_free(buf);
+}
+
+void
+qa_header_buffer::test_add16()
+{
+ size_t len = sizeof(uint16_t);
+ uint8_t *buf = (uint8_t*)volk_malloc(len, volk_get_alignment());
+
+ uint16_t data = 0xAF5C;
+
+ gr::digital::header_buffer header(buf);
+ header.add_field16(data);
+
+ // Test standard add of a uint16
+ CPPUNIT_ASSERT_EQUAL(len, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xAF, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[1]);
+
+ // Clear; test to make sure it's clear
+ header.clear();
+ CPPUNIT_ASSERT_EQUAL((size_t)0, header.length());
+
+ // Test adding some subset of bits (must be a byte boundary)
+ header.add_field16(data, 8);
+ CPPUNIT_ASSERT_EQUAL((size_t)1, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[0]);
+ header.clear();
+
+ // Test adding and byte swapping
+ header.add_field16(data, 16, true);
+ CPPUNIT_ASSERT_EQUAL((size_t)2, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xAF, header.header()[1]);
+ header.clear();
+
+ // Test adding some subset of bits and byte swapping
+ header.add_field16(data, 8, true);
+ CPPUNIT_ASSERT_EQUAL((size_t)1, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[0]);
+ header.clear();
+
+ volk_free(buf);
+}
+
+void
+qa_header_buffer::test_add32()
+{
+ size_t len = sizeof(uint32_t);
+ uint8_t *buf = (uint8_t*)volk_malloc(len, volk_get_alignment());
+
+ uint32_t data = 0xAF5C7654;
+
+ gr::digital::header_buffer header(buf);
+ header.add_field32(data);
+
+ // Test standard add of a uint32
+ CPPUNIT_ASSERT_EQUAL(len, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xAF, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[1]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x76, header.header()[2]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[3]);
+
+ // Clear; test to make sure it's clear
+ header.clear();
+ CPPUNIT_ASSERT_EQUAL((size_t)0, header.length());
+
+ // Test adding some subset of bits (must be a byte boundary)
+ header.add_field32(data, 8);
+ CPPUNIT_ASSERT_EQUAL((size_t)1, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[0]);
+ header.clear();
+
+ // Test adding and byte swapping
+ header.add_field32(data, 32, true);
+ CPPUNIT_ASSERT_EQUAL((size_t)4, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x76, header.header()[1]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[2]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xAF, header.header()[3]);
+ header.clear();
+
+ // Test adding some subset of bits and byte swapping
+ header.add_field32(data, 24, true);
+ CPPUNIT_ASSERT_EQUAL((size_t)3, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x76, header.header()[1]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[2]);
+ header.clear();
+
+ volk_free(buf);
+}
+
+void
+qa_header_buffer::test_add64()
+{
+ size_t len = sizeof(uint64_t);
+ uint8_t *buf = (uint8_t*)volk_malloc(len, volk_get_alignment());
+
+ uint64_t data = 0xAF5C765432104567;
+
+ gr::digital::header_buffer header(buf);
+ header.add_field64(data);
+
+ // Test standard add of a uint64
+ CPPUNIT_ASSERT_EQUAL(len, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xAF, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[1]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x76, header.header()[2]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[3]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x32, header.header()[4]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x10, header.header()[5]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x45, header.header()[6]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x67, header.header()[7]);
+
+ // Clear; test to make sure it's clear
+ header.clear();
+ CPPUNIT_ASSERT_EQUAL((size_t)0, header.length());
+
+ // Test adding some subset of bits (must be a byte boundary)
+ header.add_field64(data, 48);
+ CPPUNIT_ASSERT_EQUAL((size_t)6, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x76, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[1]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x32, header.header()[2]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x10, header.header()[3]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x45, header.header()[4]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x67, header.header()[5]);
+ header.clear();
+
+ // Test adding and byte swapping
+ header.add_field64(data, 64, true);
+ CPPUNIT_ASSERT_EQUAL((size_t)8, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x67, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x45, header.header()[1]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x10, header.header()[2]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x32, header.header()[3]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[4]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x76, header.header()[5]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x5C, header.header()[6]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xAF, header.header()[7]);
+ header.clear();
+
+ // Test adding some subset of bits and byte swapping
+ header.add_field64(data, 40, true);
+ CPPUNIT_ASSERT_EQUAL((size_t)5, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x67, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x45, header.header()[1]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x10, header.header()[2]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x32, header.header()[3]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[4]);
+ header.clear();
+
+ volk_free(buf);
+}
+
+void
+qa_header_buffer::test_add_many()
+{
+ size_t len = (32+64+8+16+32)/8;
+ uint8_t *buf = (uint8_t*)volk_malloc(len, volk_get_alignment());
+
+ gr::digital::header_buffer header(buf);
+ header.add_field32(0x01234567);
+ header.add_field64(0x89ABCDEFFEDCBA98);
+ header.add_field8(0x76);
+ header.add_field16(0x5432);
+ header.add_field32(0x10012345);
+
+ CPPUNIT_ASSERT_EQUAL(len, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x01, header.header()[0]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x23, header.header()[1]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x45, header.header()[2]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x67, header.header()[3]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x89, header.header()[4]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xAB, header.header()[5]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xCD, header.header()[6]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xEF, header.header()[7]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xFE, header.header()[8]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xDC, header.header()[9]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0xBA, header.header()[10]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x98, header.header()[11]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x76, header.header()[12]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x54, header.header()[13]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x32, header.header()[14]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x10, header.header()[15]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x01, header.header()[16]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x23, header.header()[17]);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x45, header.header()[18]);
+}
+
+void
+qa_header_buffer::test_extract8()
+{
+ gr::digital::header_buffer header;
+
+ uint64_t data = 0x0123456701234567;
+
+ // Packed format: 0x80C4A2E680C4A2E6
+
+ volk_64u_byteswap(&data, 1);
+ for(int i = 0; i < 64; i++) {
+ header.insert_bit((data >> i) & 0x01);
+ }
+
+ uint8_t x0 = header.extract_field8(0);
+ uint8_t x1 = header.extract_field8(12, 8);
+ uint8_t x2 = header.extract_field8(12, 4);
+
+ CPPUNIT_ASSERT_EQUAL((size_t)64, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x80, x0);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x4A, x1);
+ CPPUNIT_ASSERT_EQUAL((uint8_t)0x04, x2);
+}
+
+void
+qa_header_buffer::test_extract16()
+{
+ gr::digital::header_buffer header;
+
+ uint64_t data = 0x0123456701234567;
+
+ // Packed format: 0x80C4A2E680C4A2E6
+
+ volk_64u_byteswap(&data, 1);
+ for(int i = 0; i < 64; i++) {
+ header.insert_bit((data >> i) & 0x01);
+ }
+
+ uint16_t x0 = header.extract_field16(0);
+ uint16_t x1 = header.extract_field16(12, 16);
+ uint16_t x2 = header.extract_field16(12, 12);
+
+ CPPUNIT_ASSERT_EQUAL((size_t)64, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint16_t)0x80C4, x0);
+ CPPUNIT_ASSERT_EQUAL((uint16_t)0x4A2E, x1);
+ CPPUNIT_ASSERT_EQUAL((uint16_t)0x04A2, x2);
+}
+
+void
+qa_header_buffer::test_extract32()
+{
+ gr::digital::header_buffer header;
+
+ uint64_t data = 0x0123456701234567;
+
+ // Packed format: 0x80C4A2E680C4A2E6
+
+ volk_64u_byteswap(&data, 1);
+ for(int i = 0; i < 64; i++) {
+ header.insert_bit((data >> i) & 0x01);
+ }
+
+ uint32_t x0 = header.extract_field32(0);
+ uint32_t x1 = header.extract_field32(12, 32);
+ uint32_t x2 = header.extract_field32(12, 24);
+
+ CPPUNIT_ASSERT_EQUAL((size_t)64, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint32_t)0x80C4A2E6, x0);
+ CPPUNIT_ASSERT_EQUAL((uint32_t)0x4A2E680C, x1);
+ CPPUNIT_ASSERT_EQUAL((uint32_t)0x004A2E68, x2);
+}
+
+void
+qa_header_buffer::test_extract64()
+{
+ gr::digital::header_buffer header;
+
+ uint64_t data = 0x0123456701234567;
+
+ // Packed format: 0x80C4A2E680C4A2E6
+
+ volk_64u_byteswap(&data, 1);
+ for(int i = 0; i < 64; i++) {
+ header.insert_bit((data >> i) & 0x01);
+ }
+
+ uint64_t x0 = header.extract_field64(0);
+ uint64_t x1 = header.extract_field64(0, 32);
+ uint64_t x2 = header.extract_field64(0, 44);
+
+ CPPUNIT_ASSERT_EQUAL((size_t)64, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint64_t)0x80C4A2E680C4A2E6, x0);
+ CPPUNIT_ASSERT_EQUAL((uint64_t)0x0000000080C4A2E6, x1);
+ CPPUNIT_ASSERT_EQUAL((uint64_t)0x0000080C4A2E680C, x2);
+}
+
+void
+qa_header_buffer::test_extract_many()
+{
+ gr::digital::header_buffer header;
+
+ uint64_t data = 0x0123456701234567;
+
+ // Packed format: 0x80C4A2E680C4A2E6
+
+ volk_64u_byteswap(&data, 1);
+ for(int i = 0; i < 64; i++) {
+ header.insert_bit((data >> i) & 0x01);
+ }
+
+ uint64_t x0 = header.extract_field64(0);
+ uint16_t x1 = header.extract_field16(28, 12);
+ uint32_t x2 = header.extract_field32(40, 21);
+ uint16_t x3 = header.extract_field16(1, 12);
+ uint8_t x4 = header.extract_field8 (7, 5);
+
+ CPPUNIT_ASSERT_EQUAL((size_t)64, header.length());
+ CPPUNIT_ASSERT_EQUAL((uint64_t)0x80C4A2E680C4A2E6, x0);
+ CPPUNIT_ASSERT_EQUAL((uint16_t)0x0680, x1);
+ CPPUNIT_ASSERT_EQUAL((uint32_t)0x0018945C, x2);
+ CPPUNIT_ASSERT_EQUAL((uint16_t)0x0018, x3);
+ CPPUNIT_ASSERT_EQUAL((uint8_t) 0x0C, x4);
+}
diff --git a/gr-digital/lib/qa_header_buffer.h
b/gr-digital/lib/qa_header_buffer.h
new file mode 100644
index 0000000..48ab086
--- /dev/null
+++ b/gr-digital/lib/qa_header_buffer.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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 _QA_DIGITAL_HEADER_BUFFER_H_
+#define _QA_DIGITAL_HEADER_BUFFER_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_header_buffer : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_header_buffer);
+ CPPUNIT_TEST(test_add8);
+ CPPUNIT_TEST(test_add16);
+ CPPUNIT_TEST(test_add32);
+ CPPUNIT_TEST(test_add64);
+ CPPUNIT_TEST(test_add_many);
+
+ CPPUNIT_TEST(test_extract8);
+ CPPUNIT_TEST(test_extract16);
+ CPPUNIT_TEST(test_extract32);
+ CPPUNIT_TEST(test_extract64);
+ CPPUNIT_TEST(test_extract_many);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void test_add8();
+ void test_add16();
+ void test_add32();
+ void test_add64();
+ void test_add_many();
+
+ void test_extract8();
+ void test_extract16();
+ void test_extract32();
+ void test_extract64();
+ void test_extract_many();
+};
+
+#endif /* _QA_DIGITAL_HEADER_BUFFER_H_ */
- [Commit-gnuradio] [gnuradio] 15/24: digital: wip: packet formatters specify payload in symbols, not bits., (continued)
- [Commit-gnuradio] [gnuradio] 15/24: digital: wip: packet formatters specify payload in symbols, not bits., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 03/24: Adding new test block to adjust the sample rate of a stream and make sure tags are being placed in the correct locations., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 06/24: digital: updates to packet_formatter classes and parsing blocks., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 08/24: digital: fixing PFB clock sync block handling of tags., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 23/24: digital: Fixing QA code for testing header formatter/parsers., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 14/24: digital: wip: pfb_clock_sync_ccf tag offset update., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 18/24: digital: fixing up some of the packet formatters since the new base class., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 17/24: docs: Adding documentation for packet comms, git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 07/24: digital: Updates to corr_est block., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 20/24: digital: fixed packet_parse from using default formatter to base class, git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 24/24: digital: fixed up some header_buffer issues and added QA.,
git <=
- [Commit-gnuradio] [gnuradio] 19/24: digital: adding more support for packet formatters., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 10/24: digital: Redid packet formatter class hierarchy., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 01/24: digital: New packet management classes., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 21/24: digital: adding packet_formatter_ofdm to replace packet_header_ofdm., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 22/24: digital: refactoring formatting/parsing code., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 02/24: digital: adding examples for using packet utilities., git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 16/24: digital: Examples for dealing with packet comms, git, 2016/06/13
- [Commit-gnuradio] [gnuradio] 05/24: digital: More examples to help debug packet blocks/code., git, 2016/06/13