[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 01/24: digital: New packet management class
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 01/24: digital: New packet management classes. |
Date: |
Tue, 14 Jun 2016 00:40:54 +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 ff7f8302b1df27854b1a1bc5131ed530bde72242
Author: Tom Rondeau <address@hidden>
Date: Thu Dec 18 19:08:23 2014 -0500
digital: New packet management classes.
- default packet formatter: contains access code and payload length
fields.
- counter packet formatter: also contains the bits/sym in the payload
modulation and a packet number counter.
- Also adds QA code and the infrastructure for C++ QA code in
gr-digital.
- New block to use the packet formatter objects.
- The header and payload are transmitted as PDU messages out of different
ports.
- header_buffer class for header formatting.
- Used by packet_formatter_x classes to more easily add and format
header data for transmission.
- New blocks that parse headers.
- Handles either hard or soft bits. Produces an info message to
instruct payload demod.
- 'receive mode' to header_buffer class.
- Designed to make extracting fields from the received header bits
easier for packet formatter classes. Use extract_field[N] to get
the different fields out of a collected set of header bits. *
Docs describing both functions with small examples for how to use
them.
- Don't force access code to be a multiple of 8
- need to verify everything else handles this correctly.
- Throw an exception in the ctor if setting the code failed and emit a
log message.
---
gr-digital/grc/digital_block_tree.xml | 3 +
gr-digital/grc/digital_packet_format_async.xml | 31 ++
gr-digital/grc/digital_packet_parse_x.xml | 46 +++
.../grc/variable_packet_formatter_default.xml | 28 ++
gr-digital/include/gnuradio/digital/CMakeLists.txt | 6 +
.../include/gnuradio/digital/header_buffer.h | 301 +++++++++++++++
.../include/gnuradio/digital/packet_format_async.h | 89 +++++
.../gnuradio/digital/packet_formatter_counter.h | 128 +++++++
.../gnuradio/digital/packet_formatter_default.h | 300 +++++++++++++++
.../include/gnuradio/digital/packet_parse_b.h | 99 +++++
.../include/gnuradio/digital/packet_parse_f.h | 105 ++++++
gr-digital/lib/CMakeLists.txt | 40 ++
gr-digital/lib/header_buffer.cc | 208 ++++++++++
gr-digital/lib/packet_format_async_impl.cc | 94 +++++
.../packet_format_async_impl.h} | 46 ++-
gr-digital/lib/packet_formatter_counter.cc | 126 +++++++
gr-digital/lib/packet_formatter_default.cc | 319 ++++++++++++++++
gr-digital/lib/packet_header_ofdm.cc | 9 +-
gr-digital/lib/packet_parse_b_impl.cc | 93 +++++
gr-digital/lib/packet_parse_b_impl.h | 53 +++
gr-digital/lib/packet_parse_f_impl.cc | 92 +++++
gr-digital/lib/packet_parse_f_impl.h | 53 +++
.../{swig/packet_header.i => lib/qa_digital.cc} | 37 +-
.../{swig/packet_header.i => lib/qa_digital.h} | 34 +-
gr-digital/lib/qa_packet_formatters.cc | 417 +++++++++++++++++++++
gr-digital/lib/qa_packet_formatters.h | 49 +++
.../packet_header.i => lib/test_gr_digital.cc} | 44 ++-
gr-digital/python/digital/qa_packet_format.py | 135 +++++++
gr-digital/swig/CMakeLists.txt | 1 +
gr-digital/swig/digital_swig.i | 13 +
gr-digital/swig/packet_header.i | 20 +-
31 files changed, 2949 insertions(+), 70 deletions(-)
diff --git a/gr-digital/grc/digital_block_tree.xml
b/gr-digital/grc/digital_block_tree.xml
index 9bdf6e9..3ae99f3 100644
--- a/gr-digital/grc/digital_block_tree.xml
+++ b/gr-digital/grc/digital_block_tree.xml
@@ -72,6 +72,9 @@
<block>digital_crc32_bb</block>
<block>digital_crc32_async_bb</block>
<block>digital_framer_sink_1</block>
+ <block>variable_packet_formatter_default</block>
+ <block>digital_packet_format_async</block>
+ <block>digital_packet_parse_x</block>
<block>digital_header_payload_demux</block>
<block>digital_packet_headergenerator_bb</block>
<block>digital_packet_headergenerator_bb_default</block>
diff --git a/gr-digital/grc/digital_packet_format_async.xml
b/gr-digital/grc/digital_packet_format_async.xml
new file mode 100644
index 0000000..95f6b4f
--- /dev/null
+++ b/gr-digital/grc/digital_packet_format_async.xml
@@ -0,0 +1,31 @@
+<block>
+ <name>Packet Header Formatter</name>
+ <key>digital_packet_format_async</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.packet_format_async($formatter)</make>
+
+ <param>
+ <name>Formatter</name>
+ <key>formatter</key>
+ <type>raw</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>message</type>
+ <optional>1</optional>
+ </sink>
+
+ <source>
+ <name>header</name>
+ <type>message</type>
+ <optional>1</optional>
+ </source>
+
+ <source>
+ <name>payload</name>
+ <type>message</type>
+ <optional>1</optional>
+ </source>
+
+</block>
diff --git a/gr-digital/grc/digital_packet_parse_x.xml
b/gr-digital/grc/digital_packet_parse_x.xml
new file mode 100644
index 0000000..493b916
--- /dev/null
+++ b/gr-digital/grc/digital_packet_parse_x.xml
@@ -0,0 +1,46 @@
+<block>
+ <name>Packet Parser</name>
+ <key>digital_packet_parse_x</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.packet_parse_$(type)($formatter, $threshold)</make>
+
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Hard Bits</name>
+ <key>b</key>
+ <opt>input:byte</opt>
+ </option>
+ <option>
+ <name>Soft Bits</name>
+ <key>f</key>
+ <opt>input:float</opt>
+ </option>
+ </param>
+
+ <param>
+ <name>Formatter</name>
+ <key>formatter</key>
+ <type>raw</type>
+ </param>
+
+ <param>
+ <name>Threshold</name>
+ <key>threshold</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+
+ <source>
+ <name>info</name>
+ <type>message</type>
+ <optional>1</optional>
+ </source>
+</block>
diff --git a/gr-digital/grc/variable_packet_formatter_default.xml
b/gr-digital/grc/variable_packet_formatter_default.xml
new file mode 100644
index 0000000..7ba27fa
--- /dev/null
+++ b/gr-digital/grc/variable_packet_formatter_default.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+# packet_formatter_default object
+###################################################
+ -->
+<block>
+ <name>Default Packet Header Definition</name>
+ <key>variable_packet_formatter_default</key>
+ <import>from gnuradio import digital</import>
+ <var_make>
+#if int($access_code())==0 #
+self.$(id) = $(id) =
digital.packet_formatter_default(digital.packet_utils.default_access_code)
+#else
+self.$(id) = $(id) = digital.packet_formatter_default($access_code)
+#end if
+ </var_make>
+ <var_value>digital.packet_formatter_default($access_code)</var_value>
+ <make></make>
+
+ <param>
+ <name>Access Code</name>
+ <key>access_code</key>
+ <value>0</value>
+ <type>string</type>
+ </param>
+
+</block>
diff --git a/gr-digital/include/gnuradio/digital/CMakeLists.txt
b/gr-digital/include/gnuradio/digital/CMakeLists.txt
index d8fe2b6..a2d115d 100644
--- a/gr-digital/include/gnuradio/digital/CMakeLists.txt
+++ b/gr-digital/include/gnuradio/digital/CMakeLists.txt
@@ -65,6 +65,7 @@ install(FILES
glfsr_source_f.h
hdlc_deframer_bp.h
hdlc_framer_pb.h
+ header_buffer.h
header_payload_demux.h
kurtotic_equalizer_cc.h
lfsr.h
@@ -90,6 +91,11 @@ install(FILES
ofdm_sampler.h
ofdm_serializer_vcc.h
ofdm_sync_sc_cfb.h
+ packet_formatter_default.h
+ packet_formatter_counter.h
+ packet_format_async.h
+ packet_parse_b.h
+ packet_parse_f.h
packet_header_default.h
packet_header_ofdm.h
packet_headergenerator_bb.h
diff --git a/gr-digital/include/gnuradio/digital/header_buffer.h
b/gr-digital/include/gnuradio/digital/header_buffer.h
new file mode 100644
index 0000000..263bc35
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/header_buffer.h
@@ -0,0 +1,301 @@
+/* -*- c++ -*- */
+/* Copyright 2015 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 INCLUDED_DIGITAL_HEADER_BUFFER_H
+#define INCLUDED_DIGITAL_HEADER_BUFFER_H
+
+#include <gnuradio/digital/api.h>
+#include <vector>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Helper class for handling payload headers.
+ * \ingroup packet_operators_blk
+ *
+ * \details
+ *
+ * This class is used by the packet formatter blocks (e.g.,
+ * digital::packet_formatter_default) to make it easier to deal
+ * with payload headers. This class functions in two different
+ * ways depending on if it is used in a transmitter or
+ * receiver. When used in a transmitter, this class helps us build
+ * headers out of the fields of the protocol. When used in a
+ * receiver, this class helps us parse the received bits into the
+ * protocol's fields.
+ *
+ * This page describes how to work with the different modes,
+ * transmit or receive. The class is instructed as to which mode
+ * it is in by how the constructor is called. If the constructor
+ * is passed a valid array (non NULL), then it is in transmit mode
+ * and will pack this buffer with the header fields. If that
+ * buffer is NULL, the object is in receive mode.
+ *
+ * \section header_buffer_tx Transmit Mode
+ *
+ * When passed a valid buffer in the constructor, this object is in
+ * transmit mode. We can then use the add_field[N] functions to
+ * add new fields to this header. The buffer MUST be large enough
+ * to hold the full header. As this class is meant to work mostly
+ * with the digital::packet_formatter_default and child
+ * classes, the header length can be read from
+ * digital::packet_formatter_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.
+ *
+ * The length argument (\p len) for all add_field[N] calls is the
+ * number of bytes actually accounted for in the data
+ * structure. Often, we would use the full size of the field,
+ * which is sizeof(dtype), and the add_field[N] call defaults to
+ * len=N. Occasionally, we may need to use fewer bytes than
+ * actually represented by the data type. An example would be the
+ * access code used in the packet_formatter_default, which is a
+ * uint64_t type but may have fewer bytes used in the actual
+ * access code.
+ *
+ * The function that calls this class is expected to handle the
+ * memory handling of the buffer -- both allocating and
+ * deallocating.
+ *
+ * As simple example of using this class in transmit mode:
+ *
+ * \verbatim
+ uint8_t* buffer = (uint8_t*)volk_malloc(header_nbytes(),
+ volk_get_alignment());
+
+ header_buffer hdr(buffer);
+ hdr.add_field64(sync_word, sync_word_len);
+ hdr.add_field16(payload_length);
+ hdr.add_field8(header_flags);
+ hdr.add_field8(header_options);
+
+ // Do something with the header
+
+ volk_free(buffer);
+ \endverbatim
+ *
+ * In this example, the header contains four fields:
+ *
+ * \verbatim
+ |0 15|16 23|24 31|
+ | sync word |
+ | |
+ | length | flags | options |
+ \endverbatim
+ *
+ * The sync word can be up to 64-bits, but the add_field64 is also
+ * passed the number of actual bytes in the sync word and so could
+ * be fewer.
+ *
+ * \section header_buffer_rx Receive Mode
+ *
+ * In receive mode, we build up the header as bits are received by
+ * inserting them with insert_bit. We can find out how long the
+ * 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.
+ *
+ * The header fields are extracted using the extract_field[N]
+ * functions. Like the add_field[N] functions, we specify the size
+ * (in bits) of the field we are extracting. We pass this function
+ * the bit-position of the expected field in the received header
+ * buffer. The extract_field[N] assumes that the number of bits
+ * for the field is N, but we can tell the function to use fewer
+ * bits if we want. Setting the length parameter of these
+ * functions greater than N is illegal, and it will throw an
+ * error.
+ *
+ * For example, given a header of | length | seq. num. | where the
+ * length is 16 bits and the sequence number is 32 bits, we would
+ * use:
+ *
+ * \verbatim
+ uint16_t len = d_hdr_reg.extract_field16(0);
+ uint32_t seq = d_hdr_reg.extract_field32(16);
+ \endverbatim
+ *
+ * The extract_field functions are specific to data types of the
+ * field and the number of bits for each field is inferred by the
+ * data type. So extract_field16 assumes we want all 16 bits in
+ * the field represented.
+ *
+ * Some headers have fields that are not standard sizes of
+ * integers, like a 1 bit, 4 bit, or even 12 bit fields. We can
+ * ask for fewer bits for each field. say:
+ *
+ * \verbatim
+ |0 15|16 19|20 31|
+ | len | flags | options |
+ \endverbatim
+ *
+ * We would use the following extraction functions:
+ *
+ * \verbatim
+ uint16_t len = d_hdr_reg.extract_field16(0);
+ uint8_t flags = d_hdr_reg.extract_field8(16, 4);
+ uint16_t opts = d_hdr_reg.extract_field16(20, 12);
+ \endverbatim
+ *
+ * \sa packet_formatter_default
+ * \sa packet_formatter_counter
+ */
+ class DIGITAL_API header_buffer
+ {
+ private:
+ size_t d_offset;
+ uint8_t *d_buffer;
+
+ std::vector<bool> d_input;
+
+ public:
+ /*!
+ * Create a header buffer object with a pre-allocated buffer, \p
+ * buffer, to hold the formatted header data.
+ *
+ * If \p buffer is set to NULL, then this object is in receive
+ * mode meant to receive bits from an incoming data stream and
+ * provide the ability to extract fields. In this mode, calls to
+ * add_field are invalid and will be nops.
+ */
+ header_buffer(uint8_t *buffer=NULL);
+
+ /*!
+ * Class destructor.
+ */
+ ~header_buffer();
+
+ /*!
+ * In transmit mode, this returns the length of the data in
+ * the buffer (not the allocated buffer length).
+ *
+ * In receiving mode, this returns the current length in bits of
+ * the received header.
+ */
+ size_t length() const;
+
+ /*!
+ * Returns a constant pointer to the buffer.
+ */
+ const uint8_t* header() const;
+
+ /*!
+ * Add an 8-bit field to the header.
+ *
+ * \param data The 8-bit data item.
+ * \param len Length (in bits) of \p data (here, always 1).
+ * \param be Set to 'true' if data is already big endian.
+ */
+ void add_field8(uint8_t data, int len=8, bool be=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.
+ */
+ void add_field16(uint16_t data, int len=16, bool be=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.
+ */
+ void add_field32(uint32_t data, int len=32, bool be=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.
+ */
+ void add_field64(uint64_t data, int len=64, bool be=false);
+
+
+
+ /*****************************************************
+ * Receive mode to build a header from bits *
+ *****************************************************/
+
+ /*!
+ * Insert a new bit on the back of the input buffer.
+ *
+ * \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.
+ */
+ uint8_t extract_field8(int pos, int len=8, bool be=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.
+ */
+ uint16_t extract_field16(int pos, int len=16, bool be=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.
+ */
+ uint32_t extract_field32(int pos, int len=32, bool be=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.
+ */
+ uint64_t extract_field64(int pos, int len=64, bool be=false);
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_HEADER_BUFFER_H */
diff --git a/gr-digital/include/gnuradio/digital/packet_format_async.h
b/gr-digital/include/gnuradio/digital/packet_format_async.h
new file mode 100644
index 0000000..2f32065
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/packet_format_async.h
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 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 INCLUDED_DIGITAL_PACKET_FORMAT_ASYNC_H
+#define INCLUDED_DIGITAL_PACKET_FORMAT_ASYNC_H
+
+#include <gnuradio/digital/api.h>
+#include <gnuradio/digital/packet_formatter_default.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Uses a header formatter to append a header onto a PDU.
+ * \ingroup packet_operators_blk
+ *
+ * \details
+
+ * This block takes in PDUs and creates a header, generally for
+ * MAC-level processing. Each received PDU is assumed to be its
+ * own frame, so any fragmentation would be done upstream in or
+ * before the flowgraph.
+ *
+ * The header that is created and transmitted out of the 'header'
+ * message port as a PDU. The header is based entirely on the \p
+ * formatter, which is a packet_formatter_default or a child
+ * class. All of these packet header formatters operate the same:
+ * they take in the payload data as well as possible extra
+ * metadata info about the PDU; the formatter then returns the
+ * output PDU as a PMT argument along with any changes to the
+ * metadata info PMT.
+ *
+ * For different packet header formatting needs, we can define new
+ * classes that inherit from the packet_formatter_default block
+ * and which overload the packet_formatter_default::format
+ * function.
+ *
+ * \sa packet_formatter_default
+ * \sa packet_formatter_counter
+ *
+ * This block only uses asynchronous message passing interfaces to
+ * receiver and emit PDUs. The message ports are:
+ *
+ * \li in: receives PDUs for the frame payload
+ * \li header: the header formatted for the given frame
+ * \li payload: the payload
+ */
+ class DIGITAL_API packet_format_async : virtual public block
+ {
+ public:
+ typedef boost::shared_ptr<packet_format_async> sptr;
+
+ /*!
+ * Make a packet header block using a given \p formatter.
+ *
+ * \param formatter The formatter class to use when creating the
+ * header for the packet. The default formatter is
+ * packet_formatter_default and just applies an access
+ * code and a header that repeats the PDU's frame length
+ * twice.
+ */
+ static sptr make(const packet_formatter_default::sptr &formatter);
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_FORMAT_ASYNC_H */
diff --git a/gr-digital/include/gnuradio/digital/packet_formatter_counter.h
b/gr-digital/include/gnuradio/digital/packet_formatter_counter.h
new file mode 100644
index 0000000..30578b1
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/packet_formatter_counter.h
@@ -0,0 +1,128 @@
+/* -*- c++ -*- */
+/* Copyright 2014 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 INCLUDED_DIGITAL_PACKET_FORMATTER_COUNTER_H
+#define INCLUDED_DIGITAL_PACKET_FORMATTER_COUNTER_H
+
+#include <pmt/pmt.h>
+#include <gnuradio/digital/api.h>
+#include <gnuradio/digital/packet_formatter_default.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Header formatter that adds the payload bits/symbol
+ * format and a packet number counter.
+ * \ingroup packet_operators_blk
+ *
+ * \details
+ *
+ * Child class of packet_formatter_default. This version adds two
+ * fields to the header:
+ *
+ * \li bps (16 bits): bits/symbol used when modulating the payload.
+ * \li count (16 bits): a counter for the packet number.
+ *
+ * Like the default packet formatter, the length is encoded as a
+ * 16-bit value repeated twice. The full packet looks like:
+ * \verbatim
+ | access code | hdr | payload |
+ \endverbatim
+ *
+ * Where the access code is <= 64 bits and hdr is:
+ * \verbatim
+ | 0 -- 15 | 16 -- 31 |
+ | pkt len | pkt len |
+ | bits/sym | counter |
+ \endverbatim
+ *
+ * The access code and header are formatted for network byte order.
+ *
+ * \sa packet_formatter_default
+ */
+ class DIGITAL_API packet_formatter_counter
+ : public packet_formatter_default
+ {
+ public:
+ packet_formatter_counter(const std::string &access_code, int bps);
+ virtual ~packet_formatter_counter();
+
+ /*!
+ * Creates a header from the access code and packet length to
+ * build an output packet in the form:
+ *
+ * \verbatim
+ | access code | pkt len | pkt len | bps | counter |
+ \endverbatim
+ *
+ * \param nbytes_in The length (in bytes) of the \p input payload
+ * \param input An array of unsigned chars of the packet payload
+ * \param output A pmt::u8vector with the new header prepended
+ * onto the input data.
+ * \param info A pmt::dict containing meta data and info about
+ * the PDU (generally from the metadata portion of the
+ * input PDU). Data can be extracted from this for the
+ * header formatting or inserted.
+ */
+ virtual bool format(int nbytes_in,
+ const unsigned char *input,
+ pmt::pmt_t &output,
+ pmt::pmt_t &info);
+
+ /*!
+ * Returns the length of the formatted header in bits.
+ */
+ virtual size_t header_nbits() const;
+
+ /*!
+ * Returns the length of the formatted header in bytes.
+ */
+ virtual size_t header_nbytes() const;
+
+ /*!
+ * Factory to create an async packet header formatter; returns
+ * an sptr to the object.
+ */
+ static sptr make(const std::string &access_code, int bps);
+
+ protected:
+ uint16_t d_counter; //!< keeps track of the number of packets
transmitted
+
+ //! Verify that the header is valid
+ bool header_ok();
+
+ /*! Get info from the header; return payload length and package
+ * rest of data in d_info dictionary.
+ *
+ * Extracts the header of the form:
+ *
+ * \verbatim
+ | access code | pkt len | pkt len | bps | counter | payload |
+ \endverbatim
+ */
+ int header_payload();
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_FORMATTER_COUNTER_H */
diff --git a/gr-digital/include/gnuradio/digital/packet_formatter_default.h
b/gr-digital/include/gnuradio/digital/packet_formatter_default.h
new file mode 100644
index 0000000..f907e92
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/packet_formatter_default.h
@@ -0,0 +1,300 @@
+/* -*- c++ -*- */
+/* Copyright 2014-2015 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 INCLUDED_DIGITAL_PACKET_FORMATTER_DEFAULT_H
+#define INCLUDED_DIGITAL_PACKET_FORMATTER_DEFAULT_H
+
+#include <pmt/pmt.h>
+#include <gnuradio/digital/api.h>
+#include <gnuradio/digital/header_buffer.h>
+#include <boost/enable_shared_from_this.hpp>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Default header formatter for PDU formatting.
+ * \ingroup packet_operators_blk
+ *
+ * \details
+
+ * Used to handle the default packet header. The formatters manage
+ * two functions:
+ *
+ * \li packet_formatter_default::format: takes in a
+ * payload and creates a header from it.
+ *
+ * \li packet_formatter_default::parse receive bits and
+ * extract the header info.
+ *
+ * Another version of the parser is
+ * packet_formatter_default::parse_soft that receives soft
+ * decisions instead of hard bits.
+ *
+ * This class is specifically designed to work with packets/frames
+ * in the asynchronous PDU architecture of GNU Radio. See the
+ * packet_format_async block for formatting the headers onto
+ * payloads and packet_parse_b and packet_parse_f blocks for
+ * parsing headers in a receiver.
+ *
+ * The Packet Format block takes in a PDU and uses a formatter
+ * class derived from this class to add a header onto the
+ * packet. The Packet Format blocks takes in the PDU, unpacks the
+ * message, and passes it to a formatter class' format function,
+ * which builds a header based on the payload. The header is
+ * passed back and emitted from formatter block as a separate
+ * output. The async format block, packet_format_async, has two
+ * message output ports. The 'header' port passes the header out
+ * as a PDU and the 'payload' passes the payload out as a PDU. The
+ * flowgraph can then separately modulate and combine these two
+ * pieces in the follow-on processing.
+ *
+ * The packet_sync_b and packet_sync_f blocks use the same
+ * formatter class by calling the 'parse' or 'parse_soft' to parse
+ * the received packet headers. These parser blocks are sinks for
+ * the data stream and emit a message from an 'info' port that
+ * contains an PMT dictionary of the information in the
+ * header. The formatter class determines the dictionary keys.
+ *
+ * This is the base class for dealing with formatting headers for
+ * different protocols and purposes. For other header formatting
+ * behaviors, create a child class from here and overload the
+ * format, parse, parse_soft, and parsing state machine functions
+ * as necessary.
+ *
+ * The default header created in this base class consists of an
+ * access code and the packet length. The length is encoded as a
+ * 16-bit value repeated twice:
+ *
+ * \verbatim
+ | access code | hdr | payload |
+ \endverbatim
+ *
+ * Where the access code is <= 64 bits and hdr is:
+ *
+ * \verbatim
+ | 0 -- 15 | 16 -- 31 |
+ | pkt len | pkt len |
+ \endverbatim
+ *
+ * The access code and header are formatted for network byte order.
+ *
+ * This header generator does not calculate or append a CRC to the
+ * packet. Use the CRC32 Async block for that before adding the
+ * header. The header's length will then measure the payload plus
+ * the CRC length (4 bytes for a CRC32).
+ *
+ * The default header parser produces a PMT dictionary that
+ * contains the following keys. All formatter blocks MUST produce
+ * these two values in any dictionary.
+ *
+ * \li "skip samps": the number of samples between the end of the
+ * last payload and the beginning of this payload. This is used by
+ * a decoder block to know where in the payload to begin
+ * demodulating the payload.
+ *
+ * \li "payload bits": the number of bits in the payload. The
+ * payload decoder will have to know how this relates to the
+ * number of symbols received.
+ *
+ * \sa packet_formatter_counter
+ * \sa packet_formatter_1
+ * \sa packet_formatter_ofdm
+ */
+ class DIGITAL_API packet_formatter_default
+ : public
boost::enable_shared_from_this<gr::digital::packet_formatter_default>
+ {
+ public:
+ typedef boost::shared_ptr<packet_formatter_default> sptr;
+
+ packet_formatter_default(const std::string &access_code);
+ virtual ~packet_formatter_default();
+
+ sptr base() { return shared_from_this(); };
+ sptr formatter() { return shared_from_this(); };
+
+ /*!
+ * Creates a header from the access code and packet length and
+ * creates an output header as a PMT vector in the form:
+ *
+ * \verbatim
+ | access code | pkt len | pkt len |
+ \endverbatim
+ *
+ * \param nbytes_in The length (in bytes) of the \p input payload
+ * \param input An array of unsigned chars of the packet payload
+ * \param output A pmt::u8vector with the new header prepended
+ * onto the input data.
+ * \param info A pmt::dict containing meta data and info about
+ * the PDU (generally from the metadata portion of the
+ * input PDU). Data can be extracted from this for the
+ * header formatting or inserted.
+ */
+ virtual bool format(int nbytes_in,
+ const unsigned char *input,
+ pmt::pmt_t &output,
+ pmt::pmt_t &info);
+
+ /*!
+ * Parses a header of the form:
+ *
+ * \verbatim
+ | access code | pkt len | pkt len | payload |
+ \endverbatim
+ *
+ * This is implemented as a state machine that starts off
+ * searching for the access code. Once found, the access code is
+ * used to find the start of the packet and the following
+ * header. This default header encodes the length of the payload
+ * a 16 bit integer twice. The state machine finds the header
+ * and checks that both payload length values are the same. It
+ * then goes into its final state that reads in the payload
+ * (based on the payload length) and produces a payload as a PMT
+ * u8 vector of packed bytes.
+ *
+ * \param nbits_in The number of bits in the input array.
+ * \param input The input as hard decision bits.
+ * \param info A vector of pmt::dicts to hold any meta data or
+ * info about the PDU. When parsing the header, the
+ * formatter can add info from the header into this dict.
+ * Each packet has a single PMT dictionary of info, so
+ * the vector length is the number of packets received
+ * extracted during one call to this parser function.
+ */
+ virtual bool parse(int nbits_in,
+ const unsigned char *input,
+ std::vector<pmt::pmt_t> &info);
+
+ /*!
+ * Parses a header of the form:
+ *
+ * \verbatim
+ | access code | pkt len | pkt len | payload |
+ \endverbatim
+ *
+ * This is implemented as a state machine that starts off
+ * searching for the access code. Once found, the access code is
+ * used to find the start of the packet and the following
+ * header. This default header encodes the length of the payload
+ * a 16 bit integer twice. The state machine finds the header
+ * and checks that both payload length values are the same. It
+ * then goes into its final state that reads in the payload
+ * (based on the payload length) and produces a payload as a PMT
+ * f32 vector of soft decision bits.
+ *
+ * This form of the header parser is specifically intended for
+ * use with FEC decoders, in particular the
+ * gr::fec::async_decoder.
+ *
+ * \param nbits_in The number of soft decisions in the input array.
+ * \param input The input as soft decision floats.
+ * \param info A vector of pmt::dicts to hold any meta data or
+ * info about the PDU. When parsing the header, the
+ * formatter can add info from the header into this dict.
+ * Each packet has a single PMT dictionary of info, so
+ * the vector length is the number of packets received
+ * extracted during one call to this parser function.
+ */
+ virtual bool parse_soft(int nbits_in,
+ const float *input,
+ std::vector<pmt::pmt_t> &info);
+
+ /*!
+ * Returns the length of the formatted header in bits.
+ */
+ virtual size_t header_nbits() const;
+
+ /*!
+ * Returns the length of the formatted header in bytes.
+ */
+ virtual size_t header_nbytes() const;
+
+ /*!
+ * Updates the access code. Must be a string of 1's and 0's and
+ * <= 64 bits.
+ */
+ bool set_access_code(const std::string &access_code);
+
+ /*!
+ * Returns the formatted access code as a 64-bit register.
+ */
+ unsigned long long access_code() const;
+
+ /*!
+ * Sets the threshold for number of access code bits can be in
+ * error before detection. Defaults to 0.
+ */
+ void set_threshold(unsigned int thresh=0);
+
+ /*!
+ * Returns threshold value for access code detection.
+ */
+ unsigned int threshold() const;
+
+ /*!
+ * Factory to create an async packet header formatter; returns
+ * an sptr to the object.
+ */
+ static sptr make(const std::string &access_code);
+
+ protected:
+ enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+ uint64_t d_access_code; //!< register to hold the access code
+ size_t d_access_code_len; //!< length in bits of the access code
+
+ state_t d_state; //!< state of the state machine
+ unsigned long long d_data_reg; //!< used to look for access_code
+ unsigned long long d_mask; /*!< masks access_code bits (top N bits
are set where
+ N is the number of bits in the access
code) */
+ unsigned int d_threshold; //!< how many bits may be wrong in sync
vector
+
+ header_buffer d_hdr_reg;
+
+ int d_pkt_len; //!< Length of the packet to put into the
output buffer
+ int d_pkt_count; //!< Number of bytes/soft bits already
received
+ pmt::pmt_t d_info; //!< info captured from the header
+ int d_count; //!< count samples since last payload
start
+
+ uint16_t d_bps; //!< bits/sec of payload modulation
+
+ //! Enter Search state of the state machine to find the access code.
+ virtual void enter_search();
+
+ //! Access code found, start getting the header
+ virtual void enter_have_sync();
+
+ //! Header found, setup for pulling in the hard decision bits
+ virtual void enter_have_header(int payload_len);
+
+ //! Verify that the header is valid
+ virtual bool header_ok();
+
+ /*! Get info from the header; return payload length and package
+ * rest of data in d_info dictionary.
+ */
+ virtual int header_payload();
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_FORMATTER_DEFAULT_H */
diff --git a/gr-digital/include/gnuradio/digital/packet_parse_b.h
b/gr-digital/include/gnuradio/digital/packet_parse_b.h
new file mode 100644
index 0000000..a87beb5
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/packet_parse_b.h
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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 INCLUDED_DIGITAL_PACKET_PARSE_B_H
+#define INCLUDED_DIGITAL_PACKET_PARSE_B_H
+
+#include <gnuradio/digital/api.h>
+#include <gnuradio/digital/packet_formatter_default.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Block that synchronizes to a header based on a header
+ * formatter class. Designed to accept hard bits and produce PDUs
+ * with packed bytes (pmt::u8vector).
+ *
+ * \ingroup packet_operators_blk
+ *
+ * \details
+ *
+ * A packet synchronizer block. This block takes in hard bits
+ * (unpacked bytes; 1's and 0's as the LSB) and finds the access
+ * code as a sync word to find the start of a frame.
+ *
+ * The block uses a formatter derived from a
+ * packet_formatter_default formatter class. The only thing
+ * this class is required to have in the header is an access code
+ * of up to 64 bits. This block uses the formatter and access code
+ * to do the frame synchronization. An access code is found if the
+ * received bits have fewer than \p threshold errors detected.
+ *
+ * Once the frame access code is detected, the block uses the
+ * formatter's parse_header to decode the remaining
+ * header. Generally, as in the default header case, the header
+ * will contain the length of the frame's payload. That and
+ * anything else in the header will generally go into the PDU's
+ * meta-data dictionary.
+ *
+ * The block will output a PDU that contains frame's header info
+ * in the meta-data portion of the PDU and the payload itself. The
+ * payload is packed hard bits as taken from the input stream.
+ *
+ * \sa packet_sync_ff for a soft decision version.
+ */
+ class DIGITAL_API packet_parse_b : virtual public sync_block
+ {
+ public:
+ typedef boost::shared_ptr<packet_parse_b> sptr;
+
+ /*!
+ * Make a packet header block using a given \p formatter.
+ *
+ * \param formatter The formatter class to use when reading the
+ * header.
+ * \param threshold How many bits in the access code the
+ * \p formatter can miss and still trigger a hit.
+ */
+ static sptr make(const packet_formatter_default::sptr &formatter,
+ unsigned int threshold=0);
+
+ /*!
+ * Sets the threshold level for the formatter when finding the
+ * access code. See packet_formatter_default::set_threshold
+ * for more details.
+ */
+ virtual void set_threshold(unsigned int thresh) = 0;
+
+ /*!
+ * Gets the access code detection threshold from the formatter.
+ */
+ virtual unsigned int threshold() const = 0;
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_PARSE_B_H */
diff --git a/gr-digital/include/gnuradio/digital/packet_parse_f.h
b/gr-digital/include/gnuradio/digital/packet_parse_f.h
new file mode 100644
index 0000000..d146702
--- /dev/null
+++ b/gr-digital/include/gnuradio/digital/packet_parse_f.h
@@ -0,0 +1,105 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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 INCLUDED_DIGITAL_PACKET_PARSE_F_H
+#define INCLUDED_DIGITAL_PACKET_PARSE_F_H
+
+#include <gnuradio/digital/api.h>
+#include <gnuradio/digital/packet_formatter_default.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Block that synchronizes to a header based on a header
+ * formatter class. Designed to accept soft decisions and produce
+ * PDUs with soft decisions (pmt::f32vector).
+ *
+ * \ingroup packet_operators_blk
+ *
+ * \details
+ *
+ * A packet synchronizer block. This block takes in soft decision
+ * bits (floats) and finds the access code as a sync word to find
+ * the start of a frame.
+ *
+ * The block uses a formatter derived from a
+ * packet_formatter_default formatter class. The only thing
+ * this class is required to have in the header is an access code
+ * of up to 64 bits. This block uses the formatter and access code
+ * to do the frame synchronization. An access code is found if the
+ * received bits have fewer than \p threshold errors detected.
+ *
+ * As soft decisions are received, the header is generally uncoded
+ * or the formatter will understand the code and handle it
+ * itself. Mostly, the header_parser will just slice the decisions
+ * at 0 and convert to hard 1's and 0's.
+ *
+ * Once the frame access code is detected, the block uses the
+ * formatter's parse_header to decode the remaining
+ * header. Generally, as in the default header case, the header
+ * will contain the length of the frame's payload. That and
+ * anything else in the header will generally go into the PDU's
+ * meta-data dictionary.
+ *
+ * The block will output a PDU that contains frame's header info
+ * in the meta-data portion of the PDU and the payload itself. The
+ * payload will be the input soft decision values, so the payload
+ * will be a float vector.
+ *
+ * \sa packet_sync_bb for a hard decision version.
+ */
+ class DIGITAL_API packet_parse_f : virtual public sync_block
+ {
+ public:
+ typedef boost::shared_ptr<packet_parse_f> sptr;
+
+ /*!
+ * Make a packet header block using a given \p formatter.
+ *
+ * \param formatter The formatter class to use when reading the
+ * header.
+ * \param threshold How many bits in the access code the
+ * \p formatter can miss and still trigger a hit.
+ */
+ static sptr make(const packet_formatter_default::sptr &formatter,
+ unsigned int threshold=0);
+
+ /*!
+ * Sets the threshold level for the formatter when finding the
+ * access code. See packet_formatter_default::set_threshold
+ * for more details.
+ */
+ virtual void set_threshold(unsigned int thresh) = 0;
+
+ /*!
+ * Gets the access code detection threshold from the formatter.
+ */
+ virtual unsigned int threshold() const = 0;
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_PARSE_F_H */
diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt
index daa577f..9432082 100644
--- a/gr-digital/lib/CMakeLists.txt
+++ b/gr-digital/lib/CMakeLists.txt
@@ -83,6 +83,7 @@ list(APPEND digital_sources
glfsr_source_f_impl.cc
hdlc_deframer_bp_impl.cc
hdlc_framer_pb_impl.cc
+ header_buffer.cc
header_payload_demux_impl.cc
kurtotic_equalizer_cc_impl.cc
lms_dd_equalizer_cc_impl.cc
@@ -106,6 +107,11 @@ list(APPEND digital_sources
ofdm_sampler_impl.cc
ofdm_serializer_vcc_impl.cc
ofdm_sync_sc_cfb_impl.cc
+ packet_formatter_default.cc
+ packet_formatter_counter.cc
+ packet_format_async_impl.cc
+ packet_parse_b_impl.cc
+ packet_parse_f_impl.cc
packet_header_default.cc
packet_header_ofdm.cc
packet_headergenerator_bb_impl.cc
@@ -189,3 +195,37 @@ if(ENABLE_STATIC_LIBS)
ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "digital_devel" # .lib
file
)
endif(ENABLE_STATIC_LIBS)
+
+
+########################################################################
+# QA C++ Code for gr-blocks
+########################################################################
+if(ENABLE_TESTING)
+ include(GrTest)
+
+ include_directories(
+ ${GR_DIGITAL_INCLUDE_DIRS}
+ ${CPPUNIT_INCLUDE_DIRS})
+ link_directories(${CPPUNIT_LIBRARY_DIRS})
+
+ list(APPEND test_gr_digital_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/test_gr_digital.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_digital.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/qa_packet_formatters.cc
+ )
+
+ add_executable(test-gr-digital ${test_gr_digital_sources})
+
+ list(APPEND GR_TEST_TARGET_DEPS test-gr-digital gnuradio-digital)
+
+ target_link_libraries(
+ test-gr-digital
+ gnuradio-runtime
+ gnuradio-digital
+ ${Boost_LIBRARIES}
+ ${CPPUNIT_LIBRARIES}
+ ${LOG4CPP_LIBRARIES}
+ )
+
+ GR_ADD_TEST(test_gr_digital test-gr-digital)
+endif(ENABLE_TESTING)
diff --git a/gr-digital/lib/header_buffer.cc b/gr-digital/lib/header_buffer.cc
new file mode 100644
index 0000000..8cb0b17
--- /dev/null
+++ b/gr-digital/lib/header_buffer.cc
@@ -0,0 +1,208 @@
+/* -*- c++ -*- */
+/* Copyright 2015 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 <string.h>
+#include <algorithm>
+#include <stdexcept>
+#include <volk/volk.h>
+#include <gnuradio/digital/header_buffer.h>
+
+namespace gr {
+ namespace digital {
+
+ header_buffer::header_buffer(uint8_t *bytes_out)
+ {
+ d_offset = 0;
+ d_buffer = bytes_out;
+ }
+
+ header_buffer::~header_buffer()
+ {
+ }
+
+ size_t
+ header_buffer::length() const
+ {
+ if(d_buffer)
+ return d_offset;
+ else
+ return d_input.size();
+ }
+
+ const uint8_t*
+ header_buffer::header() const
+ {
+ return d_buffer;
+ }
+
+ void
+ header_buffer::add_field8(uint8_t data, int len, bool be)
+ {
+ int nbytes = len/8;
+ if(d_buffer) {
+ memcpy(&d_buffer[d_offset], &data, nbytes);
+ d_offset += nbytes;
+ }
+ }
+
+ void
+ header_buffer::add_field16(uint16_t data, int len, bool be)
+ {
+ int nbytes = len/8;
+ if(d_buffer) {
+ uint16_t x = data;
+ if(!be) {
+ volk_16u_byteswap(&x, 1);
+ x = x >> (16-len);
+ }
+ memcpy(&d_buffer[d_offset], &x, nbytes);
+ d_offset += nbytes;
+ }
+ }
+
+ void
+ header_buffer::add_field32(uint32_t data, int len, bool be)
+ {
+ int nbytes = len/8;
+ if(d_buffer) {
+ uint32_t x = data;
+ if(!be) {
+ volk_32u_byteswap(&x, 1);
+ x = x >> (32-len);
+ }
+ memcpy(&d_buffer[d_offset], &x, nbytes);
+ d_offset += nbytes;
+ }
+ }
+
+ void
+ header_buffer::add_field64(uint64_t data, int len, bool be)
+ {
+ int nbytes = len/8;
+ if(d_buffer) {
+ uint64_t x = data;
+ if(!be) {
+ volk_64u_byteswap(&x, 1);
+ x = x >> (64-len);
+ }
+ memcpy(&d_buffer[d_offset], &x, nbytes);
+ d_offset += nbytes;
+ }
+ }
+
+ void
+ header_buffer::insert_bit(int bit)
+ {
+ 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)
+ {
+ if(len > 8) {
+ throw std::runtime_error("header_buffer::extract_field for "
+ "uint8_t length must be <= 8");
+ }
+
+ uint8_t field = 0x00;
+ std::vector<bool>::iterator itr;
+ for(itr = d_input.begin()+pos; itr != d_input.begin()+pos+len; itr++) {
+ field = (field << 1) | ((*itr) & 0x1);
+ }
+
+ return field;
+ }
+
+ uint16_t
+ header_buffer::extract_field16(int pos, int len, bool be)
+ {
+ if(len > 16) {
+ throw std::runtime_error("header_buffer::extract_field for "
+ "uint16_t length must be <= 16");
+ }
+
+ uint16_t field = 0x0000;
+ std::vector<bool>::iterator itr;
+ for(itr = d_input.begin()+pos; itr != d_input.begin()+pos+len; itr++) {
+ field = (field << 1) | ((*itr) & 0x1);
+ }
+
+ if(be) {
+ volk_16u_byteswap(&field, 1);
+ }
+
+ return field;
+ }
+
+ uint32_t
+ header_buffer::extract_field32(int pos, int len, bool be)
+ {
+ if(len > 32) {
+ throw std::runtime_error("header_buffer::extract_field for "
+ "uint32_t length must be <= 32");
+ }
+
+ uint32_t field = 0x00000000;
+ std::vector<bool>::iterator itr;
+ for(itr = d_input.begin()+pos; itr != d_input.begin()+pos+len; itr++) {
+ field = (field << 1) | ((*itr) & 0x1);
+ }
+
+ if(be) {
+ volk_32u_byteswap(&field, 1);
+ }
+
+ return field;
+ }
+
+ uint64_t
+ header_buffer::extract_field64(int pos, int len, bool be)
+ {
+ if(len > 64) {
+ throw std::runtime_error("header_buffer::extract_field for "
+ "uint64_t length must be <= 64");
+ }
+
+ uint64_t field = 0x0000000000000000;
+ std::vector<bool>::iterator itr;
+ for(itr = d_input.begin()+pos; itr != d_input.begin()+pos+len; itr++) {
+ field = (field << 1) | ((*itr) & 0x1);
+ }
+
+ if(be) {
+ volk_64u_byteswap(&field, 1);
+ }
+
+ return field;
+ }
+
+ } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/lib/packet_format_async_impl.cc
b/gr-digital/lib/packet_format_async_impl.cc
new file mode 100644
index 0000000..2f1ccdc
--- /dev/null
+++ b/gr-digital/lib/packet_format_async_impl.cc
@@ -0,0 +1,94 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 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/io_signature.h>
+#include "packet_format_async_impl.h"
+#include <stdio.h>
+
+namespace gr {
+ namespace digital {
+
+ packet_format_async::sptr
+ packet_format_async::make(const packet_formatter_default::sptr &formatter)
+ {
+ return gnuradio::get_initial_sptr
+ (new packet_format_async_impl(formatter));
+ }
+
+ packet_format_async_impl::packet_format_async_impl(const
packet_formatter_default::sptr &formatter)
+ : block("packet_format_async",
+ io_signature::make(0, 0, 0),
+ io_signature::make(0, 0, 0))
+ {
+ d_formatter = formatter;
+
+ d_in_port = pmt::mp("in");
+ d_hdr_port = pmt::mp("header");
+ d_pld_port = pmt::mp("payload");
+
+ message_port_register_in(d_in_port);
+ message_port_register_out(d_hdr_port);
+ message_port_register_out(d_pld_port);
+
+ set_msg_handler(d_in_port,
+ boost::bind(&packet_format_async_impl::append, this ,_1)
);
+ }
+
+ packet_format_async_impl::~packet_format_async_impl()
+ {
+ }
+
+ void
+ packet_format_async_impl::append(pmt::pmt_t msg)
+ {
+ // extract input pdu
+ pmt::pmt_t meta(pmt::car(msg));
+ pmt::pmt_t input(pmt::cdr(msg));
+ pmt::pmt_t header, output;
+
+ size_t pkt_len = 0;
+ const uint8_t* bytes_in = pmt::u8vector_elements(input, pkt_len);
+
+ // Pad the payload with 0's
+ uint8_t* payload = (uint8_t*)volk_malloc(pkt_len*sizeof(uint8_t),
+ volk_get_alignment());
+ memcpy(payload, bytes_in, pkt_len*sizeof(uint8_t));
+ output = pmt::init_u8vector(pkt_len, payload);
+ volk_free(payload);
+
+ // Build the header from the input, metadata, and formatter
+ d_formatter->format(pkt_len, bytes_in, header, meta);
+
+ // Package and publish
+ pmt::pmt_t hdr_pdu = pmt::cons(meta, header);
+ pmt::pmt_t pld_pdu = pmt::cons(meta, output);
+ message_port_pub(d_hdr_port, hdr_pdu);
+ message_port_pub(d_pld_port, pld_pdu);
+ }
+
+ } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/swig/packet_header.i
b/gr-digital/lib/packet_format_async_impl.h
similarity index 50%
copy from gr-digital/swig/packet_header.i
copy to gr-digital/lib/packet_format_async_impl.h
index 7c06d19..2792a25 100644
--- a/gr-digital/swig/packet_header.i
+++ b/gr-digital/lib/packet_format_async_impl.h
@@ -1,34 +1,50 @@
/* -*- c++ -*- */
/*
- * Copyright 2012 Free Software Foundation, Inc.
- *
+ * Copyright 2015 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.
*/
-%template(packet_header_default_sptr)
boost::shared_ptr<gr::digital::packet_header_default>;
-%pythoncode %{
-packet_header_default_sptr.__repr__ = lambda self: "<packet_header_default>"
-packet_header_default = packet_header_default .make;
-%}
+#ifndef INCLUDED_DIGITAL_PACKET_FORMAT_ASYNC_IMPL_H
+#define INCLUDED_DIGITAL_PACKET_FORMAT_ASYNC_IMPL_H
-%template(packet_header_ofdm_sptr)
boost::shared_ptr<gr::digital::packet_header_ofdm>;
-%pythoncode %{
-packet_header_ofdm_sptr.__repr__ = lambda self: "<packet_header_ofdm>"
-packet_header_ofdm = packet_header_ofdm .make;
-%}
+#include <gnuradio/digital/packet_format_async.h>
+namespace gr {
+ namespace digital {
+
+ class packet_format_async_impl
+ : public packet_format_async
+ {
+ private:
+ packet_formatter_default::sptr d_formatter;
+
+ pmt::pmt_t d_in_port;
+ pmt::pmt_t d_hdr_port, d_pld_port;
+
+ void append(pmt::pmt_t msg);
+
+ public:
+ packet_format_async_impl(const packet_formatter_default::sptr
&formatter);
+ ~packet_format_async_impl();
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_FORMAT_ASYNC_IMPL_H */
diff --git a/gr-digital/lib/packet_formatter_counter.cc
b/gr-digital/lib/packet_formatter_counter.cc
new file mode 100644
index 0000000..494f514
--- /dev/null
+++ b/gr-digital/lib/packet_formatter_counter.cc
@@ -0,0 +1,126 @@
+/* -*- c++ -*- */
+/* Copyright 2014 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 <iostream>
+#include <iomanip>
+#include <string.h>
+#include <volk/volk.h>
+#include <gnuradio/digital/packet_formatter_counter.h>
+#include <gnuradio/digital/header_buffer.h>
+#include <gnuradio/math.h>
+
+namespace gr {
+ namespace digital {
+
+ packet_formatter_counter::sptr
+ packet_formatter_counter::make(const std::string &access_code, int bps)
+ {
+ return packet_formatter_counter::sptr
+ (new packet_formatter_counter(access_code, bps));
+ }
+
+ packet_formatter_counter::packet_formatter_counter(const std::string
&access_code, int bps)
+ : packet_formatter_default(access_code)
+ {
+ d_bps = bps;
+ d_counter = 0;
+ }
+
+ packet_formatter_counter::~packet_formatter_counter()
+ {
+ }
+
+ bool
+ packet_formatter_counter::format(int nbytes_in,
+ const unsigned char *input,
+ pmt::pmt_t &output,
+ pmt::pmt_t &info)
+
+ {
+ uint8_t* bytes_out = (uint8_t*)volk_malloc(header_nbytes(),
+ volk_get_alignment());
+
+ header_buffer header(bytes_out);
+ header.add_field64(d_access_code, d_access_code_len);
+ header.add_field16((uint16_t)(nbytes_in));
+ header.add_field16((uint16_t)(nbytes_in));
+ header.add_field16((uint16_t)(d_bps));
+ header.add_field16((uint16_t)(d_counter));
+
+ // Package output data into a PMT vector
+ output = pmt::init_u8vector(header_nbytes(), bytes_out);
+
+ // Creating the output pmt copies data; free our own here.
+ volk_free(bytes_out);
+
+ d_counter++;
+
+ return true;
+ }
+
+ size_t
+ packet_formatter_counter::header_nbits() const
+ {
+ return d_access_code_len + 8*4*sizeof(uint16_t);
+ }
+
+ size_t
+ packet_formatter_counter::header_nbytes() const
+ {
+ return d_access_code_len/8 + 4*sizeof(uint16_t);
+ }
+
+ bool
+ packet_formatter_counter::header_ok()
+ {
+ // confirm that two copies of header info are identical
+ uint16_t len0 = d_hdr_reg.extract_field16(0);
+ uint16_t len1 = d_hdr_reg.extract_field16(16);
+ return (len0 ^ len1) == 0;
+ }
+
+ int
+ packet_formatter_counter::header_payload()
+ {
+ uint16_t len = d_hdr_reg.extract_field16(0);
+ uint16_t bps = d_hdr_reg.extract_field16(32);
+ uint16_t counter = d_hdr_reg.extract_field16(48);
+
+ d_bps = bps;
+
+ d_info = pmt::make_dict();
+ d_info = pmt::dict_add(d_info, pmt::intern("skip samps"),
+ pmt::from_long(d_count));
+ d_info = pmt::dict_add(d_info, pmt::intern("payload bits"),
+ pmt::from_long(8*len));
+ d_info = pmt::dict_add(d_info, pmt::intern("bps"),
+ pmt::from_long(bps));
+ d_info = pmt::dict_add(d_info, pmt::intern("counter"),
+ pmt::from_long(counter));
+ return static_cast<int>(len);
+ }
+
+ } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/lib/packet_formatter_default.cc
b/gr-digital/lib/packet_formatter_default.cc
new file mode 100644
index 0000000..66f4795
--- /dev/null
+++ b/gr-digital/lib/packet_formatter_default.cc
@@ -0,0 +1,319 @@
+/* -*- c++ -*- */
+/* Copyright 2014-2015 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 <iostream>
+#include <string.h>
+#include <volk/volk.h>
+#include <gnuradio/digital/packet_formatter_default.h>
+#include <gnuradio/math.h>
+
+namespace gr {
+ namespace digital {
+
+ packet_formatter_default::sptr
+ packet_formatter_default::make(const std::string &access_code)
+ {
+ return packet_formatter_default::sptr
+ (new packet_formatter_default(access_code));
+ }
+
+ packet_formatter_default::packet_formatter_default(const std::string
&access_code)
+ {
+ if(!set_access_code(access_code)) {
+ throw std::runtime_error("packet_formatter_default: Setting access
code failed");
+ }
+
+ d_count = 0;
+ d_pkt_len = 0;
+ enter_search();
+ d_threshold = 0;
+ d_data_reg = 0;
+ d_bps = 1; // set in child classes that use this
+ }
+
+ packet_formatter_default::~packet_formatter_default()
+ {
+ }
+
+ bool
+ packet_formatter_default::set_access_code(const std::string &access_code)
+ {
+ d_access_code_len = access_code.length(); // # of bits in the
access code
+
+ //if((access_code.size() % 8 != 0) || (access_code.size() > 64)) {
+ if(access_code.size() > 64) {
+ return false;
+ }
+
+ // set len top bits to 1.
+ d_mask = ((~0ULL) >> (64 - d_access_code_len));
+
+ d_access_code = 0;
+ for(unsigned i = 0; i < d_access_code_len; i++) {
+ d_access_code = (d_access_code << 1) | (access_code[i] & 1);
+ }
+
+ return true;
+ }
+
+ unsigned long long
+ packet_formatter_default::access_code() const
+ {
+ return d_access_code;
+ }
+
+ void
+ packet_formatter_default::set_threshold(unsigned int thresh)
+ {
+ if(d_threshold > d_access_code_len)
+ throw std::runtime_error("packet_formatter_default: Cannot set
threshold " \
+ "larger than the access code length.");
+ d_threshold = thresh;
+ }
+
+ unsigned int
+ packet_formatter_default::threshold() const
+ {
+ return d_threshold;
+ }
+
+ bool
+ packet_formatter_default::format(int nbytes_in,
+ const unsigned char *input,
+ pmt::pmt_t &output,
+ pmt::pmt_t &info)
+ {
+ uint8_t* bytes_out = (uint8_t*)volk_malloc(header_nbytes(),
+ volk_get_alignment());
+
+ header_buffer header(bytes_out);
+ header.add_field64(d_access_code, d_access_code_len);
+ header.add_field16((uint16_t)(nbytes_in));
+ header.add_field16((uint16_t)(nbytes_in));
+
+ // Package output data into a PMT vector
+ output = pmt::init_u8vector(header_nbytes(), bytes_out);
+
+ // Creating the output pmt copies data; free our own here.
+ volk_free(bytes_out);
+
+ return true;
+ }
+
+ bool
+ packet_formatter_default::parse(int nbits_in,
+ const unsigned char *input,
+ std::vector<pmt::pmt_t> &info)
+ {
+ int count = 0;
+
+ while(count < nbits_in) {
+ switch(d_state) {
+ case STATE_SYNC_SEARCH: // Look for the access code correlation
+
+ while(count < nbits_in) {
+ // shift in new data
+ d_data_reg = (d_data_reg << 1) | ((input[count++]) & 0x1);
+ d_count++;
+
+ // compute hamming distance between desired access code and
current data
+ uint64_t wrong_bits = 0;
+ uint64_t nwrong = d_threshold+1;
+
+ wrong_bits = (d_data_reg ^ d_access_code) & d_mask;
+ volk_64u_popcnt(&nwrong, wrong_bits);
+
+ if(nwrong <= d_threshold) {
+ enter_have_sync();
+ break;
+ }
+ }
+ break;
+
+ case STATE_HAVE_SYNC:
+ while(count < nbits_in) { // Shift bits one at a time into header
+ d_hdr_reg.insert_bit(input[count++]);
+ d_count++;
+
+ if(d_hdr_reg.length() == (header_nbits()-d_access_code_len)) {
+ // we have a full header, check to see if it has been received
properly
+ if(header_ok()) {
+ int payload_len = header_payload();
+ enter_have_header(payload_len);
+ info.push_back(d_info);
+ }
+ else {
+ enter_search(); // bad header
+ }
+ break;
+ }
+ }
+ break;
+
+ case STATE_HAVE_HEADER:
+ while(count < nbits_in) {
+ if(d_pkt_count < d_pkt_len/d_bps) {
+ count++;
+ d_pkt_count++;
+ }
+ if(d_pkt_count == d_pkt_len/d_bps) {
+ enter_search();
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ bool
+ packet_formatter_default::parse_soft(int nbits_in,
+ const float *input,
+ std::vector<pmt::pmt_t> &info)
+ {
+ int count = 0;
+
+ while(count < nbits_in) {
+ switch(d_state) {
+ case STATE_SYNC_SEARCH: // Look for the access code correlation
+
+ while(count < nbits_in) {
+ // shift in new data
+ d_data_reg = (d_data_reg << 1) |
(gr::branchless_binary_slicer(input[count++]) & 0x1);
+ d_count++;
+
+ // compute hamming distance between desired access code and
current data
+ uint64_t wrong_bits = 0;
+ uint64_t nwrong = d_threshold+1;
+
+ wrong_bits = (d_data_reg ^ d_access_code) & d_mask;
+ volk_64u_popcnt(&nwrong, wrong_bits);
+
+ if(nwrong <= d_threshold) {
+ enter_have_sync();
+ break;
+ }
+ }
+ break;
+
+ case STATE_HAVE_SYNC:
+ while(count < nbits_in) { // Shift bits one at a time into header
+ d_hdr_reg.insert_bit(gr::branchless_binary_slicer(input[count++]));
+ d_count++;
+
+ if(d_hdr_reg.length() == (header_nbits()-d_access_code_len)) {
+ // we have a full header, check to see if it has been received
properly
+ if(header_ok()) {
+ int payload_len = header_payload();
+ enter_have_header(8*payload_len);
+ info.push_back(d_info);
+ }
+ else {
+ enter_search(); // bad header
+ }
+ break;
+ }
+ }
+ break;
+
+ case STATE_HAVE_HEADER:
+ while(count < nbits_in) {
+ if(d_pkt_count < d_pkt_len/d_bps) {
+ count++;
+ d_pkt_count++;
+ }
+ if(d_pkt_count == d_pkt_len/d_bps) {
+ enter_search();
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return true;
+ }
+
+
+ size_t
+ packet_formatter_default::header_nbits() const
+ {
+ return d_access_code_len + 8*2*sizeof(uint16_t);
+ }
+
+ size_t
+ packet_formatter_default::header_nbytes() const
+ {
+ return d_access_code_len/8 + 2*sizeof(uint16_t);
+ }
+
+ inline void
+ packet_formatter_default::enter_search()
+ {
+ d_state = STATE_SYNC_SEARCH;
+ }
+
+ inline void
+ packet_formatter_default::enter_have_sync()
+ {
+ d_state = STATE_HAVE_SYNC;
+ d_hdr_reg.clear_input();
+ }
+
+ inline void
+ packet_formatter_default::enter_have_header(int payload_len)
+ {
+ d_state = STATE_HAVE_HEADER;
+ d_pkt_len = payload_len;
+ d_pkt_count = 0;
+ d_count = 0;
+ }
+
+ bool
+ packet_formatter_default::header_ok()
+ {
+ // confirm that two copies of header info are identical
+ uint16_t len0 = d_hdr_reg.extract_field16(0, 16);
+ uint16_t len1 = d_hdr_reg.extract_field16(16, 16);
+ return (len0 ^ len1) == 0;
+ }
+
+ int
+ packet_formatter_default::header_payload()
+ {
+ uint16_t len = d_hdr_reg.extract_field16(0, 16);
+
+ d_info = pmt::make_dict();
+ d_info = pmt::dict_add(d_info, pmt::intern("skip samps"),
+ pmt::from_long(d_count));
+ d_info = pmt::dict_add(d_info, pmt::intern("payload bits"),
+ pmt::from_long(8*len));
+ return static_cast<int>(len);
+ }
+
+ } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/lib/packet_header_ofdm.cc
b/gr-digital/lib/packet_header_ofdm.cc
index 7a95586..22d62df 100644
--- a/gr-digital/lib/packet_header_ofdm.cc
+++ b/gr-digital/lib/packet_header_ofdm.cc
@@ -1,18 +1,18 @@
/* -*- c++ -*- */
/* Copyright 2012 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,
@@ -148,4 +148,3 @@ namespace gr {
} /* namespace digital */
} /* namespace gr */
-
diff --git a/gr-digital/lib/packet_parse_b_impl.cc
b/gr-digital/lib/packet_parse_b_impl.cc
new file mode 100644
index 0000000..01f1653
--- /dev/null
+++ b/gr-digital/lib/packet_parse_b_impl.cc
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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 "packet_parse_b_impl.h"
+#include <gnuradio/io_signature.h>
+#include <stdexcept>
+#include <volk/volk.h>
+#include <iostream>
+
+namespace gr {
+ namespace digital {
+
+ packet_parse_b::sptr
+ packet_parse_b::make(const packet_formatter_default::sptr &formatter,
+ unsigned int threshold)
+ {
+ return gnuradio::get_initial_sptr
+ (new packet_parse_b_impl(formatter, threshold));
+ }
+
+
+ packet_parse_b_impl::packet_parse_b_impl(const
packet_formatter_default::sptr &formatter,
+ unsigned int threshold)
+ : sync_block("packet_parse_b",
+ io_signature::make(1, 1, sizeof(char)),
+ io_signature::make(0, 0, 0))
+ {
+ d_formatter = formatter;
+ set_threshold(threshold);
+
+ d_out_port = pmt::mp("info");
+ message_port_register_out(d_out_port);
+ }
+
+ packet_parse_b_impl::~packet_parse_b_impl()
+ {
+ }
+
+ void
+ packet_parse_b_impl::set_threshold(unsigned int thresh)
+ {
+ d_formatter->set_threshold(thresh);
+ }
+
+
+ unsigned int
+ packet_parse_b_impl::threshold() const
+ {
+ return d_formatter->threshold();
+ }
+
+ int
+ packet_parse_b_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const unsigned char *in = (const unsigned char*)input_items[0];
+
+ std::vector<pmt::pmt_t> info;
+ d_formatter->parse(noutput_items, in, info);
+
+ for(size_t i = 0; i < info.size(); i++) {
+ message_port_pub(d_out_port, info[i]);
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/lib/packet_parse_b_impl.h
b/gr-digital/lib/packet_parse_b_impl.h
new file mode 100644
index 0000000..4263ca4
--- /dev/null
+++ b/gr-digital/lib/packet_parse_b_impl.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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 INCLUDED_DIGITAL_PACKET_PARSE_B_IMPL_H
+#define INCLUDED_DIGITAL_PACKET_PARSE_B_IMPL_H
+
+#include <gnuradio/digital/packet_parse_b.h>
+
+namespace gr {
+ namespace digital {
+
+ class packet_parse_b_impl : public packet_parse_b
+ {
+ private:
+ packet_formatter_default::sptr d_formatter;
+ pmt::pmt_t d_out_port;
+
+ public:
+ packet_parse_b_impl(const packet_formatter_default::sptr &formatter,
+ unsigned int threshold=0);
+ ~packet_parse_b_impl();
+
+ void set_threshold(unsigned int thresh);
+ unsigned int threshold() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_PARSE_B_IMPL_H */
diff --git a/gr-digital/lib/packet_parse_f_impl.cc
b/gr-digital/lib/packet_parse_f_impl.cc
new file mode 100644
index 0000000..8a45e11
--- /dev/null
+++ b/gr-digital/lib/packet_parse_f_impl.cc
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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 "packet_parse_f_impl.h"
+#include <gnuradio/io_signature.h>
+#include <stdexcept>
+#include <volk/volk.h>
+#include <iostream>
+
+namespace gr {
+ namespace digital {
+
+ packet_parse_f::sptr
+ packet_parse_f::make(const packet_formatter_default::sptr &formatter,
+ unsigned int threshold)
+ {
+ return gnuradio::get_initial_sptr
+ (new packet_parse_f_impl(formatter, threshold));
+ }
+
+
+ packet_parse_f_impl::packet_parse_f_impl(const
packet_formatter_default::sptr &formatter,
+ unsigned int threshold)
+ : sync_block("packet_parse_f",
+ io_signature::make(1, 1, sizeof(float)),
+ io_signature::make(0, 0, 0))
+ {
+ d_formatter = formatter;
+ set_threshold(threshold);
+
+ d_out_port = pmt::mp("info");
+ message_port_register_out(d_out_port);
+ }
+
+ packet_parse_f_impl::~packet_parse_f_impl()
+ {
+ }
+
+ void
+ packet_parse_f_impl::set_threshold(unsigned int thresh)
+ {
+ d_formatter->set_threshold(thresh);
+ }
+
+ unsigned int
+ packet_parse_f_impl::threshold() const
+ {
+ return d_formatter->threshold();
+ }
+
+ int
+ packet_parse_f_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const float *in = (const float*)input_items[0];
+
+ std::vector<pmt::pmt_t> info;
+ d_formatter->parse_soft(noutput_items, in, info);
+
+ for(size_t i = 0; i < info.size(); i++) {
+ message_port_pub(d_out_port, info[i]);
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace digital */
+} /* namespace gr */
diff --git a/gr-digital/lib/packet_parse_f_impl.h
b/gr-digital/lib/packet_parse_f_impl.h
new file mode 100644
index 0000000..2c38975
--- /dev/null
+++ b/gr-digital/lib/packet_parse_f_impl.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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 INCLUDED_DIGITAL_PACKET_PARSE_F_IMPL_H
+#define INCLUDED_DIGITAL_PACKET_PARSE_F_IMPL_H
+
+#include <gnuradio/digital/packet_parse_f.h>
+
+namespace gr {
+ namespace digital {
+
+ class packet_parse_f_impl : public packet_parse_f
+ {
+ private:
+ packet_formatter_default::sptr d_formatter;
+ pmt::pmt_t d_out_port;
+
+ public:
+ packet_parse_f_impl(const packet_formatter_default::sptr &formatter,
+ unsigned int threshold=0);
+ ~packet_parse_f_impl();
+
+ void set_threshold(unsigned int thresh);
+ unsigned int threshold() const;
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_PARSE_F_IMPL_H */
diff --git a/gr-digital/swig/packet_header.i b/gr-digital/lib/qa_digital.cc
similarity index 57%
copy from gr-digital/swig/packet_header.i
copy to gr-digital/lib/qa_digital.cc
index 7c06d19..ad88de5 100644
--- a/gr-digital/swig/packet_header.i
+++ b/gr-digital/lib/qa_digital.cc
@@ -1,34 +1,39 @@
-/* -*- c++ -*- */
/*
- * Copyright 2012 Free Software Foundation, Inc.
- *
+ * Copyright 2014 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.
*/
-%template(packet_header_default_sptr)
boost::shared_ptr<gr::digital::packet_header_default>;
-%pythoncode %{
-packet_header_default_sptr.__repr__ = lambda self: "<packet_header_default>"
-packet_header_default = packet_header_default .make;
-%}
+/*
+ * This class gathers together all the test cases for the gr-digital
+ * directory into a single test suite. As you create new test cases,
+ * add them here.
+ */
+
+#include "qa_digital.h"
+#include "qa_packet_formatters.h"
+
+CppUnit::TestSuite *
+qa_digital::suite()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite("gr-digital");
-%template(packet_header_ofdm_sptr)
boost::shared_ptr<gr::digital::packet_header_ofdm>;
-%pythoncode %{
-packet_header_ofdm_sptr.__repr__ = lambda self: "<packet_header_ofdm>"
-packet_header_ofdm = packet_header_ofdm .make;
-%}
+ s->addTest(qa_packet_formatters::suite());
+ return s;
+}
diff --git a/gr-digital/swig/packet_header.i b/gr-digital/lib/qa_digital.h
similarity index 59%
copy from gr-digital/swig/packet_header.i
copy to gr-digital/lib/qa_digital.h
index 7c06d19..c5f3592 100644
--- a/gr-digital/swig/packet_header.i
+++ b/gr-digital/lib/qa_digital.h
@@ -1,34 +1,38 @@
/* -*- c++ -*- */
/*
- * Copyright 2012 Free Software Foundation, Inc.
- *
+ * Copyright 2014 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.
*/
-%template(packet_header_default_sptr)
boost::shared_ptr<gr::digital::packet_header_default>;
-%pythoncode %{
-packet_header_default_sptr.__repr__ = lambda self: "<packet_header_default>"
-packet_header_default = packet_header_default .make;
-%}
+#ifndef _QA_GR_DIGITAL_H_
+#define _QA_GR_DIGITAL_H_
-%template(packet_header_ofdm_sptr)
boost::shared_ptr<gr::digital::packet_header_ofdm>;
-%pythoncode %{
-packet_header_ofdm_sptr.__repr__ = lambda self: "<packet_header_ofdm>"
-packet_header_ofdm = packet_header_ofdm .make;
-%}
+#include <gnuradio/attributes.h>
+#include <cppunit/TestSuite.h>
+//! collect all the tests for the gr-digital directory
+
+class __GR_ATTR_EXPORT qa_digital
+{
+ public:
+ //! return suite of tests for all of gr-digital directory
+ static CppUnit::TestSuite *suite();
+};
+
+#endif /* _QA_GR_DIGITAL_H_ */
diff --git a/gr-digital/lib/qa_packet_formatters.cc
b/gr-digital/lib/qa_packet_formatters.cc
new file mode 100644
index 0000000..a36c55a
--- /dev/null
+++ b/gr-digital/lib/qa_packet_formatters.cc
@@ -0,0 +1,417 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2013 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 <gnuradio/attributes.h>
+
+#include <stdio.h>
+#include <cmath>
+#include <volk/volk.h>
+#include <gnuradio/expj.h>
+#include <cppunit/TestAssert.h>
+
+#include "qa_packet_formatters.h"
+#include <gnuradio/digital/packet_formatter_counter.h>
+#include <gnuradio/digital/packet_formatter_default.h>
+#include <gnuradio/blocks/unpack_k_bits.h>
+
+void
+qa_packet_formatters::test_default_format()
+{
+ static const int N = 4800;
+ int upper8 = (N >> 8) & 0xFF;
+ int lower8 = N & 0xFF;
+
+ std::string ac = "1010101010101010"; //0xAAAA
+ unsigned char *data = (unsigned char*)volk_malloc(N*sizeof(unsigned char),
+ volk_get_alignment());
+ srand (time(NULL));
+ for(unsigned int i = 0; i < N; i++) {
+ data[i] = rand() % 256;
+ }
+
+ gr::digital::packet_formatter_default::sptr formatter;
+ formatter = gr::digital::packet_formatter_default::make(ac);
+
+ pmt::pmt_t output;
+ pmt::pmt_t info = pmt::make_dict();
+
+ bool ret = formatter->format(N, data, output, info);
+ size_t length = pmt::length(output);
+
+ CPPUNIT_ASSERT(ret);
+ CPPUNIT_ASSERT_EQUAL(length, formatter->header_nbytes());
+ CPPUNIT_ASSERT_EQUAL(8*length, formatter->header_nbits());
+
+ // Test access code formatted correctly
+ unsigned char h0 = pmt::u8vector_ref(output, 0);
+ unsigned char h1 = pmt::u8vector_ref(output, 1);
+ CPPUNIT_ASSERT_EQUAL(0xAA, (int)h0);
+ CPPUNIT_ASSERT_EQUAL(0xAA, (int)h1);
+
+ // Test upper and lower portion of length field, repeated twice
+ unsigned char h2 = pmt::u8vector_ref(output, 2);
+ unsigned char h3 = pmt::u8vector_ref(output, 3);
+ unsigned char h4 = pmt::u8vector_ref(output, 4);
+ unsigned char h5 = pmt::u8vector_ref(output, 5);
+ CPPUNIT_ASSERT_EQUAL(upper8, (int)h2);
+ CPPUNIT_ASSERT_EQUAL(lower8, (int)h3);
+ CPPUNIT_ASSERT_EQUAL(upper8, (int)h4);
+ CPPUNIT_ASSERT_EQUAL(lower8, (int)h5);
+
+ volk_free(data);
+}
+
+
+void
+qa_packet_formatters::test_default_parse()
+{
+ static const int nbytes = 106;
+ static const int nbits = 8*nbytes;
+ unsigned char *bytes = (unsigned char*)volk_malloc(nbytes*sizeof(unsigned
char),
+ volk_get_alignment());
+ unsigned char *bits = (unsigned char*)volk_malloc(nbits*sizeof(unsigned
char),
+ volk_get_alignment());
+
+ srand(time(NULL));
+
+ // Fill bytes with random values
+ for(unsigned int i = 0; i < nbytes; i++) {
+ bytes[i] = rand() % 256;
+ }
+
+ int index = 0;
+ bytes[index+0] = 0xAA;
+ bytes[index+1] = 0xAA;
+ bytes[index+2] = 0x00;
+ bytes[index+3] = 0x64;
+ bytes[index+4] = 0x00;
+ bytes[index+5] = 0x64;
+
+ gr::blocks::kernel::unpack_k_bits unpacker =
gr::blocks::kernel::unpack_k_bits(8);
+ unpacker.unpack(bits, bytes, nbytes);
+
+ std::string ac = "1010101010101010"; //0xAAAA
+ gr::digital::packet_formatter_default::sptr formatter;
+ formatter = gr::digital::packet_formatter_default::make(ac);
+ formatter->set_threshold(0);
+
+ std::vector<pmt::pmt_t> info;
+ bool ret = formatter->parse(nbits, bits, info);
+
+ CPPUNIT_ASSERT(ret);
+ CPPUNIT_ASSERT_EQUAL((size_t)1, info.size());
+
+ pmt::pmt_t dict = info[0];
+ int payload_bits = pmt::to_long(pmt::dict_ref(dict, pmt::intern("payload
bits"),
+ pmt::PMT_NIL));
+ int skip_samps = pmt::to_long(pmt::dict_ref(dict, pmt::intern("skip samps"),
+ pmt::PMT_NIL));
+
+ int hdr_bits = (int)formatter->header_nbits();
+ int expected_bits = nbits - hdr_bits;
+ int expected_skip = index * 8 + hdr_bits;
+ CPPUNIT_ASSERT_EQUAL(expected_bits, payload_bits);
+ CPPUNIT_ASSERT_EQUAL(expected_skip, skip_samps);
+
+ volk_free(bytes);
+ volk_free(bits);
+}
+
+void
+qa_packet_formatters::test_default_parse_soft()
+{
+ static const int nbytes = 106;
+ static const int nbits = 8*nbytes;
+ unsigned char *bytes = (unsigned char*)volk_malloc(nbytes*sizeof(unsigned
char),
+ volk_get_alignment());
+ unsigned char *bits = (unsigned char*)volk_malloc(nbits*sizeof(unsigned
char),
+ volk_get_alignment());
+ float *soft = (float*)volk_malloc(nbits*sizeof(float),
+ volk_get_alignment());
+
+ srand(time(NULL));
+
+ // Fill bytes with random values
+ for(unsigned int i = 0; i < nbytes; i++) {
+ bytes[i] = rand() % 256;
+ }
+
+ int index = 0;
+ bytes[index+0] = 0xAA;
+ bytes[index+1] = 0xAA;
+ bytes[index+2] = 0x00;
+ bytes[index+3] = 0x64;
+ bytes[index+4] = 0x00;
+ bytes[index+5] = 0x64;
+
+ gr::blocks::kernel::unpack_k_bits unpacker =
gr::blocks::kernel::unpack_k_bits(8);
+ unpacker.unpack(bits, bytes, nbytes);
+
+ // Convert bits to +/-1 and add a small bit of noise
+ std::vector<float> sub(nbits, 1.0f);
+ volk_8i_s32f_convert_32f(soft, (const int8_t*)bits, 1.0, nbits);
+ volk_32f_s32f_multiply_32f(soft, soft, 2.0, nbits);
+ volk_32f_x2_subtract_32f(soft, soft, &sub[0], nbits);
+ for(unsigned int i = 0; i < nbits; i++) {
+ soft[i] += 0.1 * ((float)rand() / (float)RAND_MAX - 0.5);
+ }
+
+ std::string ac = "1010101010101010"; //0xAAAA
+ gr::digital::packet_formatter_default::sptr formatter;
+ formatter = gr::digital::packet_formatter_default::make(ac);
+ formatter->set_threshold(0);
+
+ std::vector<pmt::pmt_t> info;
+ bool ret = formatter->parse_soft(nbits, soft, info);
+
+ CPPUNIT_ASSERT(ret);
+ CPPUNIT_ASSERT_EQUAL((size_t)1, info.size());
+
+ pmt::pmt_t dict = info[0];
+ int payload_bits = pmt::to_long(pmt::dict_ref(dict, pmt::intern("payload
bits"),
+ pmt::PMT_NIL));
+ int skip_samps = pmt::to_long(pmt::dict_ref(dict, pmt::intern("skip samps"),
+ pmt::PMT_NIL));
+
+ int hdr_bits = (int)formatter->header_nbits();
+ int expected_bits = nbits - hdr_bits;
+ int expected_skip = index * 8 + hdr_bits;
+ CPPUNIT_ASSERT_EQUAL(expected_bits, payload_bits);
+ CPPUNIT_ASSERT_EQUAL(expected_skip, skip_samps);
+
+ volk_free(bytes);
+ volk_free(bits);
+}
+
+
+void
+qa_packet_formatters::test_counter_format()
+{
+ static const int N = 4800;
+ int upper8 = (N >> 8) & 0xFF;
+ int lower8 = N & 0xFF;
+
+ std::string ac = "1010101010101010"; //0xAAAA
+ unsigned char *data = (unsigned char*)volk_malloc(N*sizeof(unsigned char),
+ volk_get_alignment());
+ srand (time(NULL));
+ for(unsigned int i = 0; i < N; i++) {
+ data[i] = rand() % 256;
+ }
+
+ uint16_t expected_bps = 2;
+ gr::digital::packet_formatter_counter::sptr formatter;
+ formatter = gr::digital::packet_formatter_counter::make(ac, expected_bps);
+
+ pmt::pmt_t output;
+ pmt::pmt_t info = pmt::make_dict();
+
+ bool ret = formatter->format(N, data, output, info);
+ size_t length = pmt::length(output);
+
+ CPPUNIT_ASSERT(ret);
+ CPPUNIT_ASSERT_EQUAL(length, formatter->header_nbytes());
+ CPPUNIT_ASSERT_EQUAL(8*length, formatter->header_nbits());
+
+ // Test access code formatted correctly
+ unsigned char h0 = pmt::u8vector_ref(output, 0);
+ unsigned char h1 = pmt::u8vector_ref(output, 1);
+ CPPUNIT_ASSERT_EQUAL(0xAA, (int)h0);
+ CPPUNIT_ASSERT_EQUAL(0xAA, (int)h1);
+
+ // Test upper and lower portion of length field, repeated twice
+ unsigned char h2 = pmt::u8vector_ref(output, 2);
+ unsigned char h3 = pmt::u8vector_ref(output, 3);
+ unsigned char h4 = pmt::u8vector_ref(output, 4);
+ unsigned char h5 = pmt::u8vector_ref(output, 5);
+ CPPUNIT_ASSERT_EQUAL(upper8, (int)h2);
+ CPPUNIT_ASSERT_EQUAL(lower8, (int)h3);
+ CPPUNIT_ASSERT_EQUAL(upper8, (int)h4);
+ CPPUNIT_ASSERT_EQUAL(lower8, (int)h5);
+
+ uint16_t h6 = (uint16_t)pmt::u8vector_ref(output, 6);
+ uint16_t h7 = (uint16_t)pmt::u8vector_ref(output, 7);
+ uint16_t bps = ((h6 << 8) & 0xFF00) | (h7 & 0x00FF);
+ CPPUNIT_ASSERT_EQUAL(expected_bps, bps);
+
+ uint16_t h8 = pmt::u8vector_ref(output, 8);
+ uint16_t h9 = pmt::u8vector_ref(output, 9);
+ uint16_t counter = ((h8 << 8) & 0xFF00) | (h9 & 0x00FF);
+ CPPUNIT_ASSERT_EQUAL((uint16_t)0, counter);
+
+ // Run another format to increment the counter to 1 and test.
+ ret = formatter->format(N, data, output, info);
+ h8 = pmt::u8vector_ref(output, 8);
+ h9 = pmt::u8vector_ref(output, 9);
+ counter = ((h8 << 8) & 0xFF00) | (h9 & 0x00FF);
+ CPPUNIT_ASSERT_EQUAL((uint16_t)1, counter);
+
+ volk_free(data);
+}
+
+
+void
+qa_packet_formatters::test_counter_parse()
+{
+ static const int nbytes = 110;
+ static const int nbits = 8*nbytes;
+ unsigned char *bytes = (unsigned char*)volk_malloc(nbytes*sizeof(unsigned
char),
+ volk_get_alignment());
+ unsigned char *bits = (unsigned char*)volk_malloc(nbits*sizeof(unsigned
char),
+ volk_get_alignment());
+
+ srand(time(NULL));
+
+ // Fill bytes with random values
+ for(unsigned int i = 0; i < nbytes; i++) {
+ bytes[i] = rand() % 256;
+ }
+
+ int index = 0;
+ bytes[index+0] = 0xAA;
+ bytes[index+1] = 0xAA;
+ bytes[index+2] = 0x00;
+ bytes[index+3] = 0x64;
+ bytes[index+4] = 0x00;
+ bytes[index+5] = 0x64;
+ bytes[index+6] = 0x00;
+ bytes[index+7] = 0x02;
+ bytes[index+8] = 0x00;
+ bytes[index+9] = 0x00;
+
+ gr::blocks::kernel::unpack_k_bits unpacker =
gr::blocks::kernel::unpack_k_bits(8);
+ unpacker.unpack(bits, bytes, nbytes);
+
+ uint16_t expected_bps = 2;
+ std::string ac = "1010101010101010"; //0xAAAA
+ gr::digital::packet_formatter_counter::sptr formatter;
+ formatter = gr::digital::packet_formatter_counter::make(ac, expected_bps);
+ formatter->set_threshold(0);
+
+ std::vector<pmt::pmt_t> info;
+ bool ret = formatter->parse(nbits, bits, info);
+
+ CPPUNIT_ASSERT(ret);
+ CPPUNIT_ASSERT_EQUAL((size_t)1, info.size());
+
+ pmt::pmt_t dict = info[0];
+ int payload_bits = pmt::to_long(pmt::dict_ref(dict, pmt::intern("payload
bits"),
+ pmt::PMT_NIL));
+ int skip_samps = pmt::to_long(pmt::dict_ref(dict, pmt::intern("skip samps"),
+ pmt::PMT_NIL));
+ int bps = pmt::to_long(pmt::dict_ref(dict, pmt::intern("bps"),
+ pmt::PMT_NIL));
+ int counter = pmt::to_long(pmt::dict_ref(dict, pmt::intern("counter"),
+ pmt::PMT_NIL));
+
+ int hdr_bits = (int)formatter->header_nbits();
+ int expected_bits = nbits - hdr_bits;
+ int expected_skip = index * 8 + hdr_bits;
+ CPPUNIT_ASSERT_EQUAL(expected_bits, payload_bits);
+ CPPUNIT_ASSERT_EQUAL(expected_skip, skip_samps);
+ CPPUNIT_ASSERT_EQUAL(expected_bps, (uint16_t)bps);
+ CPPUNIT_ASSERT_EQUAL(0, counter);
+
+ volk_free(bytes);
+ volk_free(bits);
+}
+
+void
+qa_packet_formatters::test_counter_parse_soft()
+{
+ static const int nbytes = 110;
+ static const int nbits = 8*nbytes;
+ unsigned char *bytes = (unsigned char*)volk_malloc(nbytes*sizeof(unsigned
char),
+ volk_get_alignment());
+ unsigned char *bits = (unsigned char*)volk_malloc(nbits*sizeof(unsigned
char),
+ volk_get_alignment());
+ float *soft = (float*)volk_malloc(nbits*sizeof(float),
+ volk_get_alignment());
+
+ srand(time(NULL));
+
+ // Fill bytes with random values
+ for(unsigned int i = 0; i < nbytes; i++) {
+ bytes[i] = rand() % 256;
+ }
+
+ int index = 0;
+ bytes[index+0] = 0xAA;
+ bytes[index+1] = 0xAA;
+ bytes[index+2] = 0x00;
+ bytes[index+3] = 0x64;
+ bytes[index+4] = 0x00;
+ bytes[index+5] = 0x64;
+ bytes[index+6] = 0x00;
+ bytes[index+7] = 0x02;
+ bytes[index+8] = 0x00;
+ bytes[index+9] = 0x00;
+
+ gr::blocks::kernel::unpack_k_bits unpacker =
gr::blocks::kernel::unpack_k_bits(8);
+ unpacker.unpack(bits, bytes, nbytes);
+
+ // Convert bits to +/-1 and add a small bit of noise
+ std::vector<float> sub(nbits, 1.0f);
+ volk_8i_s32f_convert_32f(soft, (const int8_t*)bits, 1.0, nbits);
+ volk_32f_s32f_multiply_32f(soft, soft, 2.0, nbits);
+ volk_32f_x2_subtract_32f(soft, soft, &sub[0], nbits);
+ for(unsigned int i = 0; i < nbits; i++) {
+ soft[i] += 0.1 * ((float)rand() / (float)RAND_MAX - 0.5);
+ }
+
+ uint16_t expected_bps = 2;
+ std::string ac = "1010101010101010"; //0xAAAA
+ gr::digital::packet_formatter_counter::sptr formatter;
+ formatter = gr::digital::packet_formatter_counter::make(ac, expected_bps);
+ formatter->set_threshold(0);
+
+ std::vector<pmt::pmt_t> info;
+ bool ret = formatter->parse_soft(nbits, soft, info);
+
+ CPPUNIT_ASSERT(ret);
+ CPPUNIT_ASSERT_EQUAL((size_t)1, info.size());
+
+ pmt::pmt_t dict = info[0];
+ int payload_bits = pmt::to_long(pmt::dict_ref(dict, pmt::intern("payload
bits"),
+ pmt::PMT_NIL));
+ int skip_samps = pmt::to_long(pmt::dict_ref(dict, pmt::intern("skip samps"),
+ pmt::PMT_NIL));
+ int bps = pmt::to_long(pmt::dict_ref(dict, pmt::intern("bps"),
+ pmt::PMT_NIL));
+ int counter = pmt::to_long(pmt::dict_ref(dict, pmt::intern("counter"),
+ pmt::PMT_NIL));
+
+ int hdr_bits = (int)formatter->header_nbits();
+ int expected_bits = nbits - hdr_bits;
+ int expected_skip = index * 8 + hdr_bits;
+ CPPUNIT_ASSERT_EQUAL(expected_bits, payload_bits);
+ CPPUNIT_ASSERT_EQUAL(expected_skip, skip_samps);
+ CPPUNIT_ASSERT_EQUAL(expected_bps, (uint16_t)bps);
+ CPPUNIT_ASSERT_EQUAL(0, counter);
+
+ volk_free(bytes);
+ volk_free(bits);
+}
diff --git a/gr-digital/lib/qa_packet_formatters.h
b/gr-digital/lib/qa_packet_formatters.h
new file mode 100644
index 0000000..83ed270
--- /dev/null
+++ b/gr-digital/lib/qa_packet_formatters.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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_PACKET_FORMATTERS_H_
+#define _QA_DIGITAL_PACKET_FORMATTERS_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_packet_formatters : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_packet_formatters);
+ CPPUNIT_TEST(test_default_format);
+ CPPUNIT_TEST(test_default_parse);
+ CPPUNIT_TEST(test_default_parse_soft);
+ CPPUNIT_TEST(test_counter_format);
+ CPPUNIT_TEST(test_counter_parse);
+ CPPUNIT_TEST(test_counter_parse_soft);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void test_default_format();
+ void test_default_parse();
+ void test_default_parse_soft();
+ void test_counter_format();
+ void test_counter_parse();
+ void test_counter_parse_soft();
+};
+
+#endif /* _QA_DIGITAL_PACKET_FORMATTERS_H_ */
diff --git a/gr-digital/swig/packet_header.i b/gr-digital/lib/test_gr_digital.cc
similarity index 53%
copy from gr-digital/swig/packet_header.i
copy to gr-digital/lib/test_gr_digital.cc
index 7c06d19..7a6049d 100644
--- a/gr-digital/swig/packet_header.i
+++ b/gr-digital/lib/test_gr_digital.cc
@@ -1,34 +1,48 @@
/* -*- c++ -*- */
/*
- * Copyright 2012 Free Software Foundation, Inc.
- *
+ * Copyright 2014 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.
*/
-%template(packet_header_default_sptr)
boost::shared_ptr<gr::digital::packet_header_default>;
-%pythoncode %{
-packet_header_default_sptr.__repr__ = lambda self: "<packet_header_default>"
-packet_header_default = packet_header_default .make;
-%}
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
-%template(packet_header_ofdm_sptr)
boost::shared_ptr<gr::digital::packet_header_ofdm>;
-%pythoncode %{
-packet_header_ofdm_sptr.__repr__ = lambda self: "<packet_header_ofdm>"
-packet_header_ofdm = packet_header_ofdm .make;
-%}
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/XmlOutputter.h>
+#include <gnuradio/unittests.h>
+#include "qa_digital.h"
+#include <iostream>
+#include <fstream>
+
+int
+main(int argc, char **argv)
+{
+ CppUnit::TextTestRunner runner;
+ std::ofstream xmlfile(get_unittest_path("digital.xml").c_str());
+ CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(),
xmlfile);
+
+ runner.addTest(qa_digital::suite());
+ runner.setOutputter(xmlout);
+
+ bool was_successful = runner.run("", false);
+
+ return was_successful ? 0 : 1;
+}
diff --git a/gr-digital/python/digital/qa_packet_format.py
b/gr-digital/python/digital/qa_packet_format.py
new file mode 100644
index 0000000..40bc144
--- /dev/null
+++ b/gr-digital/python/digital/qa_packet_format.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# Copyright 2014 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.
+#
+
+import random, time, struct
+import pmt
+from gnuradio import gr, gr_unittest, digital, blocks
+from gnuradio.digital import packet_utils
+
+class test_packet_format_fb(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_packet_format_async_default(self):
+ ac = packet_utils.default_access_code
+ formatter = digital.packet_formatter_default(ac)
+
+ pkt_header = digital.packet_format_async(formatter)
+ snk_hdr = blocks.message_debug()
+ snk_pld = blocks.message_debug()
+
+ self.tb.msg_connect(pkt_header, 'header', snk_hdr, 'store')
+ self.tb.msg_connect(pkt_header, 'payload', snk_pld, 'store')
+
+
+ send_str = "Hello World"
+ send_pmt = pmt.make_u8vector(len(send_str), ord(' '))
+ for i in range(len(send_str)):
+ pmt.u8vector_set(send_pmt, i, ord(send_str[i]))
+ msg = pmt.cons(pmt.PMT_NIL, send_pmt)
+
+ port = pmt.intern("in")
+ pkt_header.to_basic_block()._post(port, msg)
+
+ self.tb.start()
+ while (snk_hdr.num_messages() < 1) and (snk_pld.num_messages() < 1):
+ time.sleep(0.1)
+ self.tb.stop()
+ self.tb.wait()
+
+ result_hdr_pmt = pmt.cdr(snk_hdr.get_message(0))
+ result_pld_pmt = pmt.cdr(snk_pld.get_message(0))
+
+ result_hdr = pmt.u8vector_elements(result_hdr_pmt)
+ result_pld = pmt.u8vector_elements(result_pld_pmt)
+ header = "".join([chr(r) for r in result_hdr])
+ payload = "".join([chr(r) for r in result_pld])
+
+ access_code =
packet_utils.conv_1_0_string_to_packed_binary_string(packet_utils.default_access_code)[0]
+ rx_access_code = header[0:len(access_code)]
+
+ length = len(send_str)
+ rx_length = struct.unpack_from("!H", header, len(access_code))[0]
+
+ self.assertEqual(access_code, rx_access_code)
+ self.assertEqual(length, rx_length)
+ self.assertEqual(length, len(payload))
+ self.assertEqual(send_str, payload[0:length])
+
+
+ def test_packet_format_async_counter(self):
+ bps = 2
+ ac = packet_utils.default_access_code
+ formatter = digital.packet_formatter_counter(ac, 2)
+
+ pkt_header = digital.packet_format_async(formatter)
+ snk_hdr = blocks.message_debug()
+ snk_pld = blocks.message_debug()
+
+ self.tb.msg_connect(pkt_header, 'header', snk_hdr, 'store')
+ self.tb.msg_connect(pkt_header, 'payload', snk_pld, 'store')
+
+
+ send_str = "Hello World" + 1000*"xxx"
+ send_pmt = pmt.make_u8vector(len(send_str), ord(' '))
+ for i in range(len(send_str)):
+ pmt.u8vector_set(send_pmt, i, ord(send_str[i]))
+ msg = pmt.cons(pmt.PMT_NIL, send_pmt)
+
+ port = pmt.intern("in")
+ pkt_header.to_basic_block()._post(port, msg)
+
+ self.tb.start()
+ while (snk_hdr.num_messages() < 1) and (snk_pld.num_messages() < 1):
+ time.sleep(0.1)
+ self.tb.stop()
+ self.tb.wait()
+
+ result_hdr_pmt = pmt.cdr(snk_hdr.get_message(0))
+ result_pld_pmt = pmt.cdr(snk_pld.get_message(0))
+
+ result_hdr = pmt.u8vector_elements(result_hdr_pmt)
+ result_pld = pmt.u8vector_elements(result_pld_pmt)
+ header = "".join([chr(r) for r in result_hdr])
+ payload = "".join([chr(r) for r in result_pld])
+
+ access_code =
packet_utils.conv_1_0_string_to_packed_binary_string(packet_utils.default_access_code)[0]
+ rx_access_code = header[0:len(access_code)]
+
+ length = len(send_str)
+ rx_length = struct.unpack_from("!H", header, len(access_code))[0]
+ rx_bps = struct.unpack_from("!H", header, len(access_code)+4)[0]
+ rx_counter = struct.unpack_from("!H", header, len(access_code)+6)[0]
+
+ self.assertEqual(access_code, rx_access_code)
+ self.assertEqual(length, rx_length)
+ self.assertEqual(bps, rx_bps)
+ self.assertEqual(0, rx_counter)
+ self.assertEqual(length, len(payload))
+ self.assertEqual(send_str, payload[0:length])
+
+if __name__ == '__main__':
+ gr_unittest.run(test_packet_format_fb, "test_packet_format_fb.xml")
diff --git a/gr-digital/swig/CMakeLists.txt b/gr-digital/swig/CMakeLists.txt
index d87b7e9..2f00dc1 100644
--- a/gr-digital/swig/CMakeLists.txt
+++ b/gr-digital/swig/CMakeLists.txt
@@ -30,6 +30,7 @@ set(GR_SWIG_INCLUDE_DIRS
${GR_FFT_INCLUDE_DIRS}
${GR_FILTER_INCLUDE_DIRS}
${GNURADIO_RUNTIME_SWIG_INCLUDE_DIRS}
+ ${VOLK_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i
index d7a3b81..b0fe202 100644
--- a/gr-digital/swig/digital_swig.i
+++ b/gr-digital/swig/digital_swig.i
@@ -100,6 +100,11 @@
#include "gnuradio/digital/ofdm_sampler.h"
#include "gnuradio/digital/ofdm_serializer_vcc.h"
#include "gnuradio/digital/ofdm_sync_sc_cfb.h"
+#include "gnuradio/digital/packet_formatter_default.h"
+#include "gnuradio/digital/packet_formatter_counter.h"
+#include "gnuradio/digital/packet_format_async.h"
+#include "gnuradio/digital/packet_parse_b.h"
+#include "gnuradio/digital/packet_parse_f.h"
#include "gnuradio/digital/packet_header_default.h"
#include "gnuradio/digital/packet_header_ofdm.h"
#include "gnuradio/digital/packet_headergenerator_bb.h"
@@ -181,6 +186,11 @@
%include "gnuradio/digital/ofdm_sampler.h"
%include "gnuradio/digital/ofdm_serializer_vcc.h"
%include "gnuradio/digital/ofdm_sync_sc_cfb.h"
+%include "gnuradio/digital/packet_formatter_default.h"
+%include "gnuradio/digital/packet_formatter_counter.h"
+%include "gnuradio/digital/packet_format_async.h"
+%include "gnuradio/digital/packet_parse_b.h"
+%include "gnuradio/digital/packet_parse_f.h"
%include "gnuradio/digital/packet_header_default.h"
%include "gnuradio/digital/packet_header_ofdm.h"
%include "gnuradio/digital/packet_headergenerator_bb.h"
@@ -249,6 +259,9 @@ GR_SWIG_BLOCK_MAGIC2(digital, ofdm_mapper_bcv);
GR_SWIG_BLOCK_MAGIC2(digital, ofdm_sampler);
GR_SWIG_BLOCK_MAGIC2(digital, ofdm_serializer_vcc);
GR_SWIG_BLOCK_MAGIC2(digital, ofdm_sync_sc_cfb);
+GR_SWIG_BLOCK_MAGIC2(digital, packet_format_async);
+GR_SWIG_BLOCK_MAGIC2(digital, packet_parse_b);
+GR_SWIG_BLOCK_MAGIC2(digital, packet_parse_f);
GR_SWIG_BLOCK_MAGIC2(digital, packet_headergenerator_bb);
GR_SWIG_BLOCK_MAGIC2(digital, packet_headerparser_b);
GR_SWIG_BLOCK_MAGIC2(digital, packet_sink);
diff --git a/gr-digital/swig/packet_header.i b/gr-digital/swig/packet_header.i
index 7c06d19..86ee8d9 100644
--- a/gr-digital/swig/packet_header.i
+++ b/gr-digital/swig/packet_header.i
@@ -1,19 +1,19 @@
/* -*- c++ -*- */
/*
* Copyright 2012 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,
@@ -32,3 +32,15 @@ packet_header_ofdm_sptr.__repr__ = lambda self:
"<packet_header_ofdm>"
packet_header_ofdm = packet_header_ofdm .make;
%}
+%template(packet_formatter_default_sptr)
boost::shared_ptr<gr::digital::packet_formatter_default>;
+%pythoncode %{
+packet_formatter_default_sptr.__repr__ = lambda self:
"<packet_formatter_default>"
+packet_formatter_default = packet_formatter_default .make;
+%}
+
+
+%template(packet_formatter_counter_sptr)
boost::shared_ptr<gr::digital::packet_formatter_counter>;
+%pythoncode %{
+packet_formatter_counter_sptr.__repr__ = lambda self:
"<packet_formatter_counter>"
+packet_formatter_counter = packet_formatter_counter .make;
+%}
- [Commit-gnuradio] [gnuradio] 08/24: digital: fixing PFB clock sync block handling of tags., (continued)
- [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, 2016/06/13
- [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 <=
- [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