diff --git a/CMakeLists.txt b/CMakeLists.txt index 29bdf40..c84ae11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,21 +1,10 @@ -# Copyright 2011,2012,2014 Free Software Foundation, Inc. +# Copyright 2011-2020 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. ######################################################################## # gr-lora specific options @@ -41,7 +30,6 @@ if(DEFINED ENV{PYBOMBS_PREFIX}) message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}") endif() - # Select the release build type by default to get optimization flags if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") @@ -54,9 +42,9 @@ list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) # Set the version information here set(VERSION_MAJOR 1) -set(VERSION_API 0) -set(VERSION_ABI 0) -set(VERSION_PATCH git) +set(VERSION_API 0) +set(VERSION_ABI 0) +set(VERSION_PATCH 0) cmake_policy(SET CMP0011 NEW) @@ -67,20 +55,18 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Compiler specific setup ######################################################################## if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR - CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - AND NOT WIN32) + CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + AND NOT WIN32) #http://gcc.gnu.org/wiki/Visibility add_definitions(-fvisibility=hidden) - add_definitions(-Wall) - add_definitions(-Wextra) endif() IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - SET(CMAKE_CXX_STANDARD 11) + SET(CMAKE_CXX_STANDARD 14) ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - SET(CMAKE_CXX_STANDARD 11) + SET(CMAKE_CXX_STANDARD 14) ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - SET(CMAKE_CXX_STANDARD 11) + SET(CMAKE_CXX_STANDARD 14) ELSE() message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.") ENDIF() @@ -98,7 +84,7 @@ ENDIF() ######################################################################## # Install directories ######################################################################## -find_package(Gnuradio "3.8" REQUIRED COMPONENTS blocks filter fft analog digital) +find_package(Gnuradio "3.9" REQUIRED COMPONENTS blocks filter fft analog digital) include(GrVersion) include(GrPlatform) #define LIB_SUFFIX @@ -150,9 +136,9 @@ find_package(Doxygen) # Setup doxygen option ######################################################################## if(DOXYGEN_FOUND) - option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) + option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) else(DOXYGEN_FOUND) - option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) + option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) endif(DOXYGEN_FOUND) ######################################################################## @@ -165,22 +151,28 @@ configure_file( add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake -) + ) ######################################################################## # Add subdirectories ######################################################################## add_subdirectory(include/lora) add_subdirectory(lib) -add_subdirectory(swig) -add_subdirectory(python) -add_subdirectory(grc) add_subdirectory(apps) add_subdirectory(docs) +# NOTE: manually update below to use GRC to generate C++ flowgraphs w/o python +if(ENABLE_PYTHON) + message(STATUS "PYTHON and GRC components are enabled") + add_subdirectory(python) + add_subdirectory(grc) +else(ENABLE_PYTHON) + message(STATUS "PYTHON and GRC components are disabled") +endif(ENABLE_PYTHON) ######################################################################## # Install cmake search helper for this library ######################################################################## + install(FILES cmake/Modules/loraConfig.cmake DESTINATION ${CMAKE_MODULES_DIR}/lora ) diff --git a/MANIFEST.md b/MANIFEST.md index f7b4a32..c9f5039 100644 --- a/MANIFEST.md +++ b/MANIFEST.md @@ -1,16 +1,14 @@ title: The LORA OOT Module -brief: GNURadio blocks for receiving LoRa modulated radio messages using SDR +brief: Short description of gr-lora tags: # Tags are arbitrary, but look at CGRAN what other authors are using - sdr - - lora - - receiving - - decoding author: - - Pieter Robyns ) uhasselt.be> - - Eduard Marin ) esat.kuleuven.be> -#copyright_owner: + - Author Name +copyright_owner: + - Copyright Owner 1 license: -repo: https://github.com/rpp0/gr-lora +gr_supported_version: # Put a comma separated list of supported GR versions here +#repo: # Put the URL of the repository here, or leave blank for default #website: # If you have a separate project website, put it here #icon: # Put a URL to a square image here that will be used as an icon on CGRAN --- diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index c837d77..f5de7c0 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -1,21 +1,10 @@ # Copyright 2011 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. include(GrPython) diff --git a/apps/lora_receive_file.grc b/apps/lora_receive_file.grc index 8ac6066..94b9181 100644 --- a/apps/lora_receive_file.grc +++ b/apps/lora_receive_file.grc @@ -1,6 +1,7 @@ options: parameters: author: '' + catch_exceptions: 'True' category: Custom cmake_opt: '' comment: '' @@ -22,7 +23,6 @@ options: sizing_mode: fixed thread_safe_setters: '' title: '' - window_size: '' states: bus_sink: false bus_source: false @@ -182,7 +182,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [440, 148.0] + coordinate: [456, 148.0] rotation: 0 state: enabled - name: qtgui_freq_sink_x_0 @@ -237,6 +237,7 @@ blocks: minoutbuf: '0' name: '""' nconnections: '1' + norm_window: 'False' showports: 'False' tr_chan: '0' tr_level: '0.0' @@ -255,7 +256,7 @@ blocks: width7: '1' width8: '1' width9: '1' - wintype: firdes.WIN_BLACKMAN_hARRIS + wintype: window.WIN_BLACKMAN_hARRIS ymax: '10' ymin: '-140' states: diff --git a/apps/lora_receive_file.py b/apps/lora_receive_file.py index 3045346..970db16 100755 --- a/apps/lora_receive_file.py +++ b/apps/lora_receive_file.py @@ -6,7 +6,7 @@ # # GNU Radio Python Flow Graph # Title: Lora Receive File -# GNU Radio version: 3.8.0.0 +# GNU Radio version: 3.9.4.0 from distutils.version import StrictVersion @@ -27,18 +27,22 @@ import sip from gnuradio import blocks import pmt from gnuradio import gr +from gnuradio.fft import window import sys import signal from argparse import ArgumentParser from gnuradio.eng_arg import eng_float, intx from gnuradio import eng_notation import lora + + + from gnuradio import qtgui class lora_receive_file(gr.top_block, Qt.QWidget): def __init__(self): - gr.top_block.__init__(self, "Lora Receive File") + gr.top_block.__init__(self, "Lora Receive File", catch_exceptions=True) Qt.QWidget.__init__(self) self.setWindowTitle("Lora Receive File") qtgui.util.check_set_qss() @@ -84,11 +88,12 @@ class lora_receive_file(gr.top_block, Qt.QWidget): ################################################## self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c( 1024, #size - firdes.WIN_BLACKMAN_hARRIS, #wintype + window.WIN_BLACKMAN_hARRIS, #wintype capture_freq, #fc samp_rate, #bw "", #name - 1 + 1, + None # parent ) self.qtgui_freq_sink_x_0.set_update_time(0.10) self.qtgui_freq_sink_x_0.set_y_axis(-140, 10) @@ -99,6 +104,7 @@ class lora_receive_file(gr.top_block, Qt.QWidget): self.qtgui_freq_sink_x_0.set_fft_average(1.0) self.qtgui_freq_sink_x_0.enable_axis_labels(True) self.qtgui_freq_sink_x_0.enable_control_panel(False) + self.qtgui_freq_sink_x_0.set_fft_window_normalized(False) @@ -120,8 +126,8 @@ class lora_receive_file(gr.top_block, Qt.QWidget): self.qtgui_freq_sink_x_0.set_line_color(i, colors[i]) self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i]) - self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.pyqwidget(), Qt.QWidget) - self.top_grid_layout.addWidget(self._qtgui_freq_sink_x_0_win) + self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.qwidget(), Qt.QWidget) + self.top_layout.addWidget(self._qtgui_freq_sink_x_0_win) self.lora_lora_receiver_0 = lora.lora_receiver(samp_rate, capture_freq, [target_freq], bw, sf, False, 4, True, False, False, 10, False, False) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True) self.blocks_file_source_0 = blocks.file_source(gr.sizeof_gr_complex*1, 'counting_cr4_sf7.cfile', True, 0, 0) @@ -136,9 +142,13 @@ class lora_receive_file(gr.top_block, Qt.QWidget): self.connect((self.blocks_throttle_0, 0), (self.lora_lora_receiver_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.qtgui_freq_sink_x_0, 0)) + def closeEvent(self, event): self.settings = Qt.QSettings("GNU Radio", "lora_receive_file") self.settings.setValue("geometry", self.saveGeometry()) + self.stop() + self.wait() + event.accept() def get_sf(self): @@ -194,6 +204,7 @@ class lora_receive_file(gr.top_block, Qt.QWidget): + def main(top_block_cls=lora_receive_file, options=None): if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): @@ -202,10 +213,15 @@ def main(top_block_cls=lora_receive_file, options=None): qapp = Qt.QApplication(sys.argv) tb = top_block_cls() + tb.start() + tb.show() def sig_handler(sig=None, frame=None): + tb.stop() + tb.wait() + Qt.QApplication.quit() signal.signal(signal.SIGINT, sig_handler) @@ -215,12 +231,7 @@ def main(top_block_cls=lora_receive_file, options=None): timer.start(500) timer.timeout.connect(lambda: None) - def quitting(): - tb.stop() - tb.wait() - qapp.aboutToQuit.connect(quitting) qapp.exec_() - if __name__ == '__main__': main() diff --git a/apps/lora_receive_realtime.grc b/apps/lora_receive_realtime.grc index 4897946..d480668 100644 --- a/apps/lora_receive_realtime.grc +++ b/apps/lora_receive_realtime.grc @@ -1,6 +1,7 @@ options: parameters: author: '' + catch_exceptions: 'True' category: Custom cmake_opt: '' comment: '' @@ -10,7 +11,7 @@ options: gen_linking: dynamic generate_options: qt_gui hier_block_src_path: '.:' - id: lora_receive_realtime + id: lora_receive_file max_nouts: '0' output_language: python placement: (0,0) @@ -22,7 +23,6 @@ options: sizing_mode: fixed thread_safe_setters: '' title: '' - window_size: '' states: bus_sink: false bus_source: false @@ -41,7 +41,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [544, 12] + coordinate: [552, 13] rotation: 0 state: enabled - name: bw @@ -53,14 +53,14 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [456, 12] + coordinate: [456, 13] rotation: 0 state: enabled - name: capture_freq id: variable parameters: comment: '' - value: 868e6 + value: 866.0e6 states: bus_sink: false bus_source: false @@ -68,31 +68,11 @@ blocks: coordinate: [280, 13] rotation: 0 state: enabled -- name: decimation - id: variable - parameters: - comment: 'The decimation determines the oversampling rate. - - A sample rate of 1e6 and decimation of 1 equals - - 8 times oversampling, a decimation of 2 is 4 times - - oversampling, and so on. Set higher decimation - - for better performance, but worse accuracy.' - value: '1' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [640, 76] - rotation: 0 - state: enabled - name: samp_rate id: variable parameters: comment: '' - value: 1e6 + value: 10e6 states: bus_sink: false bus_source: false @@ -104,7 +84,7 @@ blocks: id: variable parameters: comment: '' - value: '11' + value: '7' states: bus_sink: false bus_source: false @@ -121,7 +101,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [640, 12] + coordinate: [664, 13] rotation: 0 state: enabled - name: target_freq @@ -133,7 +113,48 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [280, 76] + coordinate: [184, 76] + rotation: 0 + state: enabled +- name: blocks_file_source_0 + id: blocks_file_source + parameters: + affinity: '' + alias: '' + begin_tag: pmt.PMT_NIL + comment: '' + file: counting_cr4_sf7.cfile + length: '0' + maxoutbuf: '0' + minoutbuf: '0' + offset: '0' + repeat: 'True' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 164.0] + rotation: 0 + state: enabled +- name: blocks_throttle_0 + id: blocks_throttle + parameters: + affinity: '' + alias: '' + comment: '' + ignoretag: 'True' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_second: samp_rate + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [240, 196.0] rotation: 0 state: enabled - name: lora_lora_receiver_0 @@ -148,393 +169,20 @@ blocks: conj: 'False' cr: '4' crc: 'True' - decimation: decimation + decimation: '10' disable_channelization: 'False' disable_drift_correction: 'False' implicit: 'False' maxoutbuf: '0' minoutbuf: '0' reduced_rate: 'False' - samp_rate: 1e6 + samp_rate: samp_rate sf: sf states: bus_sink: false bus_source: false bus_structure: null - coordinate: [392, 212] - rotation: 0 - state: enabled -- name: lora_message_socket_sink_0 - id: lora_message_socket_sink - parameters: - affinity: '' - alias: '' - comment: '' - ip: 127.0.0.1 - layer: '0' - port: '40868' - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [656, 244.0] - rotation: 0 - state: enabled -- name: osmosdr_source_0 - id: osmosdr_source - parameters: - affinity: '' - alias: '' - ant0: '' - ant1: '' - ant10: '' - ant11: '' - ant12: '' - ant13: '' - ant14: '' - ant15: '' - ant16: '' - ant17: '' - ant18: '' - ant19: '' - ant2: '' - ant20: '' - ant21: '' - ant22: '' - ant23: '' - ant24: '' - ant25: '' - ant26: '' - ant27: '' - ant28: '' - ant29: '' - ant3: '' - ant30: '' - ant31: '' - ant4: '' - ant5: '' - ant6: '' - ant7: '' - ant8: '' - ant9: '' - args: '' - bb_gain0: '20' - bb_gain1: '20' - bb_gain10: '20' - bb_gain11: '20' - bb_gain12: '20' - bb_gain13: '20' - bb_gain14: '20' - bb_gain15: '20' - bb_gain16: '20' - bb_gain17: '20' - bb_gain18: '20' - bb_gain19: '20' - bb_gain2: '20' - bb_gain20: '20' - bb_gain21: '20' - bb_gain22: '20' - bb_gain23: '20' - bb_gain24: '20' - bb_gain25: '20' - bb_gain26: '20' - bb_gain27: '20' - bb_gain28: '20' - bb_gain29: '20' - bb_gain3: '20' - bb_gain30: '20' - bb_gain31: '20' - bb_gain4: '20' - bb_gain5: '20' - bb_gain6: '20' - bb_gain7: '20' - bb_gain8: '20' - bb_gain9: '20' - bw0: '0' - bw1: '0' - bw10: '0' - bw11: '0' - bw12: '0' - bw13: '0' - bw14: '0' - bw15: '0' - bw16: '0' - bw17: '0' - bw18: '0' - bw19: '0' - bw2: '0' - bw20: '0' - bw21: '0' - bw22: '0' - bw23: '0' - bw24: '0' - bw25: '0' - bw26: '0' - bw27: '0' - bw28: '0' - bw29: '0' - bw3: '0' - bw30: '0' - bw31: '0' - bw4: '0' - bw5: '0' - bw6: '0' - bw7: '0' - bw8: '0' - bw9: '0' - clock_source0: '' - clock_source1: '' - clock_source2: '' - clock_source3: '' - clock_source4: '' - clock_source5: '' - clock_source6: '' - clock_source7: '' - comment: '' - corr0: '0' - corr1: '0' - corr10: '0' - corr11: '0' - corr12: '0' - corr13: '0' - corr14: '0' - corr15: '0' - corr16: '0' - corr17: '0' - corr18: '0' - corr19: '0' - corr2: '0' - corr20: '0' - corr21: '0' - corr22: '0' - corr23: '0' - corr24: '0' - corr25: '0' - corr26: '0' - corr27: '0' - corr28: '0' - corr29: '0' - corr3: '0' - corr30: '0' - corr31: '0' - corr4: '0' - corr5: '0' - corr6: '0' - corr7: '0' - corr8: '0' - corr9: '0' - dc_offset_mode0: '0' - dc_offset_mode1: '0' - dc_offset_mode10: '0' - dc_offset_mode11: '0' - dc_offset_mode12: '0' - dc_offset_mode13: '0' - dc_offset_mode14: '0' - dc_offset_mode15: '0' - dc_offset_mode16: '0' - dc_offset_mode17: '0' - dc_offset_mode18: '0' - dc_offset_mode19: '0' - dc_offset_mode2: '0' - dc_offset_mode20: '0' - dc_offset_mode21: '0' - dc_offset_mode22: '0' - dc_offset_mode23: '0' - dc_offset_mode24: '0' - dc_offset_mode25: '0' - dc_offset_mode26: '0' - dc_offset_mode27: '0' - dc_offset_mode28: '0' - dc_offset_mode29: '0' - dc_offset_mode3: '0' - dc_offset_mode30: '0' - dc_offset_mode31: '0' - dc_offset_mode4: '0' - dc_offset_mode5: '0' - dc_offset_mode6: '0' - dc_offset_mode7: '0' - dc_offset_mode8: '0' - dc_offset_mode9: '0' - freq0: capture_freq - freq1: 100e6 - freq10: 100e6 - freq11: 100e6 - freq12: 100e6 - freq13: 100e6 - freq14: 100e6 - freq15: 100e6 - freq16: 100e6 - freq17: 100e6 - freq18: 100e6 - freq19: 100e6 - freq2: 100e6 - freq20: 100e6 - freq21: 100e6 - freq22: 100e6 - freq23: 100e6 - freq24: 100e6 - freq25: 100e6 - freq26: 100e6 - freq27: 100e6 - freq28: 100e6 - freq29: 100e6 - freq3: 100e6 - freq30: 100e6 - freq31: 100e6 - freq4: 100e6 - freq5: 100e6 - freq6: 100e6 - freq7: 100e6 - freq8: 100e6 - freq9: 100e6 - gain0: '10' - gain1: '10' - gain10: '10' - gain11: '10' - gain12: '10' - gain13: '10' - gain14: '10' - gain15: '10' - gain16: '10' - gain17: '10' - gain18: '10' - gain19: '10' - gain2: '10' - gain20: '10' - gain21: '10' - gain22: '10' - gain23: '10' - gain24: '10' - gain25: '10' - gain26: '10' - gain27: '10' - gain28: '10' - gain29: '10' - gain3: '10' - gain30: '10' - gain31: '10' - gain4: '10' - gain5: '10' - gain6: '10' - gain7: '10' - gain8: '10' - gain9: '10' - gain_mode0: 'False' - gain_mode1: 'False' - gain_mode10: 'False' - gain_mode11: 'False' - gain_mode12: 'False' - gain_mode13: 'False' - gain_mode14: 'False' - gain_mode15: 'False' - gain_mode16: 'False' - gain_mode17: 'False' - gain_mode18: 'False' - gain_mode19: 'False' - gain_mode2: 'False' - gain_mode20: 'False' - gain_mode21: 'False' - gain_mode22: 'False' - gain_mode23: 'False' - gain_mode24: 'False' - gain_mode25: 'False' - gain_mode26: 'False' - gain_mode27: 'False' - gain_mode28: 'False' - gain_mode29: 'False' - gain_mode3: 'False' - gain_mode30: 'False' - gain_mode31: 'False' - gain_mode4: 'False' - gain_mode5: 'False' - gain_mode6: 'False' - gain_mode7: 'False' - gain_mode8: 'False' - gain_mode9: 'False' - if_gain0: '20' - if_gain1: '20' - if_gain10: '20' - if_gain11: '20' - if_gain12: '20' - if_gain13: '20' - if_gain14: '20' - if_gain15: '20' - if_gain16: '20' - if_gain17: '20' - if_gain18: '20' - if_gain19: '20' - if_gain2: '20' - if_gain20: '20' - if_gain21: '20' - if_gain22: '20' - if_gain23: '20' - if_gain24: '20' - if_gain25: '20' - if_gain26: '20' - if_gain27: '20' - if_gain28: '20' - if_gain29: '20' - if_gain3: '20' - if_gain30: '20' - if_gain31: '20' - if_gain4: '20' - if_gain5: '20' - if_gain6: '20' - if_gain7: '20' - if_gain8: '20' - if_gain9: '20' - iq_balance_mode0: '0' - iq_balance_mode1: '0' - iq_balance_mode10: '0' - iq_balance_mode11: '0' - iq_balance_mode12: '0' - iq_balance_mode13: '0' - iq_balance_mode14: '0' - iq_balance_mode15: '0' - iq_balance_mode16: '0' - iq_balance_mode17: '0' - iq_balance_mode18: '0' - iq_balance_mode19: '0' - iq_balance_mode2: '0' - iq_balance_mode20: '0' - iq_balance_mode21: '0' - iq_balance_mode22: '0' - iq_balance_mode23: '0' - iq_balance_mode24: '0' - iq_balance_mode25: '0' - iq_balance_mode26: '0' - iq_balance_mode27: '0' - iq_balance_mode28: '0' - iq_balance_mode29: '0' - iq_balance_mode3: '0' - iq_balance_mode30: '0' - iq_balance_mode31: '0' - iq_balance_mode4: '0' - iq_balance_mode5: '0' - iq_balance_mode6: '0' - iq_balance_mode7: '0' - iq_balance_mode8: '0' - iq_balance_mode9: '0' - maxoutbuf: '0' - minoutbuf: '0' - nchan: '1' - num_mboards: '1' - sample_rate: samp_rate - sync: sync - time_source0: '' - time_source1: '' - time_source2: '' - time_source3: '' - time_source4: '' - time_source5: '' - time_source6: '' - time_source7: '' - type: fc32 - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [64, 180.0] + coordinate: [448, 148.0] rotation: 0 state: enabled - name: qtgui_freq_sink_x_0 @@ -589,6 +237,7 @@ blocks: minoutbuf: '0' name: '""' nconnections: '1' + norm_window: 'False' showports: 'False' tr_chan: '0' tr_level: '0.0' @@ -607,394 +256,21 @@ blocks: width7: '1' width8: '1' width9: '1' - wintype: firdes.WIN_BLACKMAN_hARRIS + wintype: window.WIN_BLACKMAN_hARRIS ymax: '10' ymin: '-140' states: bus_sink: false bus_source: false bus_structure: null - coordinate: [392, 384.0] + coordinate: [440, 304.0] rotation: 0 state: true -- name: uhd_usrp_source_0 - id: uhd_usrp_source - parameters: - affinity: '' - alias: '' - ant0: RX2 - ant1: '' - ant10: '' - ant11: '' - ant12: '' - ant13: '' - ant14: '' - ant15: '' - ant16: '' - ant17: '' - ant18: '' - ant19: '' - ant2: '' - ant20: '' - ant21: '' - ant22: '' - ant23: '' - ant24: '' - ant25: '' - ant26: '' - ant27: '' - ant28: '' - ant29: '' - ant3: '' - ant30: '' - ant31: '' - ant4: '' - ant5: '' - ant6: '' - ant7: '' - ant8: '' - ant9: '' - bw0: '0' - bw1: '0' - bw10: '0' - bw11: '0' - bw12: '0' - bw13: '0' - bw14: '0' - bw15: '0' - bw16: '0' - bw17: '0' - bw18: '0' - bw19: '0' - bw2: '0' - bw20: '0' - bw21: '0' - bw22: '0' - bw23: '0' - bw24: '0' - bw25: '0' - bw26: '0' - bw27: '0' - bw28: '0' - bw29: '0' - bw3: '0' - bw30: '0' - bw31: '0' - bw4: '0' - bw5: '0' - bw6: '0' - bw7: '0' - bw8: '0' - bw9: '0' - center_freq0: capture_freq - center_freq1: '0' - center_freq10: '0' - center_freq11: '0' - center_freq12: '0' - center_freq13: '0' - center_freq14: '0' - center_freq15: '0' - center_freq16: '0' - center_freq17: '0' - center_freq18: '0' - center_freq19: '0' - center_freq2: '0' - center_freq20: '0' - center_freq21: '0' - center_freq22: '0' - center_freq23: '0' - center_freq24: '0' - center_freq25: '0' - center_freq26: '0' - center_freq27: '0' - center_freq28: '0' - center_freq29: '0' - center_freq3: '0' - center_freq30: '0' - center_freq31: '0' - center_freq4: '0' - center_freq5: '0' - center_freq6: '0' - center_freq7: '0' - center_freq8: '0' - center_freq9: '0' - clock_rate: '0.0' - clock_source0: '' - clock_source1: '' - clock_source2: '' - clock_source3: '' - clock_source4: '' - clock_source5: '' - clock_source6: '' - clock_source7: '' - comment: '' - dc_offs_enb0: '""' - dc_offs_enb1: '""' - dc_offs_enb10: '""' - dc_offs_enb11: '""' - dc_offs_enb12: '""' - dc_offs_enb13: '""' - dc_offs_enb14: '""' - dc_offs_enb15: '""' - dc_offs_enb16: '""' - dc_offs_enb17: '""' - dc_offs_enb18: '""' - dc_offs_enb19: '""' - dc_offs_enb2: '""' - dc_offs_enb20: '""' - dc_offs_enb21: '""' - dc_offs_enb22: '""' - dc_offs_enb23: '""' - dc_offs_enb24: '""' - dc_offs_enb25: '""' - dc_offs_enb26: '""' - dc_offs_enb27: '""' - dc_offs_enb28: '""' - dc_offs_enb29: '""' - dc_offs_enb3: '""' - dc_offs_enb30: '""' - dc_offs_enb31: '""' - dc_offs_enb4: '""' - dc_offs_enb5: '""' - dc_offs_enb6: '""' - dc_offs_enb7: '""' - dc_offs_enb8: '""' - dc_offs_enb9: '""' - dev_addr: '""' - dev_args: '""' - gain0: '15' - gain1: '0' - gain10: '0' - gain11: '0' - gain12: '0' - gain13: '0' - gain14: '0' - gain15: '0' - gain16: '0' - gain17: '0' - gain18: '0' - gain19: '0' - gain2: '0' - gain20: '0' - gain21: '0' - gain22: '0' - gain23: '0' - gain24: '0' - gain25: '0' - gain26: '0' - gain27: '0' - gain28: '0' - gain29: '0' - gain3: '0' - gain30: '0' - gain31: '0' - gain4: '0' - gain5: '0' - gain6: '0' - gain7: '0' - gain8: '0' - gain9: '0' - iq_imbal_enb0: '""' - iq_imbal_enb1: '""' - iq_imbal_enb10: '""' - iq_imbal_enb11: '""' - iq_imbal_enb12: '""' - iq_imbal_enb13: '""' - iq_imbal_enb14: '""' - iq_imbal_enb15: '""' - iq_imbal_enb16: '""' - iq_imbal_enb17: '""' - iq_imbal_enb18: '""' - iq_imbal_enb19: '""' - iq_imbal_enb2: '""' - iq_imbal_enb20: '""' - iq_imbal_enb21: '""' - iq_imbal_enb22: '""' - iq_imbal_enb23: '""' - iq_imbal_enb24: '""' - iq_imbal_enb25: '""' - iq_imbal_enb26: '""' - iq_imbal_enb27: '""' - iq_imbal_enb28: '""' - iq_imbal_enb29: '""' - iq_imbal_enb3: '""' - iq_imbal_enb30: '""' - iq_imbal_enb31: '""' - iq_imbal_enb4: '""' - iq_imbal_enb5: '""' - iq_imbal_enb6: '""' - iq_imbal_enb7: '""' - iq_imbal_enb8: '""' - iq_imbal_enb9: '""' - lo_export0: 'False' - lo_export1: 'False' - lo_export10: 'False' - lo_export11: 'False' - lo_export12: 'False' - lo_export13: 'False' - lo_export14: 'False' - lo_export15: 'False' - lo_export16: 'False' - lo_export17: 'False' - lo_export18: 'False' - lo_export19: 'False' - lo_export2: 'False' - lo_export20: 'False' - lo_export21: 'False' - lo_export22: 'False' - lo_export23: 'False' - lo_export24: 'False' - lo_export25: 'False' - lo_export26: 'False' - lo_export27: 'False' - lo_export28: 'False' - lo_export29: 'False' - lo_export3: 'False' - lo_export30: 'False' - lo_export31: 'False' - lo_export4: 'False' - lo_export5: 'False' - lo_export6: 'False' - lo_export7: 'False' - lo_export8: 'False' - lo_export9: 'False' - lo_source0: internal - lo_source1: internal - lo_source10: internal - lo_source11: internal - lo_source12: internal - lo_source13: internal - lo_source14: internal - lo_source15: internal - lo_source16: internal - lo_source17: internal - lo_source18: internal - lo_source19: internal - lo_source2: internal - lo_source20: internal - lo_source21: internal - lo_source22: internal - lo_source23: internal - lo_source24: internal - lo_source25: internal - lo_source26: internal - lo_source27: internal - lo_source28: internal - lo_source29: internal - lo_source3: internal - lo_source30: internal - lo_source31: internal - lo_source4: internal - lo_source5: internal - lo_source6: internal - lo_source7: internal - lo_source8: internal - lo_source9: internal - maxoutbuf: '0' - minoutbuf: '0' - nchan: '1' - norm_gain0: 'False' - norm_gain1: 'False' - norm_gain10: 'False' - norm_gain11: 'False' - norm_gain12: 'False' - norm_gain13: 'False' - norm_gain14: 'False' - norm_gain15: 'False' - norm_gain16: 'False' - norm_gain17: 'False' - norm_gain18: 'False' - norm_gain19: 'False' - norm_gain2: 'False' - norm_gain20: 'False' - norm_gain21: 'False' - norm_gain22: 'False' - norm_gain23: 'False' - norm_gain24: 'False' - norm_gain25: 'False' - norm_gain26: 'False' - norm_gain27: 'False' - norm_gain28: 'False' - norm_gain29: 'False' - norm_gain3: 'False' - norm_gain30: 'False' - norm_gain31: 'False' - norm_gain4: 'False' - norm_gain5: 'False' - norm_gain6: 'False' - norm_gain7: 'False' - norm_gain8: 'False' - norm_gain9: 'False' - num_mboards: '1' - otw: '' - rx_agc0: Default - rx_agc1: Default - rx_agc10: Default - rx_agc11: Default - rx_agc12: Default - rx_agc13: Default - rx_agc14: Default - rx_agc15: Default - rx_agc16: Default - rx_agc17: Default - rx_agc18: Default - rx_agc19: Default - rx_agc2: Default - rx_agc20: Default - rx_agc21: Default - rx_agc22: Default - rx_agc23: Default - rx_agc24: Default - rx_agc25: Default - rx_agc26: Default - rx_agc27: Default - rx_agc28: Default - rx_agc29: Default - rx_agc3: Default - rx_agc30: Default - rx_agc31: Default - rx_agc4: Default - rx_agc5: Default - rx_agc6: Default - rx_agc7: Default - rx_agc8: Default - rx_agc9: Default - samp_rate: samp_rate - sd_spec0: '' - sd_spec1: '' - sd_spec2: '' - sd_spec3: '' - sd_spec4: '' - sd_spec5: '' - sd_spec6: '' - sd_spec7: '' - show_lo_controls: 'False' - stream_args: '' - stream_chans: '[]' - sync: sync - time_source0: '' - time_source1: '' - time_source2: '' - time_source3: '' - time_source4: '' - time_source5: '' - time_source6: '' - time_source7: '' - type: fc32 - states: - bus_sink: false - bus_source: false - bus_structure: null - coordinate: [64, 412.0] - rotation: 0 - state: disabled connections: -- [lora_lora_receiver_0, frames, lora_message_socket_sink_0, in] -- [osmosdr_source_0, '0', lora_lora_receiver_0, '0'] -- [osmosdr_source_0, '0', qtgui_freq_sink_x_0, '0'] -- [uhd_usrp_source_0, '0', lora_lora_receiver_0, '0'] -- [uhd_usrp_source_0, '0', qtgui_freq_sink_x_0, '0'] +- [blocks_file_source_0, '0', blocks_throttle_0, '0'] +- [blocks_throttle_0, '0', lora_lora_receiver_0, '0'] +- [blocks_throttle_0, '0', qtgui_freq_sink_x_0, '0'] metadata: file_format: 1 diff --git a/cmake/Modules/CMakeParseArgumentsCopy.cmake b/cmake/Modules/CMakeParseArgumentsCopy.cmake index 7ce4c49..66016cb 100644 --- a/cmake/Modules/CMakeParseArgumentsCopy.cmake +++ b/cmake/Modules/CMakeParseArgumentsCopy.cmake @@ -58,7 +58,7 @@ # the new option. # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would -# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. +# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefore. #============================================================================= # Copyright 2010 Alexander Neundorf diff --git a/cmake/Modules/loraConfig.cmake b/cmake/Modules/loraConfig.cmake index c61fa8c..da8cbbb 100644 --- a/cmake/Modules/loraConfig.cmake +++ b/cmake/Modules/loraConfig.cmake @@ -1,4 +1,5 @@ -INCLUDE(FindPkgConfig) +find_package(PkgConfig) + PKG_CHECK_MODULES(PC_LORA lora) FIND_PATH( @@ -22,9 +23,10 @@ FIND_LIBRARY( /usr/local/lib64 /usr/lib /usr/lib64 -) + ) + +include("${CMAKE_CURRENT_LIST_DIR}/loraTarget.cmake") INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(LORA DEFAULT_MSG LORA_LIBRARIES LORA_INCLUDE_DIRS) MARK_AS_ADVANCED(LORA_LIBRARIES LORA_INCLUDE_DIRS) - diff --git a/cmake/Modules/targetConfig.cmake.in b/cmake/Modules/targetConfig.cmake.in index 79e4a28..4a1fb31 100644 --- a/cmake/Modules/targetConfig.cmake.in +++ b/cmake/Modules/targetConfig.cmake.in @@ -2,20 +2,8 @@ # # 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. include(CMakeFindDependencyMacro) diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index f16fbf6..8690ba6 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,21 +1,10 @@ # Copyright 2011 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. ######################################################################## # Setup dependencies diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt index 1b44799..b30a312 100644 --- a/docs/doxygen/CMakeLists.txt +++ b/docs/doxygen/CMakeLists.txt @@ -1,21 +1,10 @@ # Copyright 2011 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. ######################################################################## # Create the doxygen configuration file @@ -28,6 +17,7 @@ file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir) set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) set(enable_html_docs YES) set(enable_latex_docs NO) +set(enable_mathjax NO) set(enable_xml_docs YES) configure_file( diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index 1f8bee1..451bbb5 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -199,13 +199,6 @@ TAB_SIZE = 8 ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -654,8 +647,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @top_srcdir@ \ - @top_builddir@ +INPUT = "@top_srcdir@" \ + "@top_builddir@" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -723,8 +716,6 @@ EXCLUDE_PATTERNS = */.deps/* \ EXCLUDE_SYMBOLS = ad9862 \ numpy \ - *swig* \ - *Swig* \ *my_top_block* \ *my_graph* \ *app_top_block* \ @@ -790,7 +781,7 @@ INPUT_FILTER = # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. -FILTER_PATTERNS = *.py=@top_srcdir@/doc/doxygen/other/doxypy.py +FILTER_PATTERNS = *.py="@top_srcdir@"/doc/doxygen/other/doxypy.py # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source @@ -945,7 +936,7 @@ HTML_STYLESHEET = # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more +# since it does not replace the standard style sheet and is therefore more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. @@ -989,7 +980,7 @@ HTML_COLORSTYLE_GAMMA = 80 # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. -HTML_TIMESTAMP = YES +HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1220,14 +1211,14 @@ FORMULA_TRANSPARENT = YES # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. -USE_MATHJAX = NO +USE_MATHJAX = @enable_mathjax@ # When MathJax is enabled you can set the default output format to be used for # the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. -MATHJAX_FORMAT = HTML-CSS +MATHJAX_FORMAT = SVG # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination @@ -1239,12 +1230,12 @@ MATHJAX_FORMAT = HTML-CSS # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_RELPATH = @MATHJAX2_PATH@ # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # The MATHJAX_CODEFILE tag can be used to specify a file with javascript # pieces of code that will be used on startup of the MathJax code. @@ -1503,18 +1494,6 @@ GENERATE_XML = @enable_xml_docs@ XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -# XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -# XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that @@ -1692,11 +1671,6 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- @@ -1709,15 +1683,6 @@ PERL_PATH = /usr/bin/perl CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. @@ -1846,7 +1811,7 @@ DIRECTORY_GRAPH = YES # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. diff --git a/docs/doxygen/doxyxml/__init__.py b/docs/doxygen/doxyxml/__init__.py index cf842c9..a57dc0e 100644 --- a/docs/doxygen/doxyxml/__init__.py +++ b/docs/doxygen/doxyxml/__init__.py @@ -1,22 +1,11 @@ # # Copyright 2010 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. # """ Python interface to contents of doxygen xml documentation. @@ -79,4 +68,3 @@ def _test(): if __name__ == "__main__": _test() - diff --git a/docs/doxygen/doxyxml/base.py b/docs/doxygen/doxyxml/base.py index 0f0adf2..48b9b3a 100644 --- a/docs/doxygen/doxyxml/base.py +++ b/docs/doxygen/doxyxml/base.py @@ -1,22 +1,11 @@ # # Copyright 2010 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. # """ A base class is created. @@ -24,8 +13,6 @@ A base class is created. Classes based upon this are used to make more user-friendly interfaces to the doxygen xml docs than the generated classes provide. """ -from __future__ import print_function -from __future__ import unicode_literals import os import pdb diff --git a/docs/doxygen/doxyxml/doxyindex.py b/docs/doxygen/doxyxml/doxyindex.py index 6b6fd09..12fb877 100644 --- a/docs/doxygen/doxyxml/doxyindex.py +++ b/docs/doxygen/doxyxml/doxyindex.py @@ -1,29 +1,16 @@ # # Copyright 2010 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. # """ Classes providing more user-friendly interfaces to the doxygen xml docs than the generated classes provide. """ -from __future__ import absolute_import -from __future__ import unicode_literals import os @@ -45,9 +32,9 @@ class DoxyIndex(Base): self._root = index.parse(os.path.join(self._xml_path, 'index.xml')) for mem in self._root.compound: converted = self.convert_mem(mem) - # For files we want the contents to be accessible directly - # from the parent rather than having to go through the file - # object. + # For files and namespaces we want the contents to be + # accessible directly from the parent rather than having + # to go through the file object. if self.get_cls(mem) == DoxyFile: if mem.name.endswith('.h'): self._members += converted.members() @@ -59,14 +46,6 @@ class DoxyIndex(Base): self._members.append(converted) -def generate_swig_doc_i(self): - """ - %feature("docstring") gr_make_align_on_samplenumbers_ss::align_state " - Wraps the C++: gr_align_on_samplenumbers_ss::align_state"; - """ - pass - - class DoxyCompMem(Base): @@ -101,13 +80,13 @@ class DoxyCompMem(Base): dpis.append(dpi) self._data['params'] = dpis + class DoxyCompound(DoxyCompMem): pass class DoxyMember(DoxyCompMem): pass - class DoxyFunction(DoxyMember): __module__ = "gnuradio.utils.doxyxml" @@ -178,6 +157,7 @@ class DoxyParameterItem(DoxyMember): description = property(lambda self: self.data()['description']) name = property(lambda self: self.data()['name']) + class DoxyClass(DoxyCompound): __module__ = "gnuradio.utils.doxyxml" @@ -300,4 +280,3 @@ class DoxyOther(Base): return obj.kind in cls.kinds Base.mem_classes.append(DoxyOther) - diff --git a/docs/doxygen/doxyxml/generated/__init__.py b/docs/doxygen/doxyxml/generated/__init__.py index 23095c1..3982397 100644 --- a/docs/doxygen/doxyxml/generated/__init__.py +++ b/docs/doxygen/doxyxml/generated/__init__.py @@ -5,4 +5,3 @@ These do the real work of parsing the doxygen xml files but the resultant classes are not very friendly to navigate so the rest of the doxyxml module processes them further. """ -from __future__ import unicode_literals diff --git a/docs/doxygen/doxyxml/generated/compound.py b/docs/doxygen/doxyxml/generated/compound.py index eedae7a..294f021 100644 --- a/docs/doxygen/doxyxml/generated/compound.py +++ b/docs/doxygen/doxyxml/generated/compound.py @@ -1,10 +1,9 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python """ Generated Mon Feb 9 19:08:05 2009 by generateDS.py. """ -from __future__ import absolute_import -from __future__ import unicode_literals + from xml.dom import minidom from xml.dom import Node @@ -500,5 +499,3 @@ def parse(inFilename): rootObj = supermod.DoxygenType.factory() rootObj.build(rootNode) return rootObj - - diff --git a/docs/doxygen/doxyxml/generated/compoundsuper.py b/docs/doxygen/doxyxml/generated/compoundsuper.py index ad69fd4..05c4928 100644 --- a/docs/doxygen/doxyxml/generated/compoundsuper.py +++ b/docs/doxygen/doxyxml/generated/compoundsuper.py @@ -1,16 +1,14 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # # Generated Thu Jun 11 18:44:25 2009 by generateDS.py. # -from __future__ import print_function -from __future__ import unicode_literals import sys + from xml.dom import minidom from xml.dom import Node -import six # # User methods @@ -66,7 +64,7 @@ def showIndent(outfile, level): outfile.write(' ') def quote_xml(inStr): - s1 = (isinstance(inStr, six.string_types) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -74,7 +72,7 @@ def quote_xml(inStr): return s1 def quote_attrib(inStr): - s1 = (isinstance(inStr, six.string_types) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -8341,4 +8339,3 @@ if __name__ == '__main__': main() #import pdb #pdb.run('main()') - diff --git a/docs/doxygen/doxyxml/generated/index.py b/docs/doxygen/doxyxml/generated/index.py index 5b54c66..8a817e1 100644 --- a/docs/doxygen/doxyxml/generated/index.py +++ b/docs/doxygen/doxyxml/generated/index.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python """ Generated Mon Feb 9 19:08:05 2009 by generateDS.py. """ -from __future__ import absolute_import -from __future__ import unicode_literals from xml.dom import minidom @@ -76,4 +74,3 @@ def parse(inFilename): rootObj.build(rootNode) return rootObj - diff --git a/docs/doxygen/doxyxml/generated/indexsuper.py b/docs/doxygen/doxyxml/generated/indexsuper.py index ef1f0c8..cc2c112 100644 --- a/docs/doxygen/doxyxml/generated/indexsuper.py +++ b/docs/doxygen/doxyxml/generated/indexsuper.py @@ -1,15 +1,14 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # # Generated Thu Jun 11 18:43:54 2009 by generateDS.py. # -from __future__ import print_function -from __future__ import unicode_literals + import sys + from xml.dom import minidom from xml.dom import Node -import six # # User methods @@ -65,7 +64,7 @@ def showIndent(outfile, level): outfile.write(' ') def quote_xml(inStr): - s1 = (isinstance(inStr, six.string_types) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -73,7 +72,7 @@ def quote_xml(inStr): return s1 def quote_attrib(inStr): - s1 = (isinstance(inStr, six.string_types) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -521,4 +520,3 @@ if __name__ == '__main__': main() #import pdb #pdb.run('main()') - diff --git a/docs/doxygen/doxyxml/text.py b/docs/doxygen/doxyxml/text.py index de2d19b..7c1dc9e 100644 --- a/docs/doxygen/doxyxml/text.py +++ b/docs/doxygen/doxyxml/text.py @@ -1,27 +1,15 @@ # # Copyright 2010 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. # """ Utilities for extracting text from generated classes. """ -from __future__ import unicode_literals def is_string(txt): if isinstance(txt, str): diff --git a/docs/doxygen/other/group_defs.dox b/docs/doxygen/other/group_defs.dox index f381c8d..a74bab8 100644 --- a/docs/doxygen/other/group_defs.dox +++ b/docs/doxygen/other/group_defs.dox @@ -4,4 +4,3 @@ * module are listed here or in the subcategories below. * */ - diff --git a/docs/doxygen/pydoc_macros.h b/docs/doxygen/pydoc_macros.h new file mode 100644 index 0000000..fb3954b --- /dev/null +++ b/docs/doxygen/pydoc_macros.h @@ -0,0 +1,19 @@ +#ifndef PYDOC_MACROS_H +#define PYDOC_MACROS_H + +#define __EXPAND(x) x +#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT +#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) +#define __CAT1(a, b) a##b +#define __CAT2(a, b) __CAT1(a, b) +#define __DOC1(n1) __doc_##n1 +#define __DOC2(n1, n2) __doc_##n1##_##n2 +#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3 +#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4 +#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5 +#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6 +#define __DOC7(n1, n2, n3, n4, n5, n6, n7) \ + __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7 +#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) + +#endif // PYDOC_MACROS_H diff --git a/docs/doxygen/update_pydoc.py b/docs/doxygen/update_pydoc.py new file mode 100644 index 0000000..dd2fba7 --- /dev/null +++ b/docs/doxygen/update_pydoc.py @@ -0,0 +1,340 @@ +# +# Copyright 2010-2012 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gnuradio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +""" +Updates the *pydoc_h files for a module +Execute using: python update_pydoc.py xml_path outputfilename + +The file instructs Pybind11 to transfer the doxygen comments into the +python docstrings. + +""" + +import os, sys, time, glob, re, json +from argparse import ArgumentParser + +from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile +from doxyxml import DoxyOther, base + +def py_name(name): + bits = name.split('_') + return '_'.join(bits[1:]) + +def make_name(name): + bits = name.split('_') + return bits[0] + '_make_' + '_'.join(bits[1:]) + + +class Block(object): + """ + Checks if doxyxml produced objects correspond to a gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + friendname = make_name(item.name()) + is_a_block = item.has_member(friendname, DoxyFriend) + # But now sometimes the make function isn't a friend so check again. + if not is_a_block: + is_a_block = di.has_member(friendname, DoxyFunction) + return is_a_block + +class Block2(object): + """ + Checks if doxyxml produced objects correspond to a new style + gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther) + return is_a_block2 + + +def utoascii(text): + """ + Convert unicode text into ascii and escape quotes and backslashes. + """ + if text is None: + return '' + out = text.encode('ascii', 'replace') + # swig will require us to replace blackslash with 4 backslashes + # TODO: evaluate what this should be for pybind11 + out = out.replace(b'\\', b'\\\\\\\\') + out = out.replace(b'"', b'\\"').decode('ascii') + return str(out) + + +def combine_descriptions(obj): + """ + Combines the brief and detailed descriptions of an object together. + """ + description = [] + bd = obj.brief_description.strip() + dd = obj.detailed_description.strip() + if bd: + description.append(bd) + if dd: + description.append(dd) + return utoascii('\n\n'.join(description)).strip() + +def format_params(parameteritems): + output = ['Args:'] + template = ' {0} : {1}' + for pi in parameteritems: + output.append(template.format(pi.name, pi.description)) + return '\n'.join(output) + +entry_templ = '%feature("docstring") {name} "{docstring}"' +def make_entry(obj, name=None, templ="{description}", description=None, params=[]): + """ + Create a docstring key/value pair, where the key is the object name. + + obj - a doxyxml object from which documentation will be extracted. + name - the name of the C object (defaults to obj.name()) + templ - an optional template for the docstring containing only one + variable named 'description'. + description - if this optional variable is set then it's value is + used as the description instead of extracting it from obj. + """ + if name is None: + name=obj.name() + if hasattr(obj,'_parse_data') and hasattr(obj._parse_data,'definition'): + name=obj._parse_data.definition.split(' ')[-1] + if "operator " in name: + return '' + if description is None: + description = combine_descriptions(obj) + if params: + description += '\n\n' + description += utoascii(format_params(params)) + docstring = templ.format(description=description) + + return {name: docstring} + + +def make_class_entry(klass, description=None, ignored_methods=[], params=None): + """ + Create a class docstring key/value pair. + """ + if params is None: + params = klass.params + output = {} + output.update(make_entry(klass, description=description, params=params)) + for func in klass.in_category(DoxyFunction): + if func.name() not in ignored_methods: + name = klass.name() + '::' + func.name() + output.update(make_entry(func, name=name)) + return output + + +def make_block_entry(di, block): + """ + Create class and function docstrings of a gnuradio block + """ + descriptions = [] + # Get the documentation associated with the class. + class_desc = combine_descriptions(block) + if class_desc: + descriptions.append(class_desc) + # Get the documentation associated with the make function + make_func = di.get_member(make_name(block.name()), DoxyFunction) + make_func_desc = combine_descriptions(make_func) + if make_func_desc: + descriptions.append(make_func_desc) + # Get the documentation associated with the file + try: + block_file = di.get_member(block.name() + ".h", DoxyFile) + file_desc = combine_descriptions(block_file) + if file_desc: + descriptions.append(file_desc) + except base.Base.NoSuchMember: + # Don't worry if we can't find a matching file. + pass + # And join them all together to make a super duper description. + super_description = "\n\n".join(descriptions) + # Associate the combined description with the class and + # the make function. + output = {} + output.update(make_class_entry(block, description=super_description)) + output.update(make_entry(make_func, description=super_description, + params=block.params)) + return output + +def make_block2_entry(di, block): + """ + Create class and function docstrings of a new style gnuradio block + """ + # For new style blocks all the relevant documentation should be + # associated with the 'make' method. + class_description = combine_descriptions(block) + make_func = block.get_member('make', DoxyFunction) + make_description = combine_descriptions(make_func) + description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description + # Associate the combined description with the class and + # the make function. + output = {} + output.update(make_class_entry( + block, description=description, + ignored_methods=['make'], params=make_func.params)) + makename = block.name() + '::make' + output.update(make_entry( + make_func, name=makename, description=description, + params=make_func.params)) + return output + +def get_docstrings_dict(di, custom_output=None): + + output = {} + if custom_output: + output.update(custom_output) + + # Create docstrings for the blocks. + blocks = di.in_category(Block) + blocks2 = di.in_category(Block2) + + make_funcs = set([]) + for block in blocks: + try: + make_func = di.get_member(make_name(block.name()), DoxyFunction) + # Don't want to risk writing to output twice. + if make_func.name() not in make_funcs: + make_funcs.add(make_func.name()) + output.update(make_block_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + for block in blocks2: + try: + make_func = block.get_member('make', DoxyFunction) + make_func_name = block.name() +'::make' + # Don't want to risk writing to output twice. + if make_func_name not in make_funcs: + make_funcs.add(make_func_name) + output.update(make_block2_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + # Create docstrings for functions + # Don't include the make functions since they have already been dealt with. + funcs = [f for f in di.in_category(DoxyFunction) + if f.name() not in make_funcs and not f.name().startswith('std::')] + for f in funcs: + try: + output.update(make_entry(f)) + except f.ParsingError: + sys.stderr.write('Parsing error for function {0}\n'.format(f.name())) + + # Create docstrings for classes + block_names = [block.name() for block in blocks] + block_names += [block.name() for block in blocks2] + klasses = [k for k in di.in_category(DoxyClass) + if k.name() not in block_names and not k.name().startswith('std::')] + for k in klasses: + try: + output.update(make_class_entry(k)) + except k.ParsingError: + sys.stderr.write('Parsing error for class {0}\n'.format(k.name())) + + # Docstrings are not created for anything that is not a function or a class. + # If this excludes anything important please add it here. + + return output + +def sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, output_dir, filter_str=None): + if filter_str: + docstrings_dict = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str)} + + with open(os.path.join(output_dir,'docstring_status'),'w') as status_file: + + for pydoc_file in pydoc_files: + if filter_str: + filter_str2 = "::".join((filter_str,os.path.split(pydoc_file)[-1].split('_pydoc_template.h')[0])) + docstrings_dict2 = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str2)} + else: + docstrings_dict2 = docstrings_dict + + + + file_in = open(pydoc_file,'r').read() + for key, value in docstrings_dict2.items(): + file_in_tmp = file_in + try: + doc_key = key.split("::") + # if 'gr' in doc_key: + # doc_key.remove('gr') + doc_key = '_'.join(doc_key) + regexp = r'(__doc_{} =\sR\"doc\()[^)]*(\)doc\")'.format(doc_key) + regexp = re.compile(regexp, re.MULTILINE) + + (file_in, nsubs) = regexp.subn(r'\1'+value+r'\2', file_in, count=1) + if nsubs == 1: + status_file.write("PASS: " + pydoc_file + "\n") + except KeyboardInterrupt: + raise KeyboardInterrupt + except: # be permissive, TODO log, but just leave the docstring blank + status_file.write("FAIL: " + pydoc_file + "\n") + file_in = file_in_tmp + + output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h')) + with open(output_pathname,'w') as file_out: + file_out.write(file_in) + +def copy_docstring_templates(pydoc_files, output_dir): + with open(os.path.join(output_dir,'docstring_status'),'w') as status_file: + for pydoc_file in pydoc_files: + file_in = open(pydoc_file,'r').read() + output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h')) + with open(output_pathname,'w') as file_out: + file_out.write(file_in) + status_file.write("DONE") + +def argParse(): + """Parses commandline args.""" + desc='Scrape the doxygen generated xml for docstrings to insert into python bindings' + parser = ArgumentParser(description=desc) + + parser.add_argument("function", help="Operation to perform on docstrings", choices=["scrape","sub","copy"]) + + parser.add_argument("--xml_path") + parser.add_argument("--bindings_dir") + parser.add_argument("--output_dir") + parser.add_argument("--json_path") + parser.add_argument("--filter", default=None) + + return parser.parse_args() + +if __name__ == "__main__": + # Parse command line options and set up doxyxml. + args = argParse() + if args.function.lower() == 'scrape': + di = DoxyIndex(args.xml_path) + docstrings_dict = get_docstrings_dict(di) + with open(args.json_path, 'w') as fp: + json.dump(docstrings_dict, fp) + elif args.function.lower() == 'sub': + with open(args.json_path, 'r') as fp: + docstrings_dict = json.load(fp) + pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h')) + sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, args.output_dir, args.filter) + elif args.function.lower() == 'copy': + pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h')) + copy_docstring_templates(pydoc_files, args.output_dir) diff --git a/examples/README b/examples/README new file mode 100644 index 0000000..d7a3359 --- /dev/null +++ b/examples/README @@ -0,0 +1,3 @@ +It is considered good practice to add examples in here to demonstrate the +functionality of your OOT module. Python scripts, GRC flow graphs or other +code can go here. diff --git a/grc/lora_message_socket_sink.block.yml b/grc/lora_message_socket_sink.block.yml index c2f1db2..3afb776 100644 --- a/grc/lora_message_socket_sink.block.yml +++ b/grc/lora_message_socket_sink.block.yml @@ -15,7 +15,7 @@ parameters: default: 40868 - id: layer label: Layer - dtype: enum + dtype: raw options: ['0', '1', '2'] option_labels: [LoRa TAP, LoRa PHY, LoRa MAC] diff --git a/include/lora/channelizer.h b/include/lora/channelizer.h index 3497c09..774d40c 100644 --- a/include/lora/channelizer.h +++ b/include/lora/channelizer.h @@ -36,7 +36,7 @@ namespace gr { class LORA_API channelizer : virtual public gr::hier_block2 { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * \brief Return a shared_ptr to a new instance of lora::channelizer. diff --git a/include/lora/controller.h b/include/lora/controller.h index 278e91c..01bce58 100644 --- a/include/lora/controller.h +++ b/include/lora/controller.h @@ -36,7 +36,7 @@ namespace gr { class LORA_API controller : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * \brief Return a shared_ptr to a new instance of lora::controller. diff --git a/include/lora/decoder.h b/include/lora/decoder.h index 6f043c2..0d61f07 100644 --- a/include/lora/decoder.h +++ b/include/lora/decoder.h @@ -692,7 +692,7 @@ namespace gr { */ class LORA_API decoder : virtual public gr::sync_block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * \brief Return a shared_ptr to a new instance of lora::decoder. diff --git a/include/lora/message_file_sink.h b/include/lora/message_file_sink.h index 76ac7b0..b02848f 100644 --- a/include/lora/message_file_sink.h +++ b/include/lora/message_file_sink.h @@ -694,7 +694,7 @@ namespace gr { class LORA_API message_file_sink : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * \brief Return a shared_ptr to a new instance of lora::message_file_sink. diff --git a/include/lora/message_socket_sink.h b/include/lora/message_socket_sink.h index 9b3d7fd..087f08a 100644 --- a/include/lora/message_socket_sink.h +++ b/include/lora/message_socket_sink.h @@ -691,7 +691,7 @@ namespace gr { */ class LORA_API message_socket_sink : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; enum lora_layer { LORATAP = 0, LORAPHY, LORAMAC }; /*! @@ -702,7 +702,7 @@ namespace gr { * class. lora::message_socket_sink::make is the public interface for * creating new instances. */ - static sptr make(std::string ip, int port, enum lora_layer layer); + static sptr make(std::string ip, int port, int layer); }; } // namespace lora diff --git a/include/lora/message_socket_source.h b/include/lora/message_socket_source.h index 38b2b23..c9dbed4 100644 --- a/include/lora/message_socket_source.h +++ b/include/lora/message_socket_source.h @@ -697,7 +697,7 @@ namespace gr { class LORA_API message_socket_source : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * \param addr The address to bind the UDP socket diff --git a/lib/channelizer_impl.cc b/lib/channelizer_impl.cc index 3429947..c8c35d3 100644 --- a/lib/channelizer_impl.cc +++ b/lib/channelizer_impl.cc @@ -43,7 +43,7 @@ namespace gr { gr::io_signature::make(channel_list.size(), channel_list.size(), sizeof(gr_complex))), d_cfo(0.0) { - d_lpf = gr::filter::firdes::low_pass(1.0, samp_rate, (bandwidth/2)+15000, 10000, gr::filter::firdes::WIN_HAMMING, 6.67); + d_lpf = gr::filter::firdes::low_pass(1.0, samp_rate, (bandwidth/2)+15000, 10000, fft::window::win_type::WIN_HAMMING, 6.67); d_freq_offset = channel_list[0] - center_freq; d_xlating_fir_filter = gr::filter::freq_xlating_fir_filter_ccf::make(decimation, d_lpf, d_freq_offset, samp_rate); d_controller = gr::lora::controller::make((void*)this); diff --git a/lib/debugger_impl.cc b/lib/debugger_impl.cc new file mode 100644 index 0000000..10c3775 --- /dev/null +++ b/lib/debugger_impl.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2021 gr-lora author. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include "debugger_impl.h" + +namespace gr { + namespace lora { + + #pragma message("set the following appropriately and remove this warning") + using input_type = float; + #pragma message("set the following appropriately and remove this warning") + using output_type = float; + debugger::sptr + debugger::make() + { + return gnuradio::make_block_sptr( + ); + } + + + /* + * The private constructor + */ + debugger_impl::debugger_impl() + : gr::block("debugger", + gr::io_signature::make(1 /* min inputs */, 1 /* max inputs */, sizeof(input_type)), + gr::io_signature::make(1 /* min outputs */, 1 /*max outputs */, sizeof(output_type))) + {} + + /* + * Our virtual destructor. + */ + debugger_impl::~debugger_impl() + { + } + + void + debugger_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) + { + #pragma message("implement a forecast that fills in how many items on each input you need to produce noutput_items and remove this warning") + /* <+forecast+> e.g. ninput_items_required[0] = noutput_items */ + } + + int + debugger_impl::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + auto in = static_cast(input_items[0]); + auto out = static_cast(output_items[0]); + + #pragma message("Implement the signal processing in your block and remove this warning") + // Do <+signal processing+> + // Tell runtime system how many input items we consumed on + // each input stream. + consume_each (noutput_items); + + // Tell runtime system how many output items we produced. + return noutput_items; + } + + } /* namespace lora */ +} /* namespace gr */ diff --git a/lib/debugger_impl.h b/lib/debugger_impl.h new file mode 100644 index 0000000..324a5ff --- /dev/null +++ b/lib/debugger_impl.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2021 gr-lora author. + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#ifndef INCLUDED_LORA_DEBUGGER_IMPL_H +#define INCLUDED_LORA_DEBUGGER_IMPL_H + +#include + +namespace gr { + namespace lora { + + class debugger_impl : public debugger + { + private: + // Nothing to declare in this block. + + public: + debugger_impl(); + ~debugger_impl(); + + // Where all the action really happens + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + }; + + } // namespace lora +} // namespace gr + +#endif /* INCLUDED_LORA_DEBUGGER_IMPL_H */ diff --git a/lib/message_socket_sink_impl.cc b/lib/message_socket_sink_impl.cc index df9183c..74577eb 100644 --- a/lib/message_socket_sink_impl.cc +++ b/lib/message_socket_sink_impl.cc @@ -31,7 +31,7 @@ namespace gr { namespace lora { - message_socket_sink::sptr message_socket_sink::make(std::string ip, int port, enum lora_layer layer) { + message_socket_sink::sptr message_socket_sink::make(std::string ip, int port, int layer) { return gnuradio::get_initial_sptr(new message_socket_sink_impl(ip, port, layer)); } @@ -40,7 +40,7 @@ namespace gr { * * Create a UDP socket connection to send the data through. */ - message_socket_sink_impl::message_socket_sink_impl(std::string ip, int port, enum lora_layer layer) + message_socket_sink_impl::message_socket_sink_impl(std::string ip, int port, int layer) : gr::block("message_socket_sink", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)), d_ip(ip), d_port(port), diff --git a/lib/message_socket_sink_impl.h b/lib/message_socket_sink_impl.h index 589945b..2933cc8 100644 --- a/lib/message_socket_sink_impl.h +++ b/lib/message_socket_sink_impl.h @@ -33,7 +33,7 @@ namespace gr { private: std::string d_ip = "127.0.0.1"; int d_port = 40868; - enum lora_layer d_layer; + int d_layer; // socket struct sockaddr_in *d_sock_addr; @@ -42,7 +42,7 @@ namespace gr { void handle(pmt::pmt_t msg); public: - message_socket_sink_impl(std::string ip, int port, enum lora_layer layer); + message_socket_sink_impl(std::string ip, int port, int layer); ~message_socket_sink_impl(); private: diff --git a/lib/message_socket_source_impl.cc b/lib/message_socket_source_impl.cc index 7ed7683..27bc25f 100644 --- a/lib/message_socket_source_impl.cc +++ b/lib/message_socket_source_impl.cc @@ -46,7 +46,7 @@ namespace gr { d_running(true) { message_port_register_out(pmt::mp("out")); - boost::shared_ptr(new boost::thread(boost::bind (&message_socket_source_impl::msg_receive_udp, this))); + std::shared_ptr(new boost::thread(boost::bind (&message_socket_source_impl::msg_receive_udp, this))); } void message_socket_source_impl::msg_receive_udp() { diff --git a/lib/message_socket_source_impl.h b/lib/message_socket_source_impl.h index b223871..9e9b2cf 100644 --- a/lib/message_socket_source_impl.h +++ b/lib/message_socket_source_impl.h @@ -36,7 +36,7 @@ namespace gr const std::string d_addr; const uint16_t d_udp_port; bool d_running; - boost::shared_ptr d_thread; + std::shared_ptr d_thread; void msg_receive_udp(); diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index d04abc3..0b28d79 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,21 +1,10 @@ # Copyright 2011 Free Software Foundation, Inc. # -# This file is part of GNU Radio +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-lora # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# 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. ######################################################################## # Include python install macros @@ -25,6 +14,8 @@ if(NOT PYTHONINTERP_FOUND) return() endif() +add_subdirectory(bindings) + ######################################################################## # Install python sources ######################################################################## @@ -51,5 +42,10 @@ endif(HAS_MONGODB) include(GrTest) set(GR_TEST_TARGET_DEPS gnuradio-lora) -set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) -GR_ADD_TEST(qa_receiver ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_receiver.py) +GR_ADD_TEST(qa_channelizer ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_channelizer.py) +GR_ADD_TEST(qa_controller ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_controller.py) +GR_ADD_TEST(qa_debugger ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_debugger.py) +GR_ADD_TEST(qa_decoder ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_decoder.py) +GR_ADD_TEST(qa_message_file_sink ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_message_file_sink.py) +GR_ADD_TEST(qa_message_socket_sink ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_message_socket_sink.py) +GR_ADD_TEST(qa_message_socket_source ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_message_socket_source.py) diff --git a/python/__init__.py b/python/__init__.py index b794920..5af26e7 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -1,19 +1,7 @@ # # Copyright 2008,2009 Free Software Foundation, Inc. # -# This application 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. -# -# This application 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 this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# SPDX-License-Identifier: GPL-3.0-or-later # # The presence of this file turns this directory into a Python package @@ -22,17 +10,15 @@ This is the GNU Radio LORA module. Place your Python package description here (python/__init__.py). ''' +import os -# import swig generated symbols into the lora namespace -# this might fail if the module is python-only -from .lora_swig import * +# import pybind11 generated symbols into the lora namespace +try: + # this might fail if the module is python-only + from .lora_python import * +except ModuleNotFoundError: + pass # import any pure python here -from .lora_receiver import lora_receiver +from .lora_receiver import * # - -# import optional blocks -try: - from message_mongodb_sink import message_mongodb_sink -except ImportError: - pass diff --git a/python/bindings/CMakeLists.txt b/python/bindings/CMakeLists.txt new file mode 100644 index 0000000..a2fab37 --- /dev/null +++ b/python/bindings/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright 2020 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +######################################################################## +# Check if there is C++ code at all +######################################################################## +if(NOT lora_sources) + MESSAGE(STATUS "No C++ sources... skipping python bindings") + return() +endif(NOT lora_sources) + +######################################################################## +# Check for pygccxml +######################################################################## +GR_PYTHON_CHECK_MODULE_RAW( + "pygccxml" + "import pygccxml" + PYGCCXML_FOUND + ) + +include(GrPybind) + +######################################################################## +# Python Bindings +######################################################################## + +list(APPEND lora_python_files + channelizer_python.cc + controller_python.cc + debugger_python.cc + decoder_python.cc + message_file_sink_python.cc + message_socket_sink_python.cc + message_socket_source_python.cc python_bindings.cc) + +GR_PYBIND_MAKE_OOT(lora + ../.. + gr::lora + "${lora_python_files}") + +install(TARGETS lora_python DESTINATION ${GR_PYTHON_DIR}/lora COMPONENT pythonapi) diff --git a/python/bindings/README.md b/python/bindings/README.md new file mode 100644 index 0000000..e69de29 diff --git a/python/bindings/bind_oot_file.py b/python/bindings/bind_oot_file.py new file mode 100644 index 0000000..9673ceb --- /dev/null +++ b/python/bindings/bind_oot_file.py @@ -0,0 +1,58 @@ +import warnings +import argparse +import os +from gnuradio.bindtool import BindingGenerator +import pathlib +import sys +import tempfile + +parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block') +parser.add_argument('--module', type=str, + help='Name of gr module containing file to bind (e.g. fft digital analog)') + +parser.add_argument('--output_dir', default=tempfile.gettempdir(), + help='Output directory of generated bindings') +parser.add_argument('--prefix', help='Prefix of Installed GNU Radio') +parser.add_argument('--src', help='Directory of gnuradio source tree', + default=os.path.dirname(os.path.abspath(__file__))+'/../../..') + +parser.add_argument( + '--filename', help="File to be parsed") + +parser.add_argument( + '--defines', help='Set additional defines for precompiler',default=(), nargs='*') +parser.add_argument( + '--include', help='Additional Include Dirs, separated', default=(), nargs='*') + +parser.add_argument( + '--status', help='Location of output file for general status (used during cmake)', default=None +) +parser.add_argument( + '--flag_automatic', default='0' +) +parser.add_argument( + '--flag_pygccxml', default='0' +) + +args = parser.parse_args() + +prefix = args.prefix +output_dir = args.output_dir +defines = tuple(','.join(args.defines).split(',')) +includes = ','.join(args.include) +name = args.module + +namespace = ['gr', name] +prefix_include_root = name + + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + + bg = BindingGenerator(prefix, namespace, + prefix_include_root, output_dir, define_symbols=defines, addl_includes=includes, + catch_exceptions=False, write_json_output=False, status_output=args.status, + flag_automatic=True if args.flag_automatic.lower() in [ + '1', 'true'] else False, + flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False) + bg.gen_file_binding(args.filename) diff --git a/python/bindings/channelizer_python.cc b/python/bindings/channelizer_python.cc new file mode 100644 index 0000000..64150a5 --- /dev/null +++ b/python/bindings/channelizer_python.cc @@ -0,0 +1,64 @@ +/* + * 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(channelizer.h) */ +/* BINDTOOL_HEADER_FILE_HASH(167bb3d9cfb713d2d79f74c50f07034c) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_channelizer(py::module& m) +{ + + using channelizer = ::gr::lora::channelizer; + + + py::class_>(m, "channelizer", D(channelizer)) + + .def(py::init(&channelizer::make), + py::arg("samp_rate"), + py::arg("center_freq"), + py::arg("channel_list"), + py::arg("bandwidth"), + py::arg("decimation"), + D(channelizer,make) + ) + + + + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/controller_python.cc b/python/bindings/controller_python.cc new file mode 100644 index 0000000..7a73292 --- /dev/null +++ b/python/bindings/controller_python.cc @@ -0,0 +1,60 @@ +/* + * 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(controller.h) */ +/* BINDTOOL_HEADER_FILE_HASH(512fce4847009685d991d6f271ca38fe) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_controller(py::module& m) +{ + + using controller = ::gr::lora::controller; + + + py::class_>(m, "controller", D(controller)) + + .def(py::init(&controller::make), + py::arg("parent"), + D(controller,make) + ) + + + + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/debugger_python.cc b/python/bindings/debugger_python.cc new file mode 100644 index 0000000..ada4b58 --- /dev/null +++ b/python/bindings/debugger_python.cc @@ -0,0 +1,86 @@ +/* + * 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(debugger.h) */ +/* BINDTOOL_HEADER_FILE_HASH(7f42d6dddb1e9acd3d70016f34901510) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_debugger(py::module& m) +{ + + using debugger = ::gr::lora::debugger; + + + py::class_>(m, "debugger", D(debugger)) + + .def(py::init<>(),D(debugger,debugger,0)) + .def(py::init(), py::arg("arg0"), + D(debugger,debugger,1) + ) + + + + .def("attach",&debugger::attach, + py::arg("path") = "/tmp/gr_lora.sock", + D(debugger,attach) + ) + + + + .def("detach",&debugger::detach, + D(debugger,detach) + ) + + + + .def("analyze_samples",&debugger::analyze_samples, + py::arg("clear"), + py::arg("draw_over"), + D(debugger,analyze_samples) + ) + + + + .def("store_samples",&debugger::store_samples, + py::arg("samples"), + py::arg("length"), + D(debugger,store_samples) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/decoder_python.cc b/python/bindings/decoder_python.cc new file mode 100644 index 0000000..f85c0a1 --- /dev/null +++ b/python/bindings/decoder_python.cc @@ -0,0 +1,81 @@ +/* + * 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(decoder.h) */ +/* BINDTOOL_HEADER_FILE_HASH(b2b8270ca781d7bb005a951719babe12) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_decoder(py::module& m) +{ + + using decoder = ::gr::lora::decoder; + + + py::class_>(m, "decoder", D(decoder)) + + .def(py::init(&decoder::make), + py::arg("samp_rate"), + py::arg("bandwidth"), + py::arg("sf"), + py::arg("implicit"), + py::arg("cr"), + py::arg("crc"), + py::arg("reduced_rate"), + py::arg("disable_drift_correction"), + D(decoder,make) + ) + + + + + + + .def("set_sf",&decoder::set_sf, + py::arg("sf"), + D(decoder,set_sf) + ) + + + + .def("set_samp_rate",&decoder::set_samp_rate, + py::arg("samp_rate"), + D(decoder,set_samp_rate) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/docstrings/README.md b/python/bindings/docstrings/README.md new file mode 100644 index 0000000..a506c22 --- /dev/null +++ b/python/bindings/docstrings/README.md @@ -0,0 +1 @@ +This directory stores templates for docstrings that are scraped from the include header files for each block diff --git a/python/bindings/docstrings/channelizer_pydoc_template.h b/python/bindings/docstrings/channelizer_pydoc_template.h new file mode 100644 index 0000000..362d55a --- /dev/null +++ b/python/bindings/docstrings/channelizer_pydoc_template.h @@ -0,0 +1,27 @@ +/* + * 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,lora, __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_lora_channelizer = R"doc()doc"; + + + static const char *__doc_gr_lora_channelizer_channelizer = R"doc()doc"; + + + static const char *__doc_gr_lora_channelizer_make = R"doc()doc"; + + diff --git a/python/bindings/docstrings/controller_pydoc_template.h b/python/bindings/docstrings/controller_pydoc_template.h new file mode 100644 index 0000000..bb52963 --- /dev/null +++ b/python/bindings/docstrings/controller_pydoc_template.h @@ -0,0 +1,27 @@ +/* + * 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,lora, __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_lora_controller = R"doc()doc"; + + + static const char *__doc_gr_lora_controller_controller = R"doc()doc"; + + + static const char *__doc_gr_lora_controller_make = R"doc()doc"; + + diff --git a/python/bindings/docstrings/debugger_pydoc_template.h b/python/bindings/docstrings/debugger_pydoc_template.h new file mode 100644 index 0000000..da20673 --- /dev/null +++ b/python/bindings/docstrings/debugger_pydoc_template.h @@ -0,0 +1,39 @@ +/* + * 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,lora, __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_lora_debugger = R"doc()doc"; + + + static const char *__doc_gr_lora_debugger_debugger_0 = R"doc()doc"; + + + static const char *__doc_gr_lora_debugger_debugger_1 = R"doc()doc"; + + + static const char *__doc_gr_lora_debugger_attach = R"doc()doc"; + + + static const char *__doc_gr_lora_debugger_detach = R"doc()doc"; + + + static const char *__doc_gr_lora_debugger_analyze_samples = R"doc()doc"; + + + static const char *__doc_gr_lora_debugger_store_samples = R"doc()doc"; + + diff --git a/python/bindings/docstrings/decoder_pydoc_template.h b/python/bindings/docstrings/decoder_pydoc_template.h new file mode 100644 index 0000000..89f6c67 --- /dev/null +++ b/python/bindings/docstrings/decoder_pydoc_template.h @@ -0,0 +1,36 @@ +/* + * 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,lora, __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_lora_decoder = R"doc()doc"; + + + static const char *__doc_gr_lora_decoder_decoder_0 = R"doc()doc"; + + + static const char *__doc_gr_lora_decoder_decoder_1 = R"doc()doc"; + + + static const char *__doc_gr_lora_decoder_make = R"doc()doc"; + + + static const char *__doc_gr_lora_decoder_set_sf = R"doc()doc"; + + + static const char *__doc_gr_lora_decoder_set_samp_rate = R"doc()doc"; + + diff --git a/python/bindings/docstrings/message_file_sink_pydoc_template.h b/python/bindings/docstrings/message_file_sink_pydoc_template.h new file mode 100644 index 0000000..141064d --- /dev/null +++ b/python/bindings/docstrings/message_file_sink_pydoc_template.h @@ -0,0 +1,27 @@ +/* + * 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,lora, __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_lora_message_file_sink = R"doc()doc"; + + + static const char *__doc_gr_lora_message_file_sink_message_file_sink = R"doc()doc"; + + + static const char *__doc_gr_lora_message_file_sink_make = R"doc()doc"; + + diff --git a/python/bindings/docstrings/message_socket_sink_pydoc_template.h b/python/bindings/docstrings/message_socket_sink_pydoc_template.h new file mode 100644 index 0000000..5e8b584 --- /dev/null +++ b/python/bindings/docstrings/message_socket_sink_pydoc_template.h @@ -0,0 +1,27 @@ +/* + * 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,lora, __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_lora_message_socket_sink = R"doc()doc"; + + + static const char *__doc_gr_lora_message_socket_sink_message_socket_sink = R"doc()doc"; + + + static const char *__doc_gr_lora_message_socket_sink_make = R"doc()doc"; + + diff --git a/python/bindings/docstrings/message_socket_source_pydoc_template.h b/python/bindings/docstrings/message_socket_source_pydoc_template.h new file mode 100644 index 0000000..07a612c --- /dev/null +++ b/python/bindings/docstrings/message_socket_source_pydoc_template.h @@ -0,0 +1,27 @@ +/* + * 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,lora, __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_lora_message_socket_source = R"doc()doc"; + + + static const char *__doc_gr_lora_message_socket_source_message_socket_source = R"doc()doc"; + + + static const char *__doc_gr_lora_message_socket_source_make = R"doc()doc"; + + diff --git a/python/bindings/header_utils.py b/python/bindings/header_utils.py new file mode 100644 index 0000000..2150a76 --- /dev/null +++ b/python/bindings/header_utils.py @@ -0,0 +1,78 @@ +# Utilities for reading values in header files + +from argparse import ArgumentParser +import re + + +class PybindHeaderParser: + def __init__(self, pathname): + with open(pathname,'r') as f: + self.file_txt = f.read() + + def get_flag_automatic(self): + # p = re.compile(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)', self.file_txt) + if (m and m.group(1) == '1'): + return True + else: + return False + + def get_flag_pygccxml(self): + # p = re.compile(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)', self.file_txt) + if (m and m.group(1) == '1'): + return True + else: + return False + + def get_header_filename(self): + # p = re.compile(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)', self.file_txt) + if (m): + return m.group(1) + else: + return None + + def get_header_file_hash(self): + # p = re.compile(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)', self.file_txt) + if (m): + return m.group(1) + else: + return None + + def get_flags(self): + return f'{self.get_flag_automatic()};{self.get_flag_pygccxml()};{self.get_header_filename()};{self.get_header_file_hash()};' + + + +def argParse(): + """Parses commandline args.""" + desc='Reads the parameters from the comment block in the pybind files' + parser = ArgumentParser(description=desc) + + parser.add_argument("function", help="Operation to perform on comment block of pybind file", choices=["flag_auto","flag_pygccxml","header_filename","header_file_hash","all"]) + parser.add_argument("pathname", help="Pathname of pybind c++ file to read, e.g. blockname_python.cc") + + return parser.parse_args() + +if __name__ == "__main__": + # Parse command line options and set up doxyxml. + args = argParse() + + pbhp = PybindHeaderParser(args.pathname) + + if args.function == "flag_auto": + print(pbhp.get_flag_automatic()) + elif args.function == "flag_pygccxml": + print(pbhp.get_flag_pygccxml()) + elif args.function == "header_filename": + print(pbhp.get_header_filename()) + elif args.function == "header_file_hash": + print(pbhp.get_header_file_hash()) + elif args.function == "all": + print(pbhp.get_flags()) diff --git a/python/bindings/message_file_sink_python.cc b/python/bindings/message_file_sink_python.cc new file mode 100644 index 0000000..307fce8 --- /dev/null +++ b/python/bindings/message_file_sink_python.cc @@ -0,0 +1,60 @@ +/* + * 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(message_file_sink.h) */ +/* BINDTOOL_HEADER_FILE_HASH(e9489007885a308eeca55422c9b17f72) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_message_file_sink(py::module& m) +{ + + using message_file_sink = ::gr::lora::message_file_sink; + + + py::class_>(m, "message_file_sink", D(message_file_sink)) + + .def(py::init(&message_file_sink::make), + py::arg("path"), + D(message_file_sink,make) + ) + + + + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/message_socket_sink_python.cc b/python/bindings/message_socket_sink_python.cc new file mode 100644 index 0000000..fbd6bf5 --- /dev/null +++ b/python/bindings/message_socket_sink_python.cc @@ -0,0 +1,62 @@ +/* + * 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(message_socket_sink.h) */ +/* BINDTOOL_HEADER_FILE_HASH(a5947a2cefc78aab01d2e5f4da0ffc23) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_message_socket_sink(py::module& m) +{ + + using message_socket_sink = ::gr::lora::message_socket_sink; + + + py::class_>(m, "message_socket_sink", D(message_socket_sink)) + + .def(py::init(&message_socket_sink::make), + py::arg("ip"), + py::arg("port"), + py::arg("layer"), + D(message_socket_sink,make) + ) + + + + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/message_socket_source_python.cc b/python/bindings/message_socket_source_python.cc new file mode 100644 index 0000000..1ab2233 --- /dev/null +++ b/python/bindings/message_socket_source_python.cc @@ -0,0 +1,61 @@ +/* + * 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(message_socket_source.h) */ +/* BINDTOOL_HEADER_FILE_HASH(9a72454e6b91e9fa0e2314b6992d1807) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_message_socket_source(py::module& m) +{ + + using message_socket_source = ::gr::lora::message_socket_source; + + + py::class_>(m, "message_socket_source", D(message_socket_source)) + + .def(py::init(&message_socket_source::make), + py::arg("addr"), + py::arg("port"), + D(message_socket_source,make) + ) + + + + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/python_bindings.cc b/python/bindings/python_bindings.cc new file mode 100644 index 0000000..cb1856e --- /dev/null +++ b/python/bindings/python_bindings.cc @@ -0,0 +1,67 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include + +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include + +namespace py = pybind11; + +// Headers for binding functions +/**************************************/ +// The following comment block is used for +// gr_modtool to insert function prototypes +// Please do not delete +/**************************************/ +// BINDING_FUNCTION_PROTOTYPES( + void bind_channelizer(py::module& m); + void bind_controller(py::module& m); + //void bind_debugger(py::module& m); + void bind_decoder(py::module& m); + void bind_message_file_sink(py::module& m); + void bind_message_socket_sink(py::module& m); + void bind_message_socket_source(py::module& m); +// ) END BINDING_FUNCTION_PROTOTYPES + + +// 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(lora_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"); + + /**************************************/ + // The following comment block is used for + // gr_modtool to insert binding function calls + // Please do not delete + /**************************************/ + // BINDING_FUNCTION_CALLS( + bind_channelizer(m); + bind_controller(m); + //bind_debugger(m); + bind_decoder(m); + bind_message_file_sink(m); + bind_message_socket_sink(m); + bind_message_socket_source(m); + // ) END BINDING_FUNCTION_CALLS +} diff --git a/python/qa_channelizer.py b/python/qa_channelizer.py new file mode 100755 index 0000000..22a7b25 --- /dev/null +++ b/python/qa_channelizer.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-lora author. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from gnuradio import gr, gr_unittest +# from gnuradio import blocks +try: + from lora import channelizer +except ImportError: + import os + import sys + dirname, filename = os.path.split(os.path.abspath(__file__)) + sys.path.append(os.path.join(dirname, "bindings")) + from lora import channelizer + +class qa_channelizer(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_instance(self): + # FIXME: Test will fail until you pass sensible arguments to the constructor + instance = channelizer() + + def test_001_descriptive_test_name(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_channelizer) diff --git a/python/qa_controller.py b/python/qa_controller.py new file mode 100755 index 0000000..e84ff59 --- /dev/null +++ b/python/qa_controller.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-lora author. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from gnuradio import gr, gr_unittest +# from gnuradio import blocks +try: + from lora import controller +except ImportError: + import os + import sys + dirname, filename = os.path.split(os.path.abspath(__file__)) + sys.path.append(os.path.join(dirname, "bindings")) + from lora import controller + +class qa_controller(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_instance(self): + # FIXME: Test will fail until you pass sensible arguments to the constructor + instance = controller() + + def test_001_descriptive_test_name(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_controller) diff --git a/python/qa_debugger.py b/python/qa_debugger.py new file mode 100755 index 0000000..d6820ee --- /dev/null +++ b/python/qa_debugger.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-lora author. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from gnuradio import gr, gr_unittest +# from gnuradio import blocks +try: + from lora import debugger +except ImportError: + import os + import sys + dirname, filename = os.path.split(os.path.abspath(__file__)) + sys.path.append(os.path.join(dirname, "bindings")) + from lora import debugger + +class qa_debugger(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_instance(self): + # FIXME: Test will fail until you pass sensible arguments to the constructor + instance = debugger() + + def test_001_descriptive_test_name(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_debugger) diff --git a/python/qa_decoder.py b/python/qa_decoder.py new file mode 100755 index 0000000..cefc62c --- /dev/null +++ b/python/qa_decoder.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-lora author. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from gnuradio import gr, gr_unittest +# from gnuradio import blocks +try: + from lora import decoder +except ImportError: + import os + import sys + dirname, filename = os.path.split(os.path.abspath(__file__)) + sys.path.append(os.path.join(dirname, "bindings")) + from lora import decoder + +class qa_decoder(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_instance(self): + # FIXME: Test will fail until you pass sensible arguments to the constructor + instance = decoder() + + def test_001_descriptive_test_name(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_decoder) diff --git a/python/qa_message_file_sink.py b/python/qa_message_file_sink.py new file mode 100755 index 0000000..1fd72cf --- /dev/null +++ b/python/qa_message_file_sink.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-lora author. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from gnuradio import gr, gr_unittest +# from gnuradio import blocks +try: + from lora import message_file_sink +except ImportError: + import os + import sys + dirname, filename = os.path.split(os.path.abspath(__file__)) + sys.path.append(os.path.join(dirname, "bindings")) + from lora import message_file_sink + +class qa_message_file_sink(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_instance(self): + # FIXME: Test will fail until you pass sensible arguments to the constructor + instance = message_file_sink() + + def test_001_descriptive_test_name(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_message_file_sink) diff --git a/python/qa_message_socket_sink.py b/python/qa_message_socket_sink.py new file mode 100755 index 0000000..63a2ba8 --- /dev/null +++ b/python/qa_message_socket_sink.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-lora author. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from gnuradio import gr, gr_unittest +# from gnuradio import blocks +try: + from lora import message_socket_sink +except ImportError: + import os + import sys + dirname, filename = os.path.split(os.path.abspath(__file__)) + sys.path.append(os.path.join(dirname, "bindings")) + from lora import message_socket_sink + +class qa_message_socket_sink(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_instance(self): + # FIXME: Test will fail until you pass sensible arguments to the constructor + instance = message_socket_sink() + + def test_001_descriptive_test_name(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_message_socket_sink) diff --git a/python/qa_message_socket_source.py b/python/qa_message_socket_source.py new file mode 100755 index 0000000..51212c7 --- /dev/null +++ b/python/qa_message_socket_source.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-lora author. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +from gnuradio import gr, gr_unittest +# from gnuradio import blocks +try: + from lora import message_socket_source +except ImportError: + import os + import sys + dirname, filename = os.path.split(os.path.abspath(__file__)) + sys.path.append(os.path.join(dirname, "bindings")) + from lora import message_socket_source + +class qa_message_socket_source(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_instance(self): + # FIXME: Test will fail until you pass sensible arguments to the constructor + instance = message_socket_source() + + def test_001_descriptive_test_name(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_message_socket_source)