/* -*- 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); }