summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--cmake/Modules/GnuradioConfig.cmake.in1
-rw-r--r--docs/doxygen/Doxyfile.in5
-rw-r--r--docs/doxygen/other/group_defs.dox1
-rw-r--r--gnuradio-runtime/python/gnuradio/__init__.py1
-rw-r--r--gr-pdu/CMakeLists.txt57
-rw-r--r--gr-pdu/docs/CMakeLists.txt11
-rw-r--r--gr-pdu/docs/README.pdu12
-rw-r--r--gr-pdu/examples/CMakeLists.txt12
-rw-r--r--gr-pdu/gnuradio-pdu.pc.in11
-rw-r--r--gr-pdu/grc/CMakeLists.txt11
-rw-r--r--gr-pdu/grc/pdu_pdu_split.block.yml28
-rw-r--r--gr-pdu/include/gnuradio/pdu/CMakeLists.txt17
-rw-r--r--gr-pdu/include/gnuradio/pdu/api.h21
-rw-r--r--gr-pdu/include/gnuradio/pdu/pdu.h30
-rw-r--r--gr-pdu/include/gnuradio/pdu/pdu_split.h46
-rw-r--r--gr-pdu/lib/CMakeLists.txt49
-rw-r--r--gr-pdu/lib/gnuradio-pdu.rc.in43
-rw-r--r--gr-pdu/lib/pdu.cc48
-rw-r--r--gr-pdu/lib/pdu_split_impl.cc61
-rw-r--r--gr-pdu/lib/pdu_split_impl.h34
-rw-r--r--gr-pdu/python/pdu/CMakeLists.txt34
-rw-r--r--gr-pdu/python/pdu/__init__.py23
-rw-r--r--gr-pdu/python/pdu/bindings/CMakeLists.txt17
-rw-r--r--gr-pdu/python/pdu/bindings/docstrings/pdu_pydoc_template.h30
-rw-r--r--gr-pdu/python/pdu/bindings/docstrings/pdu_split_pydoc_template.h24
-rw-r--r--gr-pdu/python/pdu/bindings/pdu_python.cc47
-rw-r--r--gr-pdu/python/pdu/bindings/pdu_split_python.cc45
-rw-r--r--gr-pdu/python/pdu/bindings/python_bindings.cc42
-rw-r--r--gr-pdu/python/pdu/qa_pdu_split.py93
30 files changed, 855 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f9097fcbc0..b65e37bec9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -481,6 +481,7 @@ add_subdirectory(gr-digital)
add_subdirectory(gr-dtv)
add_subdirectory(gr-audio)
add_subdirectory(gr-channels)
+add_subdirectory(gr-pdu)
add_subdirectory(gr-qtgui)
add_subdirectory(gr-trellis)
add_subdirectory(gr-uhd)
diff --git a/cmake/Modules/GnuradioConfig.cmake.in b/cmake/Modules/GnuradioConfig.cmake.in
index 957d2c81c3..4e8ba901e2 100644
--- a/cmake/Modules/GnuradioConfig.cmake.in
+++ b/cmake/Modules/GnuradioConfig.cmake.in
@@ -83,6 +83,7 @@ set(GR_COMPONENTS
dtv
audio
channels
+ pdu
qtgui
trellis
uhd
diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in
index 7c2e3fc608..b02047d3b6 100644
--- a/docs/doxygen/Doxyfile.in
+++ b/docs/doxygen/Doxyfile.in
@@ -161,6 +161,8 @@ STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@/gnuradio-runtime/include \
@CMAKE_BINARY_DIR@/gr-fft/include \
@CMAKE_SOURCE_DIR@/gr-filter/include \
@CMAKE_BINARY_DIR@/gr-filter/include \
+ @CMAKE_SOURCE_DIR@/gr-pdu/include \
+ @CMAKE_BINARY_DIR@/gr-pdu/include \
@CMAKE_SOURCE_DIR@/gr-qtgui/include \
@CMAKE_BINARY_DIR@/gr-qtgui/include \
@CMAKE_SOURCE_DIR@/gr-trellis/include \
@@ -725,6 +727,7 @@ EXCLUDE = @abs_top_builddir@/cmake/msvc \
@abs_top_builddir@/gnuradio-runtime/python/gnuradio/gr/gr_threading.py \
@abs_top_builddir@/gnuradio-runtime/python/gnuradio/gr/gr_threading_23.py \
@abs_top_builddir@/gnuradio-runtime/python/gnuradio/gr/gr_threading_24.py \
+ @abs_top_builddir@/gr-pdu/doc \
@abs_top_builddir@/gr-trellis/doc \
@abs_top_builddir@/grc \
@abs_top_builddir@/_CPack_Packages \
@@ -760,6 +763,8 @@ EXCLUDE = @abs_top_builddir@/cmake/msvc \
@abs_top_builddir@/gr-filter/lib \
@abs_top_srcdir@/gr-fft/lib \
@abs_top_builddir@/gr-fft/lib \
+ @abs_top_srcdir@/gr-pdu/lib \
+ @abs_top_builddir@/gr-pdu/lib \
@abs_top_srcdir@/gr-qtgui/lib \
@abs_top_builddir@/gr-qtgui/lib \
@abs_top_srcdir@/gr-trellis/lib \
diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox
index 7ec67bde23..f0283404e2 100644
--- a/docs/doxygen/other/group_defs.dox
+++ b/docs/doxygen/other/group_defs.dox
@@ -43,6 +43,7 @@
/*! \defgroup ofdm_blk OFDM Blocks */
/*! \defgroup packet_operators_blk Packet/Frame Operators */
/*! \defgroup peak_detectors_blk Peak Detectors */
+/*! \defgroup pdu_blk PDU Operators */
/*! \defgroup qtgui_blk QT Graphical Interfaces */
/*! \defgroup resamplers_blk Resamplers */
/*! \defgroup stream_operators_blk Streams Operators */
diff --git a/gnuradio-runtime/python/gnuradio/__init__.py b/gnuradio-runtime/python/gnuradio/__init__.py
index db7bc5cc48..2326c3ab89 100644
--- a/gnuradio-runtime/python/gnuradio/__init__.py
+++ b/gnuradio-runtime/python/gnuradio/__init__.py
@@ -56,4 +56,5 @@ if path.endswith(path_ending):
__path__.append(os.path.join(build_path, 'gr-fec', 'python'))
__path__.append(os.path.join(build_path, 'gr-utils'))
__path__.append(os.path.join(build_path, 'gr-uhd', 'python'))
+ __path__.append(os.path.join(build_path, 'gr-pdu', 'python'))
__path__.append(os.path.join(build_path, 'gr-zeromq', 'python'))
diff --git a/gr-pdu/CMakeLists.txt b/gr-pdu/CMakeLists.txt
new file mode 100644
index 0000000000..d0a94d6f91
--- /dev/null
+++ b/gr-pdu/CMakeLists.txt
@@ -0,0 +1,57 @@
+# Copyright 2021 Jacob Gilbert
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# Setup dependencies
+########################################################################
+include(GrBoost)
+
+########################################################################
+# Register component
+########################################################################
+include(GrComponent)
+GR_REGISTER_COMPONENT("gr-pdu" ENABLE_GR_PDU
+ Boost_FOUND
+ ENABLE_GNURADIO_RUNTIME
+ ENABLE_GR_BLOCKS
+ ENABLE_GR_FILTER
+ )
+
+########################################################################
+# Begin conditional configuration
+########################################################################
+if(ENABLE_GR_PDU)
+
+########################################################################
+# Add subdirectories
+########################################################################
+add_subdirectory(include/gnuradio/pdu)
+add_subdirectory(lib)
+if(ENABLE_PYTHON)
+ add_subdirectory(python/pdu)
+ if(ENABLE_EXAMPLES)
+ add_subdirectory(examples)
+ endif(ENABLE_EXAMPLES)
+endif(ENABLE_PYTHON)
+if(ENABLE_GRC)
+ add_subdirectory(grc)
+endif(ENABLE_GRC)
+
+########################################################################
+# Create Pkg Config File
+########################################################################
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-pdu.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-pdu.pc
+@ONLY)
+
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-pdu.pc
+ DESTINATION ${GR_LIBRARY_DIR}/pkgconfig
+)
+
+endif(ENABLE_GR_PDU)
diff --git a/gr-pdu/docs/CMakeLists.txt b/gr-pdu/docs/CMakeLists.txt
new file mode 100644
index 0000000000..6614de3719
--- /dev/null
+++ b/gr-pdu/docs/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright 2021 Jacob Gilbert
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+install(
+ FILES README.pdu
+ DESTINATION ${GR_PKG_DOC_DIR}
+)
diff --git a/gr-pdu/docs/README.pdu b/gr-pdu/docs/README.pdu
new file mode 100644
index 0000000000..f70b18648d
--- /dev/null
+++ b/gr-pdu/docs/README.pdu
@@ -0,0 +1,12 @@
+This is the GNU Radio PDU package. It contains signal processing
+blocks that operate on Protocol Data Unit format messages. Many
+such blocks are analogs of streaming API functionality. To use the
+network blocks, the Python namespace is in 'network', which is
+imported as:
+
+ from gnuradio import pdu
+
+A quick listing of the details can be found in Python after
+importing by using:
+
+ help(pdu)
diff --git a/gr-pdu/examples/CMakeLists.txt b/gr-pdu/examples/CMakeLists.txt
new file mode 100644
index 0000000000..c3f1df7c0d
--- /dev/null
+++ b/gr-pdu/examples/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright 2021 Jacob Gilbert
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+install(
+ FILES
+ DESTINATION ${GR_PKG_DATA_DIR}/examples/pdu
+)
+
diff --git a/gr-pdu/gnuradio-pdu.pc.in b/gr-pdu/gnuradio-pdu.pc.in
new file mode 100644
index 0000000000..825b41e807
--- /dev/null
+++ b/gr-pdu/gnuradio-pdu.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-pdu
+Description: GNU Radio blocks for PDU based processing
+Requires: gnuradio-runtime
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-pdu
+Cflags: -I${includedir}
diff --git a/gr-pdu/grc/CMakeLists.txt b/gr-pdu/grc/CMakeLists.txt
new file mode 100644
index 0000000000..d6ac0115b0
--- /dev/null
+++ b/gr-pdu/grc/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright 2021 Jacob Gilbert
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+install(FILES
+ pdu_pdu_split.block.yml
+ DESTINATION ${GRC_BLOCKS_DIR}
+)
diff --git a/gr-pdu/grc/pdu_pdu_split.block.yml b/gr-pdu/grc/pdu_pdu_split.block.yml
new file mode 100644
index 0000000000..1f9ca1a75f
--- /dev/null
+++ b/gr-pdu/grc/pdu_pdu_split.block.yml
@@ -0,0 +1,28 @@
+id: pdu_pdu_split
+label: PDU Split
+category: '[Core]/PDU'
+
+parameters:
+- id: pass_empty
+ label: Empty
+ dtype: enum
+ options: ['False', 'True']
+ option_labels: [Drop, Print]
+
+inputs:
+- domain: message
+ id: pdus
+
+outputs:
+- domain: message
+ id: dict
+ optional: true
+- domain: message
+ id: data
+ optional: true
+
+templates:
+ imports: from gnuradio import pdu
+ make: pdu.pdu_split(${pass_empty})
+
+file_format: 1
diff --git a/gr-pdu/include/gnuradio/pdu/CMakeLists.txt b/gr-pdu/include/gnuradio/pdu/CMakeLists.txt
new file mode 100644
index 0000000000..b007685797
--- /dev/null
+++ b/gr-pdu/include/gnuradio/pdu/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Copyright 2021 Jacob Gilbert
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# Install header files
+########################################################################
+install(FILES
+ api.h
+ pdu_split.h
+ pdu.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/pdu
+)
+
diff --git a/gr-pdu/include/gnuradio/pdu/api.h b/gr-pdu/include/gnuradio/pdu/api.h
new file mode 100644
index 0000000000..6f31dde8f3
--- /dev/null
+++ b/gr-pdu/include/gnuradio/pdu/api.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2021 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_PDU_API_H
+#define INCLUDED_PDU_API_H
+
+#include <gnuradio/attributes.h>
+
+#ifdef gnuradio_pdu_EXPORTS
+#define PDU_API __GR_ATTR_EXPORT
+#else
+#define PDU_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_PDU_API_H */
diff --git a/gr-pdu/include/gnuradio/pdu/pdu.h b/gr-pdu/include/gnuradio/pdu/pdu.h
new file mode 100644
index 0000000000..c6c0b4db3c
--- /dev/null
+++ b/gr-pdu/include/gnuradio/pdu/pdu.h
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 NTESS LLC.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+
+#ifndef INCLUDED_PDU_PORT_NAMES_H
+#define INCLUDED_PDU_PORT_NAMES_H
+
+#include <gnuradio/pdu/api.h>
+#include <pmt/pmt.h>
+
+namespace gr {
+namespace pdu {
+
+
+// static const PMT interned string getters
+PDU_API const pmt::pmt_t PMTCONSTSTR__data();
+PDU_API const pmt::pmt_t PMTCONSTSTR__dict();
+PDU_API const pmt::pmt_t PMTCONSTSTR__emit();
+PDU_API const pmt::pmt_t PMTCONSTSTR__msg();
+PDU_API const pmt::pmt_t PMTCONSTSTR__pdus();
+
+
+} // namespace pdu
+} // namespace gr
+
+#endif /* INCLUDED_PDU_PORT_NAMES_H */
diff --git a/gr-pdu/include/gnuradio/pdu/pdu_split.h b/gr-pdu/include/gnuradio/pdu/pdu_split.h
new file mode 100644
index 0000000000..8f4f3f91e2
--- /dev/null
+++ b/gr-pdu/include/gnuradio/pdu/pdu_split.h
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 NTESS LLC.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_PDU_PDU_SPLIT_H
+#define INCLUDED_PDU_PDU_SPLIT_H
+
+#include <gnuradio/block.h>
+#include <gnuradio/pdu/api.h>
+
+namespace gr {
+namespace pdu {
+
+/*!
+ * \brief Split PDU dict and data to separate ports
+ * \ingroup debug_tools_blk
+ * \ingroup pdu_blk
+ *
+ * Splits a PDU into its metadata dictionary and vector,
+ * outputs nothing if the input message is not a PDU. Useful for stripping metadata out
+ * for printing or saving.
+ *
+ */
+class PDU_API pdu_split : virtual public gr::block
+{
+public:
+ typedef std::shared_ptr<pdu_split> sptr;
+
+ /*!
+ * \brief Return a shared_ptr to a new instance of pdu::pdu_split.
+ *
+ * @param pass_empty_data - true to pass PDU vectors that are length 0
+ */
+ static sptr make(bool pass_empty_data = false);
+};
+
+} // namespace pdu
+} // namespace gr
+
+#endif /* INCLUDED_PDU_PDU_SPLIT_H */
diff --git a/gr-pdu/lib/CMakeLists.txt b/gr-pdu/lib/CMakeLists.txt
new file mode 100644
index 0000000000..72fb6a80f3
--- /dev/null
+++ b/gr-pdu/lib/CMakeLists.txt
@@ -0,0 +1,49 @@
+# Copyright 2021 Jacob Gilbert
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# Setup library
+########################################################################
+add_library(gnuradio-pdu
+ pdu_split_impl.cc
+ pdu.cc
+)
+
+#Add Windows DLL resource file if using MSVC
+if(MSVC)
+ include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake)
+
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-pdu.rc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-pdu.rc
+ @ONLY)
+
+ target_sources(gnuradio-pdu PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-pdu.rc
+ )
+endif(MSVC)
+
+target_link_libraries(gnuradio-pdu PUBLIC
+ gnuradio-runtime
+ gnuradio-blocks
+ gnuradio-filter
+)
+
+target_include_directories(gnuradio-pdu
+ PUBLIC $<INSTALL_INTERFACE:include>
+ PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
+ )
+
+
+# we need -no-as-needed or else -lgslcblas gets stripped out on newer version of gcc
+if(CMAKE_COMPILER_IS_GNUCC AND NOT APPLE)
+ SET_TARGET_PROPERTIES(gnuradio-pdu PROPERTIES LINK_FLAGS "-Wl,--no-as-needed")
+endif()
+
+if(BUILD_SHARED_LIBS)
+ GR_LIBRARY_FOO(gnuradio-pdu)
+endif()
diff --git a/gr-pdu/lib/gnuradio-pdu.rc.in b/gr-pdu/lib/gnuradio-pdu.rc.in
new file mode 100644
index 0000000000..eb050a0b68
--- /dev/null
+++ b/gr-pdu/lib/gnuradio-pdu.rc.in
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 Jacob Gilbert
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include <afxres.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@
+ PRODUCTVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@
+ FILEFLAGSMASK 0x3fL
+#ifndef NDEBUG
+ FILEFLAGS 0x0L
+#else
+ FILEFLAGS 0x1L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE VFT2_DRV_INSTALLABLE
+ BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "gnuradio-pdu"
+ VALUE "FileVersion", "@VERSION@"
+ VALUE "InternalName", "gnuradio-pdu.dll"
+ VALUE "LegalCopyright", "Licensed under GPLv3 or any later version"
+ VALUE "OriginalFilename", "gnuradio-pdu.dll"
+ VALUE "ProductName", "gnuradio-pdu"
+ VALUE "ProductVersion", "@VERSION@"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+ END
diff --git a/gr-pdu/lib/pdu.cc b/gr-pdu/lib/pdu.cc
new file mode 100644
index 0000000000..68d7dec3a4
--- /dev/null
+++ b/gr-pdu/lib/pdu.cc
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 NTESS LLC.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/pdu/pdu.h>
+#include <pmt/pmt.h>
+
+namespace gr {
+namespace pdu {
+
+
+const pmt::pmt_t PMTCONSTSTR__data()
+{
+ static const pmt::pmt_t val = pmt::mp("data");
+ return val;
+}
+const pmt::pmt_t PMTCONSTSTR__dict()
+{
+ static const pmt::pmt_t val = pmt::mp("dict");
+ return val;
+}
+const pmt::pmt_t PMTCONSTSTR__emit()
+{
+ static const pmt::pmt_t val = pmt::mp("emit");
+ return val;
+}
+const pmt::pmt_t PMTCONSTSTR__msg()
+{
+ static const pmt::pmt_t val = pmt::mp("msg");
+ return val;
+}
+const pmt::pmt_t PMTCONSTSTR__pdus()
+{
+ static const pmt::pmt_t val = pmt::mp("pdus");
+ return val;
+}
+
+
+} /* namespace pdu */
+} /* namespace gr */
diff --git a/gr-pdu/lib/pdu_split_impl.cc b/gr-pdu/lib/pdu_split_impl.cc
new file mode 100644
index 0000000000..491f00683c
--- /dev/null
+++ b/gr-pdu/lib/pdu_split_impl.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 NTESS LLC.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pdu_split_impl.h"
+#include <gnuradio/io_signature.h>
+#include <gnuradio/pdu/pdu.h>
+
+namespace gr {
+namespace pdu {
+
+pdu_split::sptr pdu_split::make(const bool pass_empty_data)
+{
+ return gnuradio::make_block_sptr<pdu_split_impl>(pass_empty_data);
+}
+
+pdu_split_impl::pdu_split_impl(const bool pass_empty_data)
+ : gr::block("pdu_split", io_signature::make(0, 0, 0), io_signature::make(0, 0, 0)),
+ d_pass_empty_data(pass_empty_data)
+{
+ message_port_register_in(PMTCONSTSTR__pdus());
+ set_msg_handler(PMTCONSTSTR__pdus(),
+ [this](pmt::pmt_t msg) { this->handle_pdu(msg); });
+ message_port_register_out(PMTCONSTSTR__dict());
+ message_port_register_out(PMTCONSTSTR__data());
+}
+
+pdu_split_impl::~pdu_split_impl() {}
+
+void pdu_split_impl::handle_pdu(pmt::pmt_t pdu)
+{
+ // make sure the data is a PDU
+ if (!(pmt::is_pdu(pdu))) {
+ GR_LOG_WARN(d_logger, "Message received is not a PDU, dropping");
+ return;
+ }
+
+ pmt::pmt_t meta = pmt::car(pdu);
+ pmt::pmt_t data = pmt::cdr(pdu);
+
+ if ((!pmt::equal(meta, pmt::PMT_NIL)) | d_pass_empty_data) {
+ message_port_pub(PMTCONSTSTR__dict(), meta);
+ }
+
+ if (pmt::length(data) | d_pass_empty_data) {
+ message_port_pub(PMTCONSTSTR__data(), data);
+ }
+}
+
+} /* namespace pdu */
+} /* namespace gr */
diff --git a/gr-pdu/lib/pdu_split_impl.h b/gr-pdu/lib/pdu_split_impl.h
new file mode 100644
index 0000000000..e927463dba
--- /dev/null
+++ b/gr-pdu/lib/pdu_split_impl.h
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2021 NTESS LLC.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#ifndef INCLUDED_PDU_PDU_SPLIT_IMPL_H
+#define INCLUDED_PDU_PDU_SPLIT_IMPL_H
+
+#include <gnuradio/pdu/pdu_split.h>
+
+namespace gr {
+namespace pdu {
+
+class pdu_split_impl : public pdu_split
+{
+private:
+ const bool d_pass_empty_data;
+
+public:
+ pdu_split_impl(const bool pass_empty_data);
+ ~pdu_split_impl();
+
+ void handle_pdu(pmt::pmt_t pdu);
+};
+
+} // namespace pdu
+} // namespace gr
+
+#endif /* INCLUDED_PDU_PDU_SPLIT_IMPL_H */
diff --git a/gr-pdu/python/pdu/CMakeLists.txt b/gr-pdu/python/pdu/CMakeLists.txt
new file mode 100644
index 0000000000..1a1bb25f8e
--- /dev/null
+++ b/gr-pdu/python/pdu/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright 2021 Jacob Gilbert
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+include(GrPython)
+
+GR_PYTHON_INSTALL(
+ FILES
+ __init__.py
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/pdu
+)
+
+########################################################################
+# Handle the unit tests
+########################################################################
+if(ENABLE_TESTING)
+ set(GR_TEST_TARGET_DEPS "")
+ set(GR_TEST_LIBRARY_DIRS "")
+ set(GR_TEST_PYTHON_DIRS
+ ${CMAKE_BINARY_DIR}/gnuradio-runtime/python
+ )
+ include(GrTest)
+ file(GLOB py_qa_test_files "qa_*.py")
+ foreach(py_qa_test_file ${py_qa_test_files})
+ get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
+ GR_ADD_TEST(${py_qa_test_name} ${QA_PYTHON_EXECUTABLE} -B ${py_qa_test_file})
+ endforeach(py_qa_test_file)
+endif(ENABLE_TESTING)
+
+add_subdirectory(bindings)
diff --git a/gr-pdu/python/pdu/__init__.py b/gr-pdu/python/pdu/__init__.py
new file mode 100644
index 0000000000..01e94a056c
--- /dev/null
+++ b/gr-pdu/python/pdu/__init__.py
@@ -0,0 +1,23 @@
+# Copyright 2021 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+#
+
+'''
+Blocks and utilities for PDU based processing.
+'''
+
+# The presence of this file turns this directory into a Python package
+import os
+
+try:
+ from .pdu_python import *
+except ImportError:
+ dirname, filename = os.path.split(os.path.abspath(__file__))
+ __path__.append(os.path.join(dirname, "bindings"))
+ from .pdu_python import *
+
+# import any pure python here
diff --git a/gr-pdu/python/pdu/bindings/CMakeLists.txt b/gr-pdu/python/pdu/bindings/CMakeLists.txt
new file mode 100644
index 0000000000..a6b3252af5
--- /dev/null
+++ b/gr-pdu/python/pdu/bindings/CMakeLists.txt
@@ -0,0 +1,17 @@
+include(GrPybind)
+
+########################################################################
+# Python Bindings
+########################################################################
+
+list(APPEND pdu_python_files
+ pdu_split_python.cc
+ pdu_python.cc
+ python_bindings.cc)
+
+GR_PYBIND_MAKE_CHECK_HASH(pdu
+ ../../..
+ gr::pdu
+ "${pdu_python_files}")
+
+install(TARGETS pdu_python DESTINATION ${GR_PYTHON_DIR}/gnuradio/pdu COMPONENT pythonapi)
diff --git a/gr-pdu/python/pdu/bindings/docstrings/pdu_pydoc_template.h b/gr-pdu/python/pdu/bindings/docstrings/pdu_pydoc_template.h
new file mode 100644
index 0000000000..b1840f5574
--- /dev/null
+++ b/gr-pdu/python/pdu/bindings/docstrings/pdu_pydoc_template.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, pdu, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+
+static const char* __doc_gr_pdu_PMTCONSTSTR__data = R"doc()doc";
+
+
+static const char* __doc_gr_pdu_PMTCONSTSTR__dict = R"doc()doc";
+
+
+static const char* __doc_gr_pdu_PMTCONSTSTR__emit = R"doc()doc";
+
+
+static const char* __doc_gr_pdu_PMTCONSTSTR__msg = R"doc()doc";
+
+
+static const char* __doc_gr_pdu_PMTCONSTSTR__pdus = R"doc()doc";
diff --git a/gr-pdu/python/pdu/bindings/docstrings/pdu_split_pydoc_template.h b/gr-pdu/python/pdu/bindings/docstrings/pdu_split_pydoc_template.h
new file mode 100644
index 0000000000..d2baf62552
--- /dev/null
+++ b/gr-pdu/python/pdu/bindings/docstrings/pdu_split_pydoc_template.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+#include "pydoc_macros.h"
+#define D(...) DOC(gr, pdu, __VA_ARGS__)
+/*
+ This file contains placeholders for docstrings for the Python bindings.
+ Do not edit! These were automatically extracted during the binding process
+ and will be overwritten during the build process
+ */
+
+
+static const char* __doc_gr_pdu_pdu_split = R"doc()doc";
+
+
+static const char* __doc_gr_pdu_pdu_split_pdu_split = R"doc()doc";
+
+
+static const char* __doc_gr_pdu_pdu_split_make = R"doc()doc";
diff --git a/gr-pdu/python/pdu/bindings/pdu_python.cc b/gr-pdu/python/pdu/bindings/pdu_python.cc
new file mode 100644
index 0000000000..bb34811618
--- /dev/null
+++ b/gr-pdu/python/pdu/bindings/pdu_python.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(pdu.h) */
+/* BINDTOOL_HEADER_FILE_HASH(34ae96025ac87967432c6b7092d1fd60) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/pdu/pdu.h>
+// pydoc.h is automatically generated in the build directory
+#include <pdu_pydoc.h>
+
+void bind_pdu(py::module& m)
+{
+
+
+ m.def("PMTCONSTSTR__data", &::gr::pdu::PMTCONSTSTR__data, D(PMTCONSTSTR__data));
+
+
+ m.def("PMTCONSTSTR__dict", &::gr::pdu::PMTCONSTSTR__dict, D(PMTCONSTSTR__dict));
+
+
+ m.def("PMTCONSTSTR__emit", &::gr::pdu::PMTCONSTSTR__emit, D(PMTCONSTSTR__emit));
+
+
+ m.def("PMTCONSTSTR__msg", &::gr::pdu::PMTCONSTSTR__msg, D(PMTCONSTSTR__msg));
+
+
+ m.def("PMTCONSTSTR__pdu", &::gr::pdu::PMTCONSTSTR__pdus, D(PMTCONSTSTR__pdus));
+}
diff --git a/gr-pdu/python/pdu/bindings/pdu_split_python.cc b/gr-pdu/python/pdu/bindings/pdu_split_python.cc
new file mode 100644
index 0000000000..ebf37aaaea
--- /dev/null
+++ b/gr-pdu/python/pdu/bindings/pdu_split_python.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+/***********************************************************************************/
+/* This file is automatically generated using bindtool and can be manually edited */
+/* The following lines can be configured to regenerate this file during cmake */
+/* If manual edits are made, the following tags should be modified accordingly. */
+/* BINDTOOL_GEN_AUTOMATIC(0) */
+/* BINDTOOL_USE_PYGCCXML(0) */
+/* BINDTOOL_HEADER_FILE(pdu_split.h) */
+/* BINDTOOL_HEADER_FILE_HASH(badbfef0fff462fec05eb888d8d3b956) */
+/***********************************************************************************/
+
+#include <pybind11/complex.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+#include <gnuradio/pdu/pdu_split.h>
+// pydoc.h is automatically generated in the build directory
+#include <pdu_split_pydoc.h>
+
+void bind_pdu_split(py::module& m)
+{
+
+ using pdu_split = ::gr::pdu::pdu_split;
+
+
+ py::class_<pdu_split, gr::block, gr::basic_block, std::shared_ptr<pdu_split>>(
+ m, "pdu_split", D(pdu_split))
+
+ .def(py::init(&pdu_split::make),
+ py::arg("pass_empty_data") = false,
+ D(pdu_split, make))
+
+
+ ;
+}
diff --git a/gr-pdu/python/pdu/bindings/python_bindings.cc b/gr-pdu/python/pdu/bindings/python_bindings.cc
new file mode 100644
index 0000000000..712021b8d1
--- /dev/null
+++ b/gr-pdu/python/pdu/bindings/python_bindings.cc
@@ -0,0 +1,42 @@
+
+/*
+ * Copyright 2021 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ */
+
+#include <pybind11/pybind11.h>
+
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#include <numpy/arrayobject.h>
+
+namespace py = pybind11;
+
+void bind_pdu_split(py::module&);
+void bind_pdu(py::module&);
+
+// We need this hack because import_array() returns NULL
+// for newer Python versions.
+// This function is also necessary because it ensures access to the C API
+// and removes a warning.
+void* init_numpy()
+{
+ import_array();
+ return NULL;
+}
+
+PYBIND11_MODULE(pdu_python, m)
+{
+ // Initialize the numpy C API
+ // (otherwise we will see segmentation faults)
+ init_numpy();
+
+ // Allow access to base block methods
+ py::module::import("gnuradio.gr");
+
+ bind_pdu_split(m);
+ bind_pdu(m);
+}
diff --git a/gr-pdu/python/pdu/qa_pdu_split.py b/gr-pdu/python/pdu/qa_pdu_split.py
new file mode 100644
index 0000000000..77f34936d9
--- /dev/null
+++ b/gr-pdu/python/pdu/qa_pdu_split.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+#
+# Copyright 2021 NTESS LLC.
+#
+# This file is part of GNU Radio
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+#
+
+
+from gnuradio import gr, gr_unittest
+from gnuradio import blocks
+import pmt
+import time
+try:
+ from gnuradio import pdu
+except ImportError:
+ import os
+ import sys
+ dirname, filename = os.path.split(os.path.abspath(__file__))
+ sys.path.append(os.path.join(dirname, "bindings"))
+ from gnuradio import pdu
+
+class qa_pdu_split (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_001_split (self):
+ split = pdu.pdu_split()
+ d1 = blocks.message_debug()
+ d2 = blocks.message_debug()
+
+ self.tb.msg_connect((split, 'dict'), (d1, 'store'))
+ self.tb.msg_connect((split, 'data'), (d2, 'store'))
+
+ in_meta1 = pmt.dict_add(pmt.make_dict(), pmt.intern('num'), pmt.from_long(4))
+ in_meta2 = pmt.dict_add(pmt.make_dict(), pmt.intern('n'), pmt.from_long(99))
+ in_pdu = pmt.cons(in_meta1, pmt.init_u8vector(6, range(6)))
+
+ self.tb.start()
+ split.to_basic_block()._post(pmt.intern("pdus"), pmt.intern("MALFORMED PDU"))
+ split.to_basic_block()._post(pmt.intern("pdus"), pmt.cons(pmt.PMT_NIL, pmt.init_u8vector(2, range(2))))
+ split.to_basic_block()._post(pmt.intern("pdus"), pmt.cons(in_meta2, pmt.init_u8vector(0, [])))
+ split.to_basic_block()._post(pmt.intern("pdus"), in_pdu)
+ split.to_basic_block()._post(pmt.intern("system"), pmt.cons(pmt.intern("done"), pmt.from_long(1)))
+ self.waitFor(lambda: d1.num_messages() == 2, timeout=1.0, poll_interval=0.01)
+ self.waitFor(lambda: d2.num_messages() == 2, timeout=1.0, poll_interval=0.01)
+ self.tb.stop()
+ self.tb.wait()
+
+ self.assertTrue(pmt.equal(d1.get_message(0), in_meta2))
+ self.assertTrue(pmt.equal(d1.get_message(1), in_meta1))
+ self.assertTrue(pmt.equal(d2.get_message(0), pmt.init_u8vector(2, range(2))))
+ self.assertTrue(pmt.equal(d2.get_message(1), pmt.init_u8vector(6, range(6))))
+
+
+ def test_002_pass_empty (self):
+ split = pdu.pdu_split(True)
+ d1 = blocks.message_debug()
+ d2 = blocks.message_debug()
+
+ self.tb.msg_connect((split, 'dict'), (d1, 'store'))
+ self.tb.msg_connect((split, 'data'), (d2, 'store'))
+
+ in_meta1 = pmt.dict_add(pmt.make_dict(), pmt.intern('num'), pmt.from_long(4))
+ in_meta2 = pmt.dict_add(pmt.make_dict(), pmt.intern('n'), pmt.from_long(99))
+ in_pdu = pmt.cons(in_meta1, pmt.init_u8vector(6, range(6)))
+
+ self.tb.start()
+ split.to_basic_block()._post(pmt.intern("pdus"), pmt.intern("MALFORMED PDU"))
+ split.to_basic_block()._post(pmt.intern("pdus"), pmt.cons(pmt.PMT_NIL, pmt.init_u8vector(2, range(2))))
+ split.to_basic_block()._post(pmt.intern("pdus"), pmt.cons(in_meta2, pmt.init_u8vector(0, [])))
+ split.to_basic_block()._post(pmt.intern("pdus"), in_pdu)
+ split.to_basic_block()._post(pmt.intern("system"), pmt.cons(pmt.intern("done"), pmt.from_long(1)))
+ self.waitFor(lambda: d1.num_messages() == 3, timeout=1.0, poll_interval=0.01)
+ self.waitFor(lambda: d2.num_messages() == 3, timeout=1.0, poll_interval=0.01)
+ self.tb.wait()
+
+ self.assertTrue(pmt.equal(d1.get_message(0), pmt.PMT_NIL))
+ self.assertTrue(pmt.equal(d1.get_message(1), in_meta2))
+ self.assertTrue(pmt.equal(d1.get_message(2), in_meta1))
+ self.assertTrue(pmt.equal(d2.get_message(0), pmt.init_u8vector(2, range(2))))
+ self.assertTrue(pmt.equal(d2.get_message(1), pmt.init_u8vector(0, [])))
+ self.assertTrue(pmt.equal(d2.get_message(2), pmt.init_u8vector(6, range(6))))
+
+
+if __name__ == '__main__':
+ gr_unittest.run(qa_pdu_split)