From 0b4542bb842258c64987039c9acf1768498c5258 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sun, 6 Jun 2021 23:51:54 -0700
Subject: [PATCH 01/24] add License; CMake builds this fine locally
---
.gitignore | 13 +-
CMakeLists.txt | 89 +++++++
LICENSE | 339 +++++++++++++++++++++++++
Readme.md | 6 +-
cmake/CPackInfo.cmake | 73 ++++++
cmake/Cache.cmake | 31 +++
cmake/CompilerWarnings.cmake | 78 ++++++
cmake/GetLibInfo.cmake | 39 +++
cmake/PreventInSourceBuilds.cmake | 18 ++
cmake/StandardProjectSettings.cmake | 37 +++
cmake/detectCPU.cmake | 43 ++++
cmake/pico_sdk_import.cmake | 62 +++++
cmake/toolchains/arm64.cmake | 34 +++
cmake/toolchains/armhf.cmake | 34 +++
cmake/toolchains/default.cmake | 1 +
cmake/toolchains/i686.cmake | 34 +++
cmake/toolchains/x86_64.cmake | 34 +++
examples/CMakeLists.txt | 37 +++
examples/addons/Sniffer/CMakeLists.txt | 13 +
examples/gwNodeInt/CMakeLists.txt | 13 +
examples/ncurses/CMakeLists.txt | 13 +
examples/ncursesInt/CMakeLists.txt | 13 +
22 files changed, 1049 insertions(+), 5 deletions(-)
create mode 100644 CMakeLists.txt
create mode 100644 LICENSE
create mode 100644 cmake/CPackInfo.cmake
create mode 100644 cmake/Cache.cmake
create mode 100644 cmake/CompilerWarnings.cmake
create mode 100644 cmake/GetLibInfo.cmake
create mode 100644 cmake/PreventInSourceBuilds.cmake
create mode 100644 cmake/StandardProjectSettings.cmake
create mode 100644 cmake/detectCPU.cmake
create mode 100644 cmake/pico_sdk_import.cmake
create mode 100644 cmake/toolchains/arm64.cmake
create mode 100644 cmake/toolchains/armhf.cmake
create mode 100644 cmake/toolchains/default.cmake
create mode 100644 cmake/toolchains/i686.cmake
create mode 100644 cmake/toolchains/x86_64.cmake
create mode 100644 examples/CMakeLists.txt
create mode 100644 examples/addons/Sniffer/CMakeLists.txt
create mode 100644 examples/gwNodeInt/CMakeLists.txt
create mode 100644 examples/ncurses/CMakeLists.txt
create mode 100644 examples/ncursesInt/CMakeLists.txt
diff --git a/.gitignore b/.gitignore
index 8fe78b1..b3ddf24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,14 @@
-# ignore doxygen generated files
+# Generated library files
+*.so
+*.so.1
+
+# ignore docs folder
docs/html/
docs/xml/
+
+# ignore CMake stuff
+build/
+*CMakeUserPresets.json
+
+# ignore local vscode folder
+.vscode/
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..4c89691
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,89 @@
+cmake_minimum_required(VERSION 3.15)
+
+# Set the project name to your project name
+project(RF24Gateway C CXX)
+include(cmake/StandardProjectSettings.cmake)
+include(cmake/PreventInSourceBuilds.cmake)
+
+# Link this 'library' to set the c++ standard / compile-time options requested
+add_library(project_options INTERFACE)
+target_compile_features(project_options INTERFACE cxx_std_17)
+add_compile_options(-Ofast -Wall)
+
+# detect CPU and add compiler flags accordingly
+include(cmake/detectCPU.cmake)
+
+if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
+ option(ENABLE_BUILD_WITH_TIME_TRACE "Enable -ftime-trace to generate time tracing .json files on clang" OFF)
+ if(ENABLE_BUILD_WITH_TIME_TRACE)
+ add_compile_definitions(project_options INTERFACE -ftime-trace)
+ endif()
+endif()
+
+# Link this 'library' to use the warnings specified in CompilerWarnings.cmake
+add_library(project_warnings INTERFACE)
+
+# enable cache system
+include(cmake/Cache.cmake)
+
+# standard compiler warnings
+include(cmake/CompilerWarnings.cmake)
+set_project_warnings(project_warnings)
+
+# get library info from Arduino IDE's required library.properties file
+include(cmake/GetLibInfo.cmake) # sets the variable LibTargetName
+
+# setup CPack options
+include(cmake/CPackInfo.cmake)
+
+find_library(RF24 rf24 REQUIRED)
+message(STATUS "using RF24 library: ${RF24}")
+
+find_library(RF24Network rf24network REQUIRED)
+message(STATUS "using RF24Network library: ${RF24Network}")
+
+find_library(RF24Mesh rf24mesh REQUIRED)
+message(STATUS "using RF24Mesh library: ${RF24Mesh}")
+
+###########################
+# create target for bulding the RF24Log lib
+###########################
+add_library(${LibTargetName} SHARED
+ RF24Gateway.cpp
+ )
+target_include_directories(${LibTargetName} PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}
+ )
+
+target_link_libraries(${LibTargetName} INTERFACE
+ project_options
+ project_warnings
+ SHARED ${RF24}
+ SHARED ${RF24Network}
+ SHARED ${RF24Mesh}
+ )
+
+set_target_properties(
+ ${LibTargetName}
+ PROPERTIES
+ SOVERSION ${${LibName}_VERSION_MAJOR}
+ VERSION ${${LibName}_VERSION_STRING}
+ )
+
+###########################
+# target install rules for the RF24Log lib
+###########################
+install(TARGETS ${LibTargetName}
+ DESTINATION lib
+ )
+
+install(FILES
+ RF24Gateway.h
+ DESTINATION include/RF24Gateway
+ )
+
+# CMAKE_CROSSCOMPILING is only TRUE when CMAKE_TOOLCHAIN_FILE is specified via CLI
+if(CMAKE_HOST_UNIX AND "${CMAKE_CROSSCOMPILING}" STREQUAL "FALSE")
+ install(CODE "message(STATUS \"Updating ldconfig\")")
+ install(CODE "execute_process(COMMAND ldconfig)")
+endif()
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..23cb790
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ {description}
+ Copyright (C) {year} {fullname}
+
+ This program 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 2 of the License, or
+ (at your option) any later version.
+
+ This program 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.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ {signature of Ty Coon}, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/Readme.md b/Readme.md
index a521589..e93d102 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,6 +1,4 @@
-
-**RF24Gateway**
-
+## RF24Gateway
A complimentary library to RF24Ethernet, for RPi/Linux devices.
RF24Ethernet allows small Arduino/AVR devices to communicate using TCP/IP over nrf24l01 radio modules.
@@ -8,7 +6,7 @@ RF24Ethernet allows small Arduino/AVR devices to communicate using TCP/IP over n
RF24Gateway allows a RPi/Linux device to act as a gateway for those nodes, handling IP traffic automatically, while allowing users
to utilize standard RF24Network messages as well.
-**Documentation:**
+### Documentation:
http://nRF24.github.io/RF24Gateway
diff --git a/cmake/CPackInfo.cmake b/cmake/CPackInfo.cmake
new file mode 100644
index 0000000..f5c9e3a
--- /dev/null
+++ b/cmake/CPackInfo.cmake
@@ -0,0 +1,73 @@
+# This module will build a debian compatible package to install - handy for cross-compiling
+
+if(NOT PKG_REV)
+ set(PKG_REV "1")
+endif()
+
+# get target arch if not cross-compiling
+if(NOT TARGET_ARCH) # TARGET_ARCH is defined only in the toolchain_.cmake files
+ if(WIN32)
+ set(TARGET_ARCH $ENV{PROCESSOR_ARCHITECTURE})
+ else()
+ execute_process(COMMAND dpkg --print-architecture
+ OUTPUT_VARIABLE TARGET_ARCH
+ )
+ endif()
+ string(STRIP "${TARGET_ARCH}" TARGET_ARCH)
+endif()
+
+# set the Cpack generators (specific to types of packages to create)
+if(NOT WIN32)
+ set(CPACK_GENERATOR DEB RPM) # RPM requires rpmbuild executable
+else()
+ set(CPACK_GENERATOR "") # should find out how to build vcpkg packages
+endif()
+
+# assemble a debian package filename from known info
+include(InstallRequiredSystemLibraries)
+set(CPACK_PACKAGE_FILE_NAME "lib${LibTargetName}_${${LibName}_VERSION_STRING}-${PKG_REV}_${TARGET_ARCH}")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
+set(CPACK_PACKAGE_VERSION_MAJOR "${${LibName}_VERSION_MAJOR}")
+set(CPACK_PACKAGE_VERSION_MINOR "${${LibName}_VERSION_MINOR}")
+set(CPACK_PACKAGE_VERSION_PATCH "${${LibName}_VERSION_PATCH}")
+set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/pkgs") # for easy uploading to github releases
+
+if(NOT WIN32)
+ ###############################
+ # info specific debian packages
+ ###############################
+ set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${TARGET_ARCH})
+ set(CPACK_DEBIAN_PACKAGE_SECTION libs)
+ set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+ set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON)
+
+ ###############################
+ # info specific rpm (fedora) packages
+ ###############################
+ set(CPACK_RPM_FILE_NAME "lib${LibTargetName}-${${LibName}_VERSION_STRING}-${PKG_REV}.${TARGET_ARCH}.rpm")
+ set(CPACK_RPM_PACKAGE_ARCHITECTURE ${TARGET_ARCH})
+ set(CPACK_RPM_PACKAGE_LICENSE "GPLv2.0")
+ set(CPACK_RPM_PACKAGE_VENDOR "Humanity")
+
+ # create a post-install & post-removal scripts to update linker
+ set(POST_SCRIPTS
+ ${CMAKE_BINARY_DIR}/DEBIAN/postrm
+ ${CMAKE_BINARY_DIR}/DEBIAN/postinst
+ )
+ foreach(script ${POST_SCRIPTS})
+ file(WRITE ${script} /sbin/ldconfig)
+ execute_process(COMMAND chmod +x ${script})
+ execute_process(COMMAND chmod 775 ${script})
+ endforeach()
+ # declare scripts for deb pkgs
+ list(JOIN POST_SCRIPTS ";" EXTRA_CTRL_FILES)
+ set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA EXTRA_CTRL_FILES)
+ # declare scripts for rpm pkgs
+ list(POP_FRONT POST_SCRIPTS CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE)
+ list(POP_FRONT POST_SCRIPTS CPACK_RPM_POST_INSTALL_SCRIPT_FILE)
+
+ message(STATUS "ready to package: ${CPACK_PACKAGE_FILE_NAME}.deb")
+ message(STATUS "ready to package: ${CPACK_RPM_FILE_NAME}")
+endif()
+
+include(CPack)
diff --git a/cmake/Cache.cmake b/cmake/Cache.cmake
new file mode 100644
index 0000000..4cc2e8c
--- /dev/null
+++ b/cmake/Cache.cmake
@@ -0,0 +1,31 @@
+option(ENABLE_CACHE "Enable cache if available" ON)
+if(NOT ENABLE_CACHE)
+ return()
+endif()
+
+set(CACHE_OPTION
+ "ccache"
+ CACHE STRING "Compiler cache to be used"
+ )
+set(CACHE_OPTION_VALUES "ccache" "sccache")
+set_property(CACHE CACHE_OPTION PROPERTY STRINGS ${CACHE_OPTION_VALUES})
+list(
+ FIND
+ CACHE_OPTION_VALUES
+ ${CACHE_OPTION}
+ CACHE_OPTION_INDEX
+ )
+
+if(${CACHE_OPTION_INDEX} EQUAL -1)
+ message(STATUS
+ "Using custom compiler cache system: '${CACHE_OPTION}', explicitly supported entries are ${CACHE_OPTION_VALUES}"
+ )
+endif()
+
+find_program(CACHE_BINARY ${CACHE_OPTION})
+if(CACHE_BINARY)
+ message(STATUS "${CACHE_OPTION} found and enabled")
+ set(CMAKE_CXX_COMPILER_LAUNCHER ${CACHE_BINARY})
+else()
+ message(WARNING "${CACHE_OPTION} is enabled but was not found. Not using it")
+endif()
diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake
new file mode 100644
index 0000000..9031160
--- /dev/null
+++ b/cmake/CompilerWarnings.cmake
@@ -0,0 +1,78 @@
+# from here:
+#
+# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md
+
+function(set_project_warnings project_name)
+ option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" TRUE)
+
+ set(MSVC_WARNINGS
+ /W4 # Baseline reasonable warnings
+ /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data
+ /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
+ /w14263 # 'function': member function does not override any base class virtual member function
+ /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not
+ # be destructed correctly
+ /w14287 # 'operator': unsigned/negative constant mismatch
+ /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside
+ # the for-loop scope
+ /w14296 # 'operator': expression is always 'boolean_value'
+ /w14311 # 'variable': pointer truncation from 'type1' to 'type2'
+ /w14545 # expression before comma evaluates to a function which is missing an argument list
+ /w14546 # function call before comma missing argument list
+ /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect
+ /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'?
+ /w14555 # expression has no effect; expected expression with side- effect
+ /w14619 # pragma warning: there is no warning number 'number'
+ /w14640 # Enable warning on thread un-safe static member initialization
+ /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior.
+ /w14905 # wide string literal cast to 'LPSTR'
+ /w14906 # string literal cast to 'LPWSTR'
+ /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied
+ /permissive- # standards conformance mode for MSVC compiler.
+ )
+
+ set(CLANG_WARNINGS
+ -Wall
+ -Wextra # reasonable and standard
+ -Wshadow # warn the user if a variable declaration shadows one from a parent context
+ -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps
+ # catch hard to track down memory errors
+ -Wold-style-cast # warn for c-style casts
+ -Wcast-align # warn for potential performance problem casts
+ -Wunused # warn on anything being unused
+ -Woverloaded-virtual # warn if you overload (not override) a virtual function
+ -Wpedantic # warn if non-standard C++ is used
+ -Wconversion # warn on type conversions that may lose data
+ -Wsign-conversion # warn on sign conversions
+ -Wnull-dereference # warn if a null dereference is detected
+ -Wdouble-promotion # warn if float is implicit promoted to double
+ -Wformat=2 # warn on security issues around functions that format output (ie printf)
+ )
+
+ if(WARNINGS_AS_ERRORS)
+ set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror)
+ set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX)
+ endif()
+
+ set(GCC_WARNINGS
+ ${CLANG_WARNINGS}
+ -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist
+ -Wduplicated-cond # warn if if / else chain has duplicated conditions
+ -Wduplicated-branches # warn if if / else branches have duplicated code
+ -Wlogical-op # warn about logical operations being used where bitwise were probably wanted
+ -Wuseless-cast # warn if you perform a cast to the same type
+ )
+
+ if(MSVC)
+ set(PROJECT_WARNINGS ${MSVC_WARNINGS})
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
+ set(PROJECT_WARNINGS ${CLANG_WARNINGS})
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ set(PROJECT_WARNINGS ${GCC_WARNINGS})
+ else()
+ message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.")
+ endif()
+
+ target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS})
+
+endfunction()
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
new file mode 100644
index 0000000..9ed2bb0
--- /dev/null
+++ b/cmake/GetLibInfo.cmake
@@ -0,0 +1,39 @@
+# get lib info from the git cmds
+execute_process(COMMAND git config --get remote.origin.url OUTPUT_VARIABLE CMAKE_PROJECT_HOMEPAGE_URL)
+string(STRIP CMAKE_PROJECT_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL})
+
+# use URL to get repo owner as Contact/Maintainer name
+string(REGEX REPLACE "^http[s]?://github.com/(.+)/.+\\.git" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
+string(STRIP "${CPACK_PACKAGE_CONTACT}" CPACK_PACKAGE_CONTACT)
+
+# use URL to get the repo name as the Lib Name. Note that we don't use the folder name for this
+string(REGEX REPLACE "^http[s]?://github.com/.+/(.+)\\.git" "\\1" LibName "${CMAKE_PROJECT_HOMEPAGE_URL}")
+string(STRIP "${LibName}" LibName)
+
+# convert the LibName to lower case
+string(TOLOWER ${LibName} LibTargetName)
+
+# have to hard-code the Repo Summary (which is copied from the parent repo's "About" info)
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "TCP/IP (RF24Ethernet) and RF24Network Gateway")
+
+# Use repo README.md to get the project description
+file(READ "README.md" CPACK_PACKAGE_DESCRIPTION)
+string(FIND "${CPACK_PACKAGE_DESCRIPTION}" "## RF24Gateway" README_TITLE)
+math(EXPR README_TITLE "${README_TITLE} + 15") # compensates for '\n' char
+string(FIND "${CPACK_PACKAGE_DESCRIPTION}" "### Documentation" DOC_LINK_TITLE)
+math(EXPR DESCRIPTION_LENGTH "${DOC_LINK_TITLE} - ${README_TITLE}")
+string(SUBSTRING "${CPACK_PACKAGE_DESCRIPTION}" ${README_TITLE} ${DESCRIPTION_LENGTH} CPACK_PACKAGE_DESCRIPTION)
+
+# parse the version information into pieces.
+execute_process(COMMAND git describe --tags OUTPUT_VARIABLE VERSION)
+string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VERSION}")
+string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VERSION}")
+string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VERSION}")
+
+# this is the library version
+set(${LibName}_VERSION_MAJOR ${VERSION_MAJOR})
+set(${LibName}_VERSION_MINOR ${VERSION_MINOR})
+set(${LibName}_VERSION_PATCH ${VERSION_PATCH})
+set(${LibName}_VERSION_STRING ${${LibName}_VERSION_MAJOR}.${${LibName}_VERSION_MINOR}.${${LibName}_VERSION_PATCH})
+
+message(STATUS "${LibName} library version: ${${LibName}_VERSION_STRING}")
diff --git a/cmake/PreventInSourceBuilds.cmake b/cmake/PreventInSourceBuilds.cmake
new file mode 100644
index 0000000..dc4fd81
--- /dev/null
+++ b/cmake/PreventInSourceBuilds.cmake
@@ -0,0 +1,18 @@
+#
+# This function will prevent in-source builds
+function(AssureOutOfSourceBuilds)
+ # make sure the user doesn't play dirty with symlinks
+ get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
+ get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)
+
+ # disallow in-source builds
+ if("${srcdir}" STREQUAL "${bindir}")
+ message("######################################################")
+ message("Warning: in-source builds are disabled")
+ message("Please create a separate build directory and run cmake from there")
+ message("######################################################")
+ message(FATAL_ERROR "Quitting configuration")
+ endif()
+endfunction()
+
+assureoutofsourcebuilds()
diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake
new file mode 100644
index 0000000..0414e99
--- /dev/null
+++ b/cmake/StandardProjectSettings.cmake
@@ -0,0 +1,37 @@
+# Set a default build type if none was specified
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
+ set(CMAKE_BUILD_TYPE
+ RelWithDebInfo
+ CACHE STRING "Choose the type of build." FORCE
+ )
+ # Set the possible values of build type for cmake-gui, ccmake
+ set_property(
+ CACHE CMAKE_BUILD_TYPE
+ PROPERTY STRINGS
+ "Debug"
+ "Release"
+ "MinSizeRel"
+ "RelWithDebInfo"
+ )
+endif()
+
+# Generate compile_commands.json to make it easier to work with clang based tools
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF)
+
+if(ENABLE_IPO)
+ include(CheckIPOSupported)
+ check_ipo_supported(
+ RESULT
+ result
+ OUTPUT
+ output
+ )
+ if(result)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+ else()
+ message(SEND_ERROR "IPO is not supported: ${output}")
+ endif()
+endif()
diff --git a/cmake/detectCPU.cmake b/cmake/detectCPU.cmake
new file mode 100644
index 0000000..ebd7fe7
--- /dev/null
+++ b/cmake/detectCPU.cmake
@@ -0,0 +1,43 @@
+# try to get the CPU model using a Linux bash command
+execute_process(COMMAND cat /proc/cpuinfo
+ OUTPUT_VARIABLE CPU_MODEL
+ )
+
+# If above command is not executed on an actual SOC board (& compatible OS), then
+# there won't be a "Hardware" field to describe the CPU model
+string(FIND ${CPU_MODEL} "Hardware" cpu_info_has_hw_field)
+if(${cpu_info_has_hw_field} GREATER 0) # Hardware field does exist
+ string(SUBSTRING ${CPU_MODEL} ${cpu_info_has_hw_field} -1 CPU_MODEL)
+ string(REGEX MATCH "[ ]+([A-Za-z0-9_])+" SOC ${CPU_MODEL})
+ string(STRIP ${SOC} SOC)
+else() # Hardware field does not exist
+ set(SOC "UNKNOWN") # use this string as a sentinel
+endif()
+
+# detect machine hardware name
+execute_process(COMMAND uname -m
+ OUTPUT_VARIABLE CPU_TYPE)
+string(STRIP "${CPU_TYPE}" CPU_TYPE)
+message(STATUS "detected CPU type: ${CPU_TYPE}")
+
+# add compiler flags to optomize builds with arm-linux-gnueabihf-g* compilers
+if("${CMAKE_C_COMPILER}" STREQUAL "/usr/bin/arm-linux-gnueabihf-gcc" AND
+ "${CMAKE_CXX_COMPILER}" STREQUAL "/usr/bin/arm-linux-gnueabihf-g++")
+ if("${SOC}" STREQUAL "BCM2835")
+ add_compile_options(-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard)
+ elseif("$SOC" STREQUAL "BCM2836")
+ add_compile_options(-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
+ elseif("$SOC" STREQUAL "AM33XX")
+ add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard)
+ elseif("$SOC" STREQUAL "A10")
+ add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard)
+ elseif("$SOC" STREQUAL "A13")
+ add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard)
+ elseif("$SOC" STREQUAL "A20")
+ add_compile_options(-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
+ elseif("$SOC" STREQUAL "H3")
+ add_compile_options(-march=armv8-a -mtune=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard)
+ endif()
+endif()
+
+message(STATUS "detected SoC: ${SOC}")
\ No newline at end of file
diff --git a/cmake/pico_sdk_import.cmake b/cmake/pico_sdk_import.cmake
new file mode 100644
index 0000000..07bd143
--- /dev/null
+++ b/cmake/pico_sdk_import.cmake
@@ -0,0 +1,62 @@
+# This is a copy of /external/pico_sdk_import.cmake
+#
+# This can be dropped into an external project to help locate this SDK
+# It should be include()ed prior to project()
+
+if(DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
+ set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
+ message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
+endif()
+
+if(DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
+ set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
+ message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
+endif()
+
+if(DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
+ set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
+ message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
+endif()
+
+set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
+set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
+set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
+
+if(NOT PICO_SDK_PATH)
+ if(PICO_SDK_FETCH_FROM_GIT)
+ include(FetchContent)
+ set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
+ if(PICO_SDK_FETCH_FROM_GIT_PATH)
+ get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
+ endif()
+ FetchContent_Declare(
+ pico_sdk
+ GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
+ GIT_TAG master
+ )
+ if(NOT pico_sdk)
+ message("Downloading Raspberry Pi Pico SDK")
+ FetchContent_Populate(pico_sdk)
+ set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
+ endif()
+ set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
+ else ()
+ message(FATAL_ERROR
+ "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
+ )
+ endif()
+endif()
+
+get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
+if(NOT EXISTS ${PICO_SDK_PATH})
+ message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
+endif()
+
+set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
+if(NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
+ message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
+endif()
+
+set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
+
+include(${PICO_SDK_INIT_CMAKE_FILE})
diff --git a/cmake/toolchains/arm64.cmake b/cmake/toolchains/arm64.cmake
new file mode 100644
index 0000000..add14e1
--- /dev/null
+++ b/cmake/toolchains/arm64.cmake
@@ -0,0 +1,34 @@
+###################### FOR CROSS-COMPILING using the aarch64-linux-gnu-g** compiler
+# invoke this toolchain file using `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/.cmake`
+# this file is meant to be used generically, but will not work for all CMake projects
+# this toolchain file's cmds was copied from the CMake docs then modified for better explanation and re-use
+
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR arm64)
+set(TARGET_ARCH arm64) # only used in cmake/createDebianPkg.cmake
+set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
+set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
+
+# CMAKE_SYSROOT can only be set in a toolchain file
+# set(CMAKE_SYSROOT /usr/aarch64-linux-gnu) # useful when a target machine's files are available
+
+# set the directory for searching installed headers
+# add_compile_options(-I /usr/aarch64-linux-gnu/include) # this may not be best practice
+
+#[[
+# CMAKE_STAGING_PREFIX is only useful for transfering a built CMake project to a target machine
+set(CMAKE_STAGING_PREFIX /home/devel/stage) # use CMAKE_INSTALL_PREFIX instead (see below comments)
+
+CMAKE_FIND_ROOT_PATH is an empty list by default (this list can be modified where applicable)
+if cross-compiling a dependent lib (like MRAA - which is optional), then
+set the lib's CMAKE_INSTALL_PREFIX to a value that is appended to RF24 lib's CMAKE_FIND_ROOT_PATH
+example using MRAA:
+(for MRAA/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=path/to/RF24/repo/cmake/toolchains/arm64.cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/aarch64-linux-gnu
+(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm64.cmake
+]]
+list(APPEND CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu)
+# message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_package() is called
diff --git a/cmake/toolchains/armhf.cmake b/cmake/toolchains/armhf.cmake
new file mode 100644
index 0000000..f1611f2
--- /dev/null
+++ b/cmake/toolchains/armhf.cmake
@@ -0,0 +1,34 @@
+###################### FOR CROSS-COMPILING using the arm-linux-gnueabihf-g** compiler
+# invoke this toolchain file using `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/.cmake`
+# this file is meant to be used generically, but will not work for all CMake projects
+# this toolchain file's cmds was copied from the CMake docs then modified for better explanation and re-use
+
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR armhf)
+set(TARGET_ARCH armhf) # only used in cmake/CPackInfo.cmake
+set(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc)
+set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++)
+
+# CMAKE_SYSROOT can only be set in a toolchain file
+# set(CMAKE_SYSROOT /usr/arm-linux-gnueabihf) # useful when a target machine's files are available
+
+# set the directory for searching installed headers
+# add_compile_options(-I /usr/arm-linux-gnueabihf/include) # this may not be best practice
+
+#[[
+# CMAKE_STAGING_PREFIX is only useful for transfering a built CMake project to a target machine
+set(CMAKE_STAGING_PREFIX /home/devel/stage) # use CMAKE_INSTALL_PREFIX instead (see below comments)
+
+CMAKE_FIND_ROOT_PATH is an empty list by default (this list can be modified where applicable)
+if cross-compiling a dependent lib (like MRAA - which is optional), then
+set the lib's CMAKE_INSTALL_PREFIX to a value that is appended to RF24 lib's CMAKE_FIND_ROOT_PATH
+example using MRAA:
+(for MRAA/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=path/to/RF24/repo/cmake/toolchains/arm.cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/arm-linux-gnueabihf
+(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm.cmake
+]]
+list(APPEND CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf)
+# message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_package() is called
diff --git a/cmake/toolchains/default.cmake b/cmake/toolchains/default.cmake
new file mode 100644
index 0000000..e67d723
--- /dev/null
+++ b/cmake/toolchains/default.cmake
@@ -0,0 +1 @@
+# empty toolchain file to allow CI scripts to still use system default toolchains
\ No newline at end of file
diff --git a/cmake/toolchains/i686.cmake b/cmake/toolchains/i686.cmake
new file mode 100644
index 0000000..344fd8b
--- /dev/null
+++ b/cmake/toolchains/i686.cmake
@@ -0,0 +1,34 @@
+###################### FOR CROSS-COMPILING using the i686-linux-gnu-g** compiler
+# invoke this toolchain file using `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/.cmake`
+# this file is meant to be used generically, but will not work for all CMake projects
+# this toolchain file's cmds was copied from the CMake docs then modified for better explanation and re-use
+
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR i686)
+set(TARGET_ARCH i686) # only used in cmake/createDebianPkg.cmake
+set(CMAKE_C_COMPILER /usr/bin/i686-linux-gnu-gcc)
+set(CMAKE_CXX_COMPILER /usr/bin/i686-linux-gnu-g++)
+
+# CMAKE_SYSROOT can only be set in a toolchain file
+# set(CMAKE_SYSROOT /usr/i686-linux-gnu) # useful when a target machine's files are available
+
+# set the directory for searching installed headers
+# add_compile_options(-I /usr/i686-linux-gnu/include) # this may not be best practice
+
+#[[
+# CMAKE_STAGING_PREFIX is only useful for transfering a built CMake project to a target machine
+set(CMAKE_STAGING_PREFIX /home/devel/stage) # use CMAKE_INSTALL_PREFIX instead (see below comments)
+
+CMAKE_FIND_ROOT_PATH is an empty list by default (this list can be modified where applicable)
+if cross-compiling a dependent lib (like MRAA - which is optional), then
+set the lib's CMAKE_INSTALL_PREFIX to a value that is appended to RF24 lib's CMAKE_FIND_ROOT_PATH
+example using MRAA:
+(for MRAA/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=path/to/RF24/repo/cmake/toolchains/i686.cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/i686-linux-gnu
+(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/i686.cmake
+]]
+list(APPEND CMAKE_FIND_ROOT_PATH /usr/i686-linux-gnu)
+# message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_package() is called
diff --git a/cmake/toolchains/x86_64.cmake b/cmake/toolchains/x86_64.cmake
new file mode 100644
index 0000000..b75ab3f
--- /dev/null
+++ b/cmake/toolchains/x86_64.cmake
@@ -0,0 +1,34 @@
+###################### FOR CROSS-COMPILING using the x86_64-linux-gnux32-g** compiler
+# invoke this toolchain file using `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/.cmake`
+# this file is meant to be used generically, but will not work for all CMake projects
+# this toolchain file's cmds was copied from the CMake docs then modified for better explanation and re-use
+
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR x86_64)
+set(TARGET_ARCH x86_64) # only used in cmake/createDebianPkg.cmake
+set(CMAKE_C_COMPILER /usr/bin/x86_64-linux-gnux32-gcc)
+set(CMAKE_CXX_COMPILER /usr/bin/x86_64-linux-gnux32-g++)
+
+# CMAKE_SYSROOT can only be set in a toolchain file
+# set(CMAKE_SYSROOT /usr/x86_64-linux-gnux32) # useful when a target machine's files are available
+
+# set the directory for searching installed headers
+# add_compile_options(-I /usr/x86_64-linux-gnux32/include) # this may not be best practice
+
+#[[
+# CMAKE_STAGING_PREFIX is only useful for transfering a built CMake project to a target machine
+set(CMAKE_STAGING_PREFIX /home/devel/stage) # use CMAKE_INSTALL_PREFIX instead (see below comments)
+
+CMAKE_FIND_ROOT_PATH is an empty list by default (this list can be modified where applicable)
+if cross-compiling a dependent lib (like MRAA - which is optional), then
+set the lib's CMAKE_INSTALL_PREFIX to a value that is appended to RF24 lib's CMAKE_FIND_ROOT_PATH
+example using MRAA:
+(for MRAA/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=path/to/RF24/repo/cmake/toolchains/x86_64.cmake -D CMAKE_INSTALL_PREFIX:PATH=/usr/x86_64-linux-gnux32
+(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/x86_64.cmake
+]]
+list(APPEND CMAKE_FIND_ROOT_PATH /usr/x86_64-linux-gnux32)
+# message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_package() is called
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644
index 0000000..aa71032
--- /dev/null
+++ b/examples/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.12)
+
+project(RF24GatewayExamples)
+add_compile_options(-Ofast -Wall) # passing the compiler a `-pthread` flag doesn't work here
+
+# detect the CPU make and type
+include(../cmake/detectCPU.cmake) # sets the variable SOC accordingly
+
+find_library(RF24 rf24 REQUIRED)
+message(STATUS "using RF24 library: ${RF24}")
+
+find_library(RF24Network rf24network REQUIRED)
+message(STATUS "using RF24Network library: ${RF24Network}")
+
+find_library(RF24Mesh rf24mesh REQUIRED)
+message(STATUS "using RF24Mesh library: ${RF24Mesh}")
+
+find_library(RF24Gateway rf24gateway REQUIRED)
+message(STATUS "using RF24Gateway library: ${RF24Gateway}")
+
+set(example RF24GatewayNode)
+# make a target
+add_executable(${example} ${example}.cpp)
+
+# link the RF24 lib to the target. Notice we specify pthread as a linked lib here
+target_link_libraries(${example} PUBLIC
+ ${RF24}
+ pthread
+ ${RF24Network}
+ ${RF24Mesh}
+ ${RF24Gateway}
+ )
+
+add_subdirectory(ncurses)
+add_subdirectory(ncursesInt)
+add_subdirectory(gwNodeInt)
+add_subdirectory(addons/Sniffer)
diff --git a/examples/addons/Sniffer/CMakeLists.txt b/examples/addons/Sniffer/CMakeLists.txt
new file mode 100644
index 0000000..2b83a3f
--- /dev/null
+++ b/examples/addons/Sniffer/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(example Sniffer)
+
+# make a target
+add_executable(${example} ${example}.cpp)
+
+# link the RF24 lib to the target. Notice we specify pthread as a linked lib here
+target_link_libraries(${example} PUBLIC
+ ${RF24}
+ pthread
+ ${RF24Network}
+ ${RF24Mesh}
+ ${RF24Gateway}
+ )
diff --git a/examples/gwNodeInt/CMakeLists.txt b/examples/gwNodeInt/CMakeLists.txt
new file mode 100644
index 0000000..572690a
--- /dev/null
+++ b/examples/gwNodeInt/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(example RF24GatewayNodeInt)
+
+# make a target
+add_executable(${example} ${example}.cpp)
+
+# link the RF24 lib to the target. Notice we specify pthread as a linked lib here
+target_link_libraries(${example} PUBLIC
+ ${RF24}
+ pthread
+ ${RF24Network}
+ ${RF24Mesh}
+ ${RF24Gateway}
+ )
diff --git a/examples/ncurses/CMakeLists.txt b/examples/ncurses/CMakeLists.txt
new file mode 100644
index 0000000..4e7751f
--- /dev/null
+++ b/examples/ncurses/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(example RF24Gateway_ncurses)
+
+# make a target
+add_executable(${example} ${example}.cpp)
+
+# link the RF24 lib to the target. Notice we specify pthread as a linked lib here
+target_link_libraries(${example} PUBLIC
+ ${RF24}
+ pthread
+ ${RF24Network}
+ ${RF24Mesh}
+ ${RF24Gateway}
+ )
diff --git a/examples/ncursesInt/CMakeLists.txt b/examples/ncursesInt/CMakeLists.txt
new file mode 100644
index 0000000..b27803e
--- /dev/null
+++ b/examples/ncursesInt/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(example RF24Gateway_ncursesInt)
+
+# make a target
+add_executable(${example} ${example}.cpp)
+
+# link the RF24 lib to the target. Notice we specify pthread as a linked lib here
+target_link_libraries(${example} PUBLIC
+ ${RF24}
+ pthread
+ ${RF24Network}
+ ${RF24Mesh}
+ ${RF24Gateway}
+ )
From 0da85b42781732e153afc14e4746164adea0e2c5 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 00:30:26 -0700
Subject: [PATCH 02/24] add linux_build CI
---
.github/workflows/build_linux.yml | 164 ++++++++++++++++++++++++++++++
1 file changed, 164 insertions(+)
create mode 100644 .github/workflows/build_linux.yml
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
new file mode 100644
index 0000000..bb82c24
--- /dev/null
+++ b/.github/workflows/build_linux.yml
@@ -0,0 +1,164 @@
+name: Linux build
+
+on:
+ pull_request:
+ types: [opened, reopened]
+ push:
+ release:
+ types: [published, edited]
+
+env:
+ # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
+ BUILD_TYPE: Release
+
+jobs:
+ using_cmake:
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+
+ matrix:
+ toolchain:
+ - compiler: "armhf"
+ usr_dir: "arm-linux-gnueabihf"
+ - compiler: "arm64"
+ usr_dir: "aarch64-linux-gnu"
+ # - compiler: "x86_64"
+ # usr_dir: "x86_64-linux-gnux32"
+ # - compiler: "i686"
+ # usr_dir: "i686-linux-gnu"
+ - compiler: "default" # github runner is hosted on a "amd64"
+ usr_dir: "local"
+
+ steps:
+ - name: install rpmbuild
+ run: sudo apt-get install rpm
+
+ # - name: provide toolchain (for x86_64)
+ # if: ${{ matrix.toolchain.compiler == 'x86_64' }}
+ # run: |
+ # sudo apt-get update
+ # sudo apt-get install gcc-x86-64-linux-gnux32 g++-x86-64-linux-gnux32
+
+ # - name: provide toolchain (for i686)
+ # if: ${{ matrix.toolchain.compiler == 'i686' }}
+ # run: |
+ # sudo apt-get update
+ # sudo apt-get install gcc-i686-linux-gnu g++-i686-linux-gnu
+
+ - name: provide toolchain (for arm64)
+ if: ${{ matrix.toolchain.compiler == 'arm64' }}
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
+
+ - name: provide toolchain (for armhf)
+ if: ${{ matrix.toolchain.compiler == 'armhf' }}
+ run: |
+ sudo apt-get update
+ sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
+
+ - name: checkout RF24
+ uses: actions/checkout@v2
+ with:
+ repository: nRF24/RF24
+ ref: rp2xxx
+
+ - name: build & install RF24
+ run: |
+ mkdir build
+ cd build
+ cmake .. -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D RF24_DRIVER=SPIDEV \
+ -D CMAKE_INSTALL_PREFIX=/usr/${{ matrix.toolchain.usr_dir }} \
+ -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/${{ matrix.toolchain.compiler }}.cmake
+ sudo make install
+
+ - name: checkout RF24Network
+ uses: actions/checkout@v2
+ with:
+ repository: nRF24/RF24Network
+ ref: CMake-4-Linux
+
+ - name: build & install RF24Network
+ run: |
+ mkdir build
+ cd build
+ cmake .. -D CMAKE_BUILD_TYPE=$BUILD_TYPE \
+ -D CMAKE_INSTALL_PREFIX=/usr/${{ matrix.toolchain.usr_dir }} \
+ -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/${{ matrix.toolchain.compiler }}.cmake
+ sudo make install
+
+ - name: checkout RF24Mesh
+ uses: actions/checkout@v2
+
+ - name: build & install RF24Mesh
+ run: |
+ mkdir build
+ cd build
+ cmake .. -D CMAKE_BUILD_TYPE=$BUILD_TYPE \
+ -D CMAKE_INSTALL_PREFIX=/usr/${{ matrix.toolchain.usr_dir }} \
+ -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/${{ matrix.toolchain.compiler }}.cmake
+ sudo make install
+
+ - name: checkout RF24Gateway
+ uses: actions/checkout@v2
+
+ - name: create CMake build environment
+ run: cmake -E make_directory ${{ github.workspace }}/build
+
+ - name: configure lib
+ if: ${{ matrix.toolchain.compiler == 'default' }}
+ working-directory: ${{ github.workspace }}/build
+ run: cmake .. -D CMAKE_BUILD_TYPE=$BUILD_TYPE
+
+ - name: configure lib (with toolchain compilers)
+ if: ${{ matrix.toolchain.compiler != 'default' }}
+ working-directory: ${{ github.workspace }}/build
+ run: |
+ cmake .. -D CMAKE_BUILD_TYPE=$BUILD_TYPE \
+ -D CMAKE_INSTALL_PREFIX=/usr/${{ matrix.toolchain.usr_dir }} \
+ -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/${{ matrix.toolchain.compiler }}.cmake
+
+ - name: build lib
+ working-directory: ${{ github.workspace }}/build
+ run: cmake --build .
+
+ - name: install lib
+ working-directory: ${{ github.workspace }}/build
+ run: sudo cmake --install .
+
+ - name: package lib
+ working-directory: ${{ github.workspace }}/build
+ run: sudo cpack
+
+ - name: Save artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: "pkg_RF24Mesh"
+ path: |
+ ${{ github.workspace }}/build/pkgs/*.deb
+ ${{ github.workspace }}/build/pkgs/*.rpm
+
+ - name: Upload Release assets
+ if: github.event_name == 'release' && (matrix.toolchain.compiler == 'armhf' || matrix.toolchain.compiler == 'arm64')
+ uses: csexton/release-asset-action@master
+ with:
+ pattern: "${{ github.workspace }}/build/pkgs/librf24*"
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: clean build environment
+ working-directory: ${{ github.workspace }}/build
+ run: sudo rm -r ./*
+
+ - name: configure examples
+ working-directory: ${{ github.workspace }}/build
+ run: |
+ cmake ../examples \
+ -D CMAKE_TOOLCHAIN_FILE=../cmake/toolchains/${{ matrix.toolchain.compiler }}.cmake
+
+ - name: build examples (none that use ncurses)
+ working-directory: ${{ github.workspace }}/build
+ run: |
+ cmake --build . --target RF24GatewayNode --target Sniffer --target RF24GatewayNodeInt
+ file ./RF24GatewayNode
From 8c50a95f8c57907520e05381812d709d92fbfadd Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 00:31:56 -0700
Subject: [PATCH 03/24] oops! c-n-p much?
---
.github/workflows/build_linux.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index bb82c24..f409fd7 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -91,6 +91,8 @@ jobs:
- name: checkout RF24Mesh
uses: actions/checkout@v2
+ repository: nRF24/RF24Mesh
+ ref: CMake-4-Linux
- name: build & install RF24Mesh
run: |
From 9df2a8ff4df681c7e418be7cb52cba7f68b89d13 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 00:33:19 -0700
Subject: [PATCH 04/24] [LinuxCI] forgot the "with:" line
---
.github/workflows/build_linux.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index f409fd7..d54e65c 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -91,6 +91,7 @@ jobs:
- name: checkout RF24Mesh
uses: actions/checkout@v2
+ with:
repository: nRF24/RF24Mesh
ref: CMake-4-Linux
From c610e095f0f9ccc052255b0e36c5e63c9a8f86f5 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 00:35:36 -0700
Subject: [PATCH 05/24] linux FS is case sensitive
---
cmake/GetLibInfo.cmake | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
index 9ed2bb0..639e792 100644
--- a/cmake/GetLibInfo.cmake
+++ b/cmake/GetLibInfo.cmake
@@ -17,7 +17,7 @@ string(TOLOWER ${LibName} LibTargetName)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "TCP/IP (RF24Ethernet) and RF24Network Gateway")
# Use repo README.md to get the project description
-file(READ "README.md" CPACK_PACKAGE_DESCRIPTION)
+file(READ "Readme.md" CPACK_PACKAGE_DESCRIPTION)
string(FIND "${CPACK_PACKAGE_DESCRIPTION}" "## RF24Gateway" README_TITLE)
math(EXPR README_TITLE "${README_TITLE} + 15") # compensates for '\n' char
string(FIND "${CPACK_PACKAGE_DESCRIPTION}" "### Documentation" DOC_LINK_TITLE)
From 5def5e40146f64cd86c1bf73d9401761adf86a1c Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 00:43:09 -0700
Subject: [PATCH 06/24] this will fail in CI; I need to debug it more
---
cmake/GetLibInfo.cmake | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
index 639e792..71eb161 100644
--- a/cmake/GetLibInfo.cmake
+++ b/cmake/GetLibInfo.cmake
@@ -1,7 +1,7 @@
# get lib info from the git cmds
execute_process(COMMAND git config --get remote.origin.url OUTPUT_VARIABLE CMAKE_PROJECT_HOMEPAGE_URL)
string(STRIP CMAKE_PROJECT_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL})
-
+message("URL = ${CMAKE_PROJECT_HOMEPAGE_URL}")
# use URL to get repo owner as Contact/Maintainer name
string(REGEX REPLACE "^http[s]?://github.com/(.+)/.+\\.git" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
string(STRIP "${CPACK_PACKAGE_CONTACT}" CPACK_PACKAGE_CONTACT)
From 5109a132edd0e1f9aab527f87efba0882c1110f9 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 01:19:53 -0700
Subject: [PATCH 07/24] use regex to detect if returned url ends with .git
---
cmake/GetLibInfo.cmake | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
index 71eb161..f1479de 100644
--- a/cmake/GetLibInfo.cmake
+++ b/cmake/GetLibInfo.cmake
@@ -1,13 +1,13 @@
# get lib info from the git cmds
execute_process(COMMAND git config --get remote.origin.url OUTPUT_VARIABLE CMAKE_PROJECT_HOMEPAGE_URL)
string(STRIP CMAKE_PROJECT_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL})
-message("URL = ${CMAKE_PROJECT_HOMEPAGE_URL}")
+
# use URL to get repo owner as Contact/Maintainer name
-string(REGEX REPLACE "^http[s]?://github.com/(.+)/.+\\.git" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
+string(REGEX REPLACE "^http[s]?://github.com/(.+)/.+[\\.git]?.*&" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
string(STRIP "${CPACK_PACKAGE_CONTACT}" CPACK_PACKAGE_CONTACT)
# use URL to get the repo name as the Lib Name. Note that we don't use the folder name for this
-string(REGEX REPLACE "^http[s]?://github.com/.+/(.+)\\.git" "\\1" LibName "${CMAKE_PROJECT_HOMEPAGE_URL}")
+string(REGEX REPLACE "^http[s]?://github.com/.+/(.+)[\\.git]?.*&" "\\1" LibName "${CMAKE_PROJECT_HOMEPAGE_URL}")
string(STRIP "${LibName}" LibName)
# convert the LibName to lower case
From eabc7af12cfa83a67c5100de328bad9e0c5f355f Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 01:35:07 -0700
Subject: [PATCH 08/24] better regex pattern
---
cmake/GetLibInfo.cmake | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
index f1479de..3bd2dd9 100644
--- a/cmake/GetLibInfo.cmake
+++ b/cmake/GetLibInfo.cmake
@@ -3,11 +3,11 @@ execute_process(COMMAND git config --get remote.origin.url OUTPUT_VARIABLE CMAKE
string(STRIP CMAKE_PROJECT_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL})
# use URL to get repo owner as Contact/Maintainer name
-string(REGEX REPLACE "^http[s]?://github.com/(.+)/.+[\\.git]?.*&" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
+string(REGEX REPLACE "^http[s]?:\/\/github.com\/(.+)\/.+[\\.git]?.*" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
string(STRIP "${CPACK_PACKAGE_CONTACT}" CPACK_PACKAGE_CONTACT)
# use URL to get the repo name as the Lib Name. Note that we don't use the folder name for this
-string(REGEX REPLACE "^http[s]?://github.com/.+/(.+)[\\.git]?.*&" "\\1" LibName "${CMAKE_PROJECT_HOMEPAGE_URL}")
+string(REGEX REPLACE "^http[s]?:\/\/github\\.com\/.+\/(.+)[\\.git]?.*" "\\1" LibName "${CMAKE_PROJECT_HOMEPAGE_URL}")
string(STRIP "${LibName}" LibName)
# convert the LibName to lower case
From 6a91d3f8d4fd32f1b21f841adde947081e05d9d8 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 01:57:13 -0700
Subject: [PATCH 09/24] show me what `git describe` returns on GH runner
---
cmake/GetLibInfo.cmake | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
index 3bd2dd9..b982659 100644
--- a/cmake/GetLibInfo.cmake
+++ b/cmake/GetLibInfo.cmake
@@ -3,7 +3,7 @@ execute_process(COMMAND git config --get remote.origin.url OUTPUT_VARIABLE CMAKE
string(STRIP CMAKE_PROJECT_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL})
# use URL to get repo owner as Contact/Maintainer name
-string(REGEX REPLACE "^http[s]?:\/\/github.com\/(.+)\/.+[\\.git]?.*" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
+string(REGEX REPLACE "^http[s]?:\/\/github\\.com\/(.+)\/.+[\\.git]?.*" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
string(STRIP "${CPACK_PACKAGE_CONTACT}" CPACK_PACKAGE_CONTACT)
# use URL to get the repo name as the Lib Name. Note that we don't use the folder name for this
@@ -25,7 +25,15 @@ math(EXPR DESCRIPTION_LENGTH "${DOC_LINK_TITLE} - ${README_TITLE}")
string(SUBSTRING "${CPACK_PACKAGE_DESCRIPTION}" ${README_TITLE} ${DESCRIPTION_LENGTH} CPACK_PACKAGE_DESCRIPTION)
# parse the version information into pieces.
-execute_process(COMMAND git describe --tags OUTPUT_VARIABLE VERSION)
+execute_process(COMMAND git describe --tags
+ OUTPUT_VARIABLE VERSION
+ ERROR_VARIABLE GIT_DESCRIBE_FAIL
+ )
+if(${GIT_DESCRIBE_FAIL})
+ message(FATAL "`git describe --tags` failed with: ${GIT_DESCRIBE_FAIL}")
+else()
+ message("git describes the version tag as ${VERSION}")
+endif()
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VERSION}")
From 4a05041314bcbc2853bd5da6a956dc67585f7693 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 02:03:07 -0700
Subject: [PATCH 10/24] try with fetch-depth = 0
---
.github/workflows/build_linux.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index d54e65c..85ef24f 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -106,6 +106,8 @@ jobs:
- name: checkout RF24Gateway
uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
- name: create CMake build environment
run: cmake -E make_directory ${{ github.workspace }}/build
From ee7b259e01c71e6460050853ca2b7c1178191a27 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 02:05:34 -0700
Subject: [PATCH 11/24] that worked; remove debug prompts
---
cmake/GetLibInfo.cmake | 10 +---------
1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
index b982659..251afc9 100644
--- a/cmake/GetLibInfo.cmake
+++ b/cmake/GetLibInfo.cmake
@@ -25,15 +25,7 @@ math(EXPR DESCRIPTION_LENGTH "${DOC_LINK_TITLE} - ${README_TITLE}")
string(SUBSTRING "${CPACK_PACKAGE_DESCRIPTION}" ${README_TITLE} ${DESCRIPTION_LENGTH} CPACK_PACKAGE_DESCRIPTION)
# parse the version information into pieces.
-execute_process(COMMAND git describe --tags
- OUTPUT_VARIABLE VERSION
- ERROR_VARIABLE GIT_DESCRIBE_FAIL
- )
-if(${GIT_DESCRIBE_FAIL})
- message(FATAL "`git describe --tags` failed with: ${GIT_DESCRIBE_FAIL}")
-else()
- message("git describes the version tag as ${VERSION}")
-endif()
+execute_process(COMMAND git describe --tags OUTPUT_VARIABLE VERSION)
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VERSION}")
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VERSION}")
From c3965855f01de247c8f1868e8eeb7455470529a2 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Mon, 7 Jun 2021 02:06:32 -0700
Subject: [PATCH 12/24] [no ci] rename workflow assets DL file
---
.github/workflows/build_linux.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index 85ef24f..bd4c48a 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -140,7 +140,7 @@ jobs:
- name: Save artifact
uses: actions/upload-artifact@v2
with:
- name: "pkg_RF24Mesh"
+ name: "pkg_RF24Gateway"
path: |
${{ github.workspace }}/build/pkgs/*.deb
${{ github.workspace }}/build/pkgs/*.rpm
From 029709e2881f92b2862bc79cc8be786199fe43bd Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sat, 12 Jun 2021 04:51:26 -0700
Subject: [PATCH 13/24] [no ci] code fmt; prep rename casing of READMEs
---
.github/workflows/build_linux.yml | 16 +
.github/workflows/doxygen.yml | 29 +-
CMakeLists.txt | 18 +-
Readme.md => READM.md | 0
cmake/CPackInfo.cmake | 68 +-
cmake/Cache.cmake | 14 +-
cmake/CompilerWarnings.cmake | 6 +-
cmake/GetLibInfo.cmake | 20 +-
cmake/StandardProjectSettings.cmake | 16 +-
cmake/detectCPU.cmake | 87 +-
cmake/enableNcursesExample.cmake | 15 +
cmake/pico_sdk_import.cmake | 4 +-
cmake/toolchains/arm64.cmake | 1 -
cmake/toolchains/armhf.cmake | 1 -
cmake/toolchains/i686.cmake | 1 -
cmake/toolchains/x86_64.cmake | 1 -
docs/{README.md => READM.md} | 0
examples/CMakeLists.txt | 10 +-
examples/{README.txt => READM.txt} | 0
examples/RF24GatewayNode.cpp | 139 +--
examples/addons/{README.md => READM.md} | 0
examples/addons/Sniffer/Sniffer.cpp | 100 +-
.../BashClient/{readme.md => READM.md} | 0
.../NodeJSClient/{readme.md => READM.md} | 0
.../PythonClient/{readme.md => READM.md} | 0
examples/clients/{readme.md => READM.md} | 0
examples/ncurses/CMakeLists.txt | 7 +-
examples/ncurses/RF24Gateway_ncurses.cpp | 1021 ++++++++--------
examples/ncursesInt/CMakeLists.txt | 7 +-
.../ncursesInt/RF24Gateway_ncursesInt.cpp | 1068 +++++++++--------
30 files changed, 1439 insertions(+), 1210 deletions(-)
rename Readme.md => READM.md (100%)
create mode 100644 cmake/enableNcursesExample.cmake
rename docs/{README.md => READM.md} (100%)
rename examples/{README.txt => READM.txt} (100%)
rename examples/addons/{README.md => READM.md} (100%)
rename examples/clients/BashClient/{readme.md => READM.md} (100%)
rename examples/clients/NodeJSClient/{readme.md => READM.md} (100%)
rename examples/clients/PythonClient/{readme.md => READM.md} (100%)
rename examples/clients/{readme.md => READM.md} (100%)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index bd4c48a..c2b8aaa 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -3,7 +3,23 @@ name: Linux build
on:
pull_request:
types: [opened, reopened]
+ paths:
+ - '*.h'
+ - '*.cpp'
+ - 'CMakeLists.txt'
+ - 'cmake/**'
+ - 'examples/**.cpp'
+ - '!**Makefile' # old build system is not tested in this workflow
+ - '.github/workflows/build_linux.yml'
push:
+ paths:
+ - '*.h'
+ - '*.cpp'
+ - 'CMakeLists.txt'
+ - 'cmake/**'
+ - 'examples/**.cpp'
+ - '!**Makefile' # old build system is not tested in this workflow
+ - '.github/workflows/build_linux.yml'
release:
types: [published, edited]
diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml
index 032b251..37a8b09 100644
--- a/.github/workflows/doxygen.yml
+++ b/.github/workflows/doxygen.yml
@@ -2,17 +2,28 @@ name: DoxyGen build
on:
pull_request:
- branches:
- - master
+ branches: [master]
+ paths:
+ - '*.h'
+ - '*.md'
+ - 'docs/**'
+ - '!**README.md'
+ - 'examples**.cpp'
+ - '.github/workflows/doxygen.yml'
+ - 'Doxyfile'
push:
- branches:
- - master
+ branches: [master]
+ paths:
+ - '*.h'
+ - '*.md'
+ - 'docs/**'
+ - '!**README.md'
+ - 'examples**.cpp'
+ - '.github/workflows/doxygen.yml'
+ - 'Doxyfile'
release:
- branches:
- - master
- types:
- - published
- - edited
+ branches: [master]
+ types: [published, edited]
jobs:
build-doxygen:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4c89691..5ce4426 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,12 +48,8 @@ message(STATUS "using RF24Mesh library: ${RF24Mesh}")
###########################
# create target for bulding the RF24Log lib
###########################
-add_library(${LibTargetName} SHARED
- RF24Gateway.cpp
- )
-target_include_directories(${LibTargetName} PUBLIC
- ${CMAKE_CURRENT_LIST_DIR}
- )
+add_library(${LibTargetName} SHARED RF24Gateway.cpp)
+target_include_directories(${LibTargetName} PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(${LibTargetName} INTERFACE
project_options
@@ -61,26 +57,24 @@ target_link_libraries(${LibTargetName} INTERFACE
SHARED ${RF24}
SHARED ${RF24Network}
SHARED ${RF24Mesh}
- )
+)
set_target_properties(
${LibTargetName}
PROPERTIES
SOVERSION ${${LibName}_VERSION_MAJOR}
VERSION ${${LibName}_VERSION_STRING}
- )
+)
###########################
# target install rules for the RF24Log lib
###########################
-install(TARGETS ${LibTargetName}
- DESTINATION lib
- )
+install(TARGETS ${LibTargetName} DESTINATION lib)
install(FILES
RF24Gateway.h
DESTINATION include/RF24Gateway
- )
+)
# CMAKE_CROSSCOMPILING is only TRUE when CMAKE_TOOLCHAIN_FILE is specified via CLI
if(CMAKE_HOST_UNIX AND "${CMAKE_CROSSCOMPILING}" STREQUAL "FALSE")
diff --git a/Readme.md b/READM.md
similarity index 100%
rename from Readme.md
rename to READM.md
diff --git a/cmake/CPackInfo.cmake b/cmake/CPackInfo.cmake
index f5c9e3a..172fd2d 100644
--- a/cmake/CPackInfo.cmake
+++ b/cmake/CPackInfo.cmake
@@ -11,7 +11,7 @@ if(NOT TARGET_ARCH) # TARGET_ARCH is defined only in the toolchain_.c
else()
execute_process(COMMAND dpkg --print-architecture
OUTPUT_VARIABLE TARGET_ARCH
- )
+ )
endif()
string(STRIP "${TARGET_ARCH}" TARGET_ARCH)
endif()
@@ -32,42 +32,40 @@ set(CPACK_PACKAGE_VERSION_MINOR "${${LibName}_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${${LibName}_VERSION_PATCH}")
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/pkgs") # for easy uploading to github releases
-if(NOT WIN32)
- ###############################
- # info specific debian packages
- ###############################
- set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${TARGET_ARCH})
- set(CPACK_DEBIAN_PACKAGE_SECTION libs)
- set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
- set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON)
+###############################
+# info specific debian packages
+###############################
+set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${TARGET_ARCH})
+set(CPACK_DEBIAN_PACKAGE_SECTION libs)
+set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
+set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON)
- ###############################
- # info specific rpm (fedora) packages
- ###############################
- set(CPACK_RPM_FILE_NAME "lib${LibTargetName}-${${LibName}_VERSION_STRING}-${PKG_REV}.${TARGET_ARCH}.rpm")
- set(CPACK_RPM_PACKAGE_ARCHITECTURE ${TARGET_ARCH})
- set(CPACK_RPM_PACKAGE_LICENSE "GPLv2.0")
- set(CPACK_RPM_PACKAGE_VENDOR "Humanity")
+###############################
+# info specific rpm (fedora) packages
+###############################
+set(CPACK_RPM_FILE_NAME "lib${LibTargetName}-${${LibName}_VERSION_STRING}-${PKG_REV}.${TARGET_ARCH}.rpm")
+set(CPACK_RPM_PACKAGE_ARCHITECTURE ${TARGET_ARCH})
+set(CPACK_RPM_PACKAGE_LICENSE "GPLv2.0")
+set(CPACK_RPM_PACKAGE_VENDOR "Humanity")
- # create a post-install & post-removal scripts to update linker
- set(POST_SCRIPTS
- ${CMAKE_BINARY_DIR}/DEBIAN/postrm
- ${CMAKE_BINARY_DIR}/DEBIAN/postinst
- )
- foreach(script ${POST_SCRIPTS})
- file(WRITE ${script} /sbin/ldconfig)
- execute_process(COMMAND chmod +x ${script})
- execute_process(COMMAND chmod 775 ${script})
- endforeach()
- # declare scripts for deb pkgs
- list(JOIN POST_SCRIPTS ";" EXTRA_CTRL_FILES)
- set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA EXTRA_CTRL_FILES)
- # declare scripts for rpm pkgs
- list(POP_FRONT POST_SCRIPTS CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE)
- list(POP_FRONT POST_SCRIPTS CPACK_RPM_POST_INSTALL_SCRIPT_FILE)
+# create a post-install & post-removal scripts to update linker
+set(POST_SCRIPTS
+ ${CMAKE_BINARY_DIR}/DEBIAN/postrm
+ ${CMAKE_BINARY_DIR}/DEBIAN/postinst
+)
+foreach(script ${POST_SCRIPTS})
+ file(WRITE ${script} /sbin/ldconfig)
+ execute_process(COMMAND chmod +x ${script})
+ execute_process(COMMAND chmod 775 ${script})
+endforeach()
+# declare scripts for deb pkgs
+list(JOIN POST_SCRIPTS ";" EXTRA_CTRL_FILES)
+set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA EXTRA_CTRL_FILES)
+# declare scripts for rpm pkgs
+list(POP_FRONT POST_SCRIPTS CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE)
+list(POP_FRONT POST_SCRIPTS CPACK_RPM_POST_INSTALL_SCRIPT_FILE)
- message(STATUS "ready to package: ${CPACK_PACKAGE_FILE_NAME}.deb")
- message(STATUS "ready to package: ${CPACK_RPM_FILE_NAME}")
-endif()
+message(STATUS "ready to package: ${CPACK_PACKAGE_FILE_NAME}.deb")
+message(STATUS "ready to package: ${CPACK_RPM_FILE_NAME}")
include(CPack)
diff --git a/cmake/Cache.cmake b/cmake/Cache.cmake
index 4cc2e8c..8e7ae63 100644
--- a/cmake/Cache.cmake
+++ b/cmake/Cache.cmake
@@ -3,23 +3,15 @@ if(NOT ENABLE_CACHE)
return()
endif()
-set(CACHE_OPTION
- "ccache"
- CACHE STRING "Compiler cache to be used"
- )
+set(CACHE_OPTION "ccache" CACHE STRING "Compiler cache to be used")
set(CACHE_OPTION_VALUES "ccache" "sccache")
set_property(CACHE CACHE_OPTION PROPERTY STRINGS ${CACHE_OPTION_VALUES})
-list(
- FIND
- CACHE_OPTION_VALUES
- ${CACHE_OPTION}
- CACHE_OPTION_INDEX
- )
+list(FIND CACHE_OPTION_VALUES ${CACHE_OPTION} CACHE_OPTION_INDEX)
if(${CACHE_OPTION_INDEX} EQUAL -1)
message(STATUS
"Using custom compiler cache system: '${CACHE_OPTION}', explicitly supported entries are ${CACHE_OPTION_VALUES}"
- )
+ )
endif()
find_program(CACHE_BINARY ${CACHE_OPTION})
diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake
index 9031160..af36206 100644
--- a/cmake/CompilerWarnings.cmake
+++ b/cmake/CompilerWarnings.cmake
@@ -29,7 +29,7 @@ function(set_project_warnings project_name)
/w14906 # string literal cast to 'LPWSTR'
/w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied
/permissive- # standards conformance mode for MSVC compiler.
- )
+ )
set(CLANG_WARNINGS
-Wall
@@ -47,7 +47,7 @@ function(set_project_warnings project_name)
-Wnull-dereference # warn if a null dereference is detected
-Wdouble-promotion # warn if float is implicit promoted to double
-Wformat=2 # warn on security issues around functions that format output (ie printf)
- )
+ )
if(WARNINGS_AS_ERRORS)
set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror)
@@ -61,7 +61,7 @@ function(set_project_warnings project_name)
-Wduplicated-branches # warn if if / else branches have duplicated code
-Wlogical-op # warn about logical operations being used where bitwise were probably wanted
-Wuseless-cast # warn if you perform a cast to the same type
- )
+ )
if(MSVC)
set(PROJECT_WARNINGS ${MSVC_WARNINGS})
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
index 251afc9..6a58fc6 100644
--- a/cmake/GetLibInfo.cmake
+++ b/cmake/GetLibInfo.cmake
@@ -1,14 +1,20 @@
# get lib info from the git cmds
-execute_process(COMMAND git config --get remote.origin.url OUTPUT_VARIABLE CMAKE_PROJECT_HOMEPAGE_URL)
-string(STRIP CMAKE_PROJECT_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL})
+execute_process(COMMAND git config --get remote.origin.url
+ OUTPUT_VARIABLE CMAKE_PROJECT_HOMEPAGE_URL
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+string(FIND "${CMAKE_PROJECT_HOMEPAGE_URL}" ".git" has_git_ext REVERSE)
+if(has_git_ext GREATER -1)
+ string(SUBSTRING "${CMAKE_PROJECT_HOMEPAGE_URL}" 0 ${has_git_ext} CMAKE_PROJECT_HOMEPAGE_URL)
+endif()
# use URL to get repo owner as Contact/Maintainer name
-string(REGEX REPLACE "^http[s]?:\/\/github\\.com\/(.+)\/.+[\\.git]?.*" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
-string(STRIP "${CPACK_PACKAGE_CONTACT}" CPACK_PACKAGE_CONTACT)
+string(REGEX REPLACE "^http[s]?:\/\/github\\.com\/(.+)\/.+$" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
+# string(STRIP "${CPACK_PACKAGE_CONTACT}" CPACK_PACKAGE_CONTACT)
# use URL to get the repo name as the Lib Name. Note that we don't use the folder name for this
-string(REGEX REPLACE "^http[s]?:\/\/github\\.com\/.+\/(.+)[\\.git]?.*" "\\1" LibName "${CMAKE_PROJECT_HOMEPAGE_URL}")
-string(STRIP "${LibName}" LibName)
+string(REGEX REPLACE "^http[s]?:\/\/github\\.com\/.+\/(.+)$" "\\1" LibName "${CMAKE_PROJECT_HOMEPAGE_URL}")
+# string(STRIP "${LibName}" LibName)
# convert the LibName to lower case
string(TOLOWER ${LibName} LibTargetName)
@@ -17,7 +23,7 @@ string(TOLOWER ${LibName} LibTargetName)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "TCP/IP (RF24Ethernet) and RF24Network Gateway")
# Use repo README.md to get the project description
-file(READ "Readme.md" CPACK_PACKAGE_DESCRIPTION)
+file(READ "README.md" CPACK_PACKAGE_DESCRIPTION)
string(FIND "${CPACK_PACKAGE_DESCRIPTION}" "## RF24Gateway" README_TITLE)
math(EXPR README_TITLE "${README_TITLE} + 15") # compensates for '\n' char
string(FIND "${CPACK_PACKAGE_DESCRIPTION}" "### Documentation" DOC_LINK_TITLE)
diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake
index 0414e99..75a379f 100644
--- a/cmake/StandardProjectSettings.cmake
+++ b/cmake/StandardProjectSettings.cmake
@@ -1,10 +1,10 @@
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
- message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
+ message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE
- RelWithDebInfo
+ Release
CACHE STRING "Choose the type of build." FORCE
- )
+ )
# Set the possible values of build type for cmake-gui, ccmake
set_property(
CACHE CMAKE_BUILD_TYPE
@@ -13,7 +13,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
"Release"
"MinSizeRel"
"RelWithDebInfo"
- )
+ )
endif()
# Generate compile_commands.json to make it easier to work with clang based tools
@@ -24,11 +24,9 @@ option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimizati
if(ENABLE_IPO)
include(CheckIPOSupported)
check_ipo_supported(
- RESULT
- result
- OUTPUT
- output
- )
+ RESULT result
+ OUTPUT output
+ )
if(result)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
diff --git a/cmake/detectCPU.cmake b/cmake/detectCPU.cmake
index ebd7fe7..bd702f9 100644
--- a/cmake/detectCPU.cmake
+++ b/cmake/detectCPU.cmake
@@ -1,43 +1,78 @@
# try to get the CPU model using a Linux bash command
-execute_process(COMMAND cat /proc/cpuinfo
- OUTPUT_VARIABLE CPU_MODEL
- )
+if(NOT SOC) # if SOC variable not defined by user at CLI
+ if(EXISTS "/sys/class/sunxi_info/sys_info")
+ execute_process(COMMAND grep sunxi_platform /sys/class/sunxi_info/sys_info
+ OUTPUT_VARIABLE CPU_MODEL
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ else()
+ execute_process(COMMAND grep Hardware /proc/cpuinfo
+ OUTPUT_VARIABLE CPU_MODEL
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ endif()
-# If above command is not executed on an actual SOC board (& compatible OS), then
-# there won't be a "Hardware" field to describe the CPU model
-string(FIND ${CPU_MODEL} "Hardware" cpu_info_has_hw_field)
-if(${cpu_info_has_hw_field} GREATER 0) # Hardware field does exist
- string(SUBSTRING ${CPU_MODEL} ${cpu_info_has_hw_field} -1 CPU_MODEL)
- string(REGEX MATCH "[ ]+([A-Za-z0-9_])+" SOC ${CPU_MODEL})
- string(STRIP ${SOC} SOC)
-else() # Hardware field does not exist
- set(SOC "UNKNOWN") # use this string as a sentinel
+ string(FIND "${CPU_MODEL}" ":" cpu_is_described)
+ if(${cpu_is_described} GREATER 0) # Hardware field does exist
+ math(EXPR cpu_is_described "${cpu_is_described} + 1")
+ string(SUBSTRING "${CPU_MODEL}" ${cpu_is_described} -1 SOC)
+ string(STRIP "${SOC}" SOC)
+ else() # Hardware field does not exist
+ set(SOC "UNKNOWN") # use this string as a sentinel
+ endif()
+ message(STATUS "detected SoC: ${SOC}")
+else()
+ message(STATUS "SOC set to ${SOC}")
endif()
-# detect machine hardware name
+string(FIND "${SOC}" "Generic AM33XX" is_AM33XX)
+
+#[[ detect machine hardware name
+This CPU_TYPE variable is not used anywhere.
+It remains as useful prompt info & to be consistent with old build system ]]
execute_process(COMMAND uname -m
- OUTPUT_VARIABLE CPU_TYPE)
-string(STRIP "${CPU_TYPE}" CPU_TYPE)
+ OUTPUT_VARIABLE CPU_TYPE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
message(STATUS "detected CPU type: ${CPU_TYPE}")
+# identify the compiler base name for customizing flags
+# THIS ONLY WORKS/TESTED FOR GNU COMPILERS
+if(NOT CMAKE_CROSSCOMPILING) # need to use /usr/lib/gcc soft symlink
+ # NOTE the following command doesn't work with " | tail -1" appended
+ execute_process(COMMAND ls /usr/lib/gcc
+ OUTPUT_VARIABLE tool_name
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ # use only last entry if multiple entries are returned
+ string(FIND "${tool_name}" "\n" last_list_delimiter REVERSE)
+ if(last_list_delimiter GREATER -1)
+ math(EXPR last_list_delimiter "${last_list_delimiter} + 1")
+ string(SUBSTRING "${tool_name}" ${last_list_delimiter} -1 tool_name)
+ endif()
+
+else() # we can use the compiler's name of the path set in the toolchain file
+ string(REGEX REPLACE "^\/usr\/bin\/(.*)-gcc.*" "\\1" tool_name "${CMAKE_C_COMPILER}")
+endif()
+
+message(STATUS "tool name being used is ${tool_name}")
+
# add compiler flags to optomize builds with arm-linux-gnueabihf-g* compilers
-if("${CMAKE_C_COMPILER}" STREQUAL "/usr/bin/arm-linux-gnueabihf-gcc" AND
- "${CMAKE_CXX_COMPILER}" STREQUAL "/usr/bin/arm-linux-gnueabihf-g++")
- if("${SOC}" STREQUAL "BCM2835")
+if("${tool_name}" STREQUAL "arm-linux-gnueabihf")
+ if("${SOC}" STREQUAL "BCM2835" OR "${SOC}" STREQUAL "BCM2708")
add_compile_options(-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard)
- elseif("$SOC" STREQUAL "BCM2836")
+ elseif("$SOC" STREQUAL "BCM2836" OR "${SOC}" STREQUAL "BCM2709")
add_compile_options(-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
- elseif("$SOC" STREQUAL "AM33XX")
+ elseif(${is_AM33XX} GREATER -1)
add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard)
- elseif("$SOC" STREQUAL "A10")
+ elseif("$SOC" STREQUAL "sun4i" OR "${SOC}" STREQUAL "Sun4iw1p1") # A10
add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard)
- elseif("$SOC" STREQUAL "A13")
+ elseif("$SOC" STREQUAL "sun5i" OR "${SOC}" STREQUAL "Sun4iw2p1") # A13
add_compile_options(-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard)
- elseif("$SOC" STREQUAL "A20")
+ elseif("$SOC" STREQUAL "sun7i" OR "${SOC}" STREQUAL "Sun8iw2p1") # A20
add_compile_options(-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
- elseif("$SOC" STREQUAL "H3")
+ elseif("$SOC" STREQUAL "sun8i" OR "${SOC}" STREQUAL "Sun8iw7p1") # H3
add_compile_options(-march=armv8-a -mtune=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard)
endif()
endif()
-
-message(STATUS "detected SoC: ${SOC}")
\ No newline at end of file
diff --git a/cmake/enableNcursesExample.cmake b/cmake/enableNcursesExample.cmake
new file mode 100644
index 0000000..b016787
--- /dev/null
+++ b/cmake/enableNcursesExample.cmake
@@ -0,0 +1,15 @@
+find_package(Curses)
+if(Curses_FOUND)
+ include_directories(${CURSES_INCLUDE_DIR})
+ option(BUILD_NCURSES_EXAMPLE
+ "Enable/Disable building the ncurses example (requires libncurses5-dev installed)"
+ ON
+ )
+else()
+ message(STATUS "libncurses5-dev not found. Skipping ncurses example")
+ option(BUILD_NCURSES_EXAMPLE
+ "Enable/Disable building the ncurses example (requires libncurses5-dev installed)"
+ OFF
+ )
+endif()
+message(STATUS "BUILD_NCURSES_EXAMPLE set to ${BUILD_NCURSES_EXAMPLE}")
diff --git a/cmake/pico_sdk_import.cmake b/cmake/pico_sdk_import.cmake
index 07bd143..0a1da56 100644
--- a/cmake/pico_sdk_import.cmake
+++ b/cmake/pico_sdk_import.cmake
@@ -33,7 +33,7 @@ if(NOT PICO_SDK_PATH)
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
- )
+ )
if(NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
@@ -43,7 +43,7 @@ if(NOT PICO_SDK_PATH)
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
- )
+ )
endif()
endif()
diff --git a/cmake/toolchains/arm64.cmake b/cmake/toolchains/arm64.cmake
index add14e1..23e41ca 100644
--- a/cmake/toolchains/arm64.cmake
+++ b/cmake/toolchains/arm64.cmake
@@ -27,7 +27,6 @@ example using MRAA:
(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm64.cmake
]]
list(APPEND CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu)
-# message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called
diff --git a/cmake/toolchains/armhf.cmake b/cmake/toolchains/armhf.cmake
index f1611f2..488b81a 100644
--- a/cmake/toolchains/armhf.cmake
+++ b/cmake/toolchains/armhf.cmake
@@ -27,7 +27,6 @@ example using MRAA:
(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm.cmake
]]
list(APPEND CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf)
-# message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called
diff --git a/cmake/toolchains/i686.cmake b/cmake/toolchains/i686.cmake
index 344fd8b..f3c42be 100644
--- a/cmake/toolchains/i686.cmake
+++ b/cmake/toolchains/i686.cmake
@@ -27,7 +27,6 @@ example using MRAA:
(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/i686.cmake
]]
list(APPEND CMAKE_FIND_ROOT_PATH /usr/i686-linux-gnu)
-# message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called
diff --git a/cmake/toolchains/x86_64.cmake b/cmake/toolchains/x86_64.cmake
index b75ab3f..e4ff737 100644
--- a/cmake/toolchains/x86_64.cmake
+++ b/cmake/toolchains/x86_64.cmake
@@ -27,7 +27,6 @@ example using MRAA:
(for RF24/build dir) `cmake .. -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/x86_64.cmake
]]
list(APPEND CMAKE_FIND_ROOT_PATH /usr/x86_64-linux-gnux32)
-# message("CMAKE_FIND_ROOT_PATH = ${CMAKE_FIND_ROOT_PATH}")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # search CMAKE_SYSROOT when find_program() is called
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_library() is called
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # search CMAKE_FIND_ROOT_PATH entries when find_file() is called
diff --git a/docs/README.md b/docs/READM.md
similarity index 100%
rename from docs/README.md
rename to docs/READM.md
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index aa71032..b8ab01e 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -29,9 +29,13 @@ target_link_libraries(${example} PUBLIC
${RF24Network}
${RF24Mesh}
${RF24Gateway}
- )
+)
-add_subdirectory(ncurses)
-add_subdirectory(ncursesInt)
add_subdirectory(gwNodeInt)
add_subdirectory(addons/Sniffer)
+
+include(../cmake/enableNcursesExample.cmake)
+if(BUILD_NCURSES_EXAMPLE)
+ add_subdirectory(ncurses)
+ add_subdirectory(ncursesInt)
+endif()
diff --git a/examples/README.txt b/examples/READM.txt
similarity index 100%
rename from examples/README.txt
rename to examples/READM.txt
diff --git a/examples/RF24GatewayNode.cpp b/examples/RF24GatewayNode.cpp
index 048cfab..372375e 100644
--- a/examples/RF24GatewayNode.cpp
+++ b/examples/RF24GatewayNode.cpp
@@ -1,81 +1,82 @@
-
-
#include
#include
-#include
+#include
#include
-//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
-RF24 radio(22,0);
+RF24 radio(22, 0);
RF24Network network(radio);
-RF24Mesh mesh(radio,network);
-RF24Gateway gw(radio,network,mesh);
+RF24Mesh mesh(radio, network);
+RF24Gateway gw(radio, network, mesh);
uint32_t mesh_timer = 0;
-int main(int argc, char** argv) {
+int main(int argc, char **argv)
+{
- //Config for use with RF24Mesh as Master Node
- //uint8_t nodeID=0;
- gw.begin();
+ //Config for use with RF24Mesh as Master Node
+ //uint8_t nodeID=0;
+ gw.begin();
- //Config for use with RF24Mesh as child Node
- // uint8_t nodeID = 2;
- // gw.begin(nodeID);
-
-
- //Config for use without RF24Mesh
- // uint16_t RF24NetworkAddress = 0;
- // gw.begin(RF24NetworkAddress);
-
- //Set this to your chosen IP/Subnet
- char ip[] = "10.10.2.2";
- char subnet[] = "255.255.255.0";
-
- gw.setIP(ip,subnet);
- uint32_t failCounter = 0;
-
- while(1){
-
- // The gateway handles all IP traffic (marked as EXTERNAL_DATA_TYPE) and passes it to the associated network interface
- // RF24Network user payloads are loaded into the user cache
- gw.update();
- if( network.available() ){
- RF24NetworkHeader header;
- size_t size = network.peek(header);
- uint8_t buf[size];
- network.read(header,&buf,size);
- printf("Received Network Message, type: %d id %d from %d\n",header.type,header.id,mesh.getNodeID(header.from_node));
-
- RF24NetworkFrame frame = RF24NetworkFrame(header,buf,size);
- gw.sendUDP(mesh.getNodeID(header.from_node),frame);
-
- }
- delay(2);
-
- if(millis()-mesh_timer > 30000 && mesh.getNodeID()){ //Every 30 seconds, test mesh connectivity
- mesh_timer = millis();
- if( ! mesh.checkConnection() ){
- //refresh the network address
- mesh.renewAddress();
- }
- }
- //This section checks for failures detected by RF24 & RF24Network as well as
- //checking for deviations from the default configuration (1MBPS data rate)
- //The mesh is restarted on failure and failure count logged to failLog.txt
- //This makes the radios hot-swappable, disconnect & reconnect as desired, it should come up automatically
- if(radio.failureDetected > 0 || radio.getDataRate() != RF24_1MBPS){
- radio.failureDetected = 0;
- std::ofstream myFile;
- myFile.open ("failLog.txt");
- if (myFile.is_open()){
- myFile << ++failCounter << "\n";
- myFile.close();
- }
- delay(500);
- mesh.begin();
+ //Config for use with RF24Mesh as child Node
+ // uint8_t nodeID = 2;
+ // gw.begin(nodeID);
+
+ //Config for use without RF24Mesh
+ // uint16_t RF24NetworkAddress = 0;
+ // gw.begin(RF24NetworkAddress);
+
+ //Set this to your chosen IP/Subnet
+ char ip[] = "10.10.2.2";
+ char subnet[] = "255.255.255.0";
+
+ gw.setIP(ip, subnet);
+ uint32_t failCounter = 0;
+
+ while (1)
+ {
+
+ // The gateway handles all IP traffic (marked as EXTERNAL_DATA_TYPE) and passes it to the associated network interface
+ // RF24Network user payloads are loaded into the user cache
+ gw.update();
+ if (network.available())
+ {
+ RF24NetworkHeader header;
+ size_t size = network.peek(header);
+ uint8_t buf[size];
+ network.read(header, &buf, size);
+ printf("Received Network Message, type: %d id %d from %d\n", header.type, header.id, mesh.getNodeID(header.from_node));
+
+ RF24NetworkFrame frame = RF24NetworkFrame(header, buf, size);
+ gw.sendUDP(mesh.getNodeID(header.from_node), frame);
+ }
+ delay(2);
+
+ if (millis() - mesh_timer > 30000 && mesh.getNodeID())
+ { //Every 30 seconds, test mesh connectivity
+ mesh_timer = millis();
+ if (!mesh.checkConnection())
+ {
+ //refresh the network address
+ mesh.renewAddress();
+ }
+ }
+ //This section checks for failures detected by RF24 & RF24Network as well as
+ //checking for deviations from the default configuration (1MBPS data rate)
+ //The mesh is restarted on failure and failure count logged to failLog.txt
+ //This makes the radios hot-swappable, disconnect & reconnect as desired, it should come up automatically
+ if (radio.failureDetected > 0 || radio.getDataRate() != RF24_1MBPS)
+ {
+ radio.failureDetected = 0;
+ std::ofstream myFile;
+ myFile.open("failLog.txt");
+ if (myFile.is_open())
+ {
+ myFile << ++failCounter << "\n";
+ myFile.close();
+ }
+ delay(500);
+ mesh.begin();
+ }
}
-
- }
- return 0;
+ return 0;
}
diff --git a/examples/addons/README.md b/examples/addons/READM.md
similarity index 100%
rename from examples/addons/README.md
rename to examples/addons/READM.md
diff --git a/examples/addons/Sniffer/Sniffer.cpp b/examples/addons/Sniffer/Sniffer.cpp
index d9ab0c2..b22f792 100644
--- a/examples/addons/Sniffer/Sniffer.cpp
+++ b/examples/addons/Sniffer/Sniffer.cpp
@@ -1,76 +1,72 @@
-
/*
RF24Network Scanner by TMRh20 Aug 2016
Outputs data to console & UDP port 32001
See the LUA script for Wireshark at https://github.com/TMRh20/RF24Gateway/tree/master/examples/addons
-
+
Impersonate any RF24Network/RF24Mesh/RF24Gateway node & scan traffic without disruption to the network
*/
#include
#include
-#include
+#include
#include
-//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
-RF24 radio(25,0);
+RF24 radio(22, 0);
RF24Network network(radio);
-RF24Mesh mesh(radio,network);
-RF24Gateway gw(radio,network,mesh);
+RF24Mesh mesh(radio, network);
+RF24Gateway gw(radio, network, mesh);
uint8_t buffer[1000][32];
int sizes[1000];
int buffCtr = 0;
uint32_t mesh_timer = 0;
+int main(int argc, char **argv)
+{
+ radio.begin();
+ radio.setAutoAck(0);
+ // Because AutoAck is disabled, and we are not transmitting any payloads, we will not interfere with the network
+ // Setup this node as a clone of any network node to scan for all payloads passing to or through that node
+ gw.begin();
-int main(int argc, char** argv) {
+ while (1)
+ {
+ // Buffer all payloads while the radio has data
+ while (radio.available())
+ {
+ sizes[buffCtr] = radio.getDynamicPayloadSize();
+ radio.read(&buffer[buffCtr][0], sizes[buffCtr]);
+ ++buffCtr;
+ }
- radio.begin();
- radio.setAutoAck(0);
-
- // Because AutoAck is disabled, and we are not transmitting any payloads, we will not interfere with the network
- // Setup this node as a clone of any network node to scan for all payloads passing to or through that node
- gw.begin();
-
-
-
- while(1){
-
- // Buffer all payloads while the radio has data
- while(radio.available()){
- sizes[buffCtr] = radio.getDynamicPayloadSize();
- radio.read(&buffer[buffCtr][0],sizes[buffCtr]);
- ++buffCtr;
- }
-
- // Dissect and print the data
- if(buffCtr){
- for(int i=0; i
* a: Interface statistics from /proc/net/dev
* b: RF24Mesh address/id assignments
* c: RF24Network/Radio information
* d: Active IP connections (optional)
*
-* **Requirements: NCurses**
+* **Requirements: NCurses**
* Install NCurses: apt-get install libncurses5-dev
*
* **Controls**
@@ -21,7 +19,7 @@
#include
#include
-#include
+#include
#include
#include
@@ -46,507 +44,586 @@
/******************************************************************/
-RF24 radio(22,0);
+RF24 radio(22, 0);
RF24Network network(radio);
-RF24Mesh mesh(radio,network);
-RF24Gateway gw(radio,network,mesh);
+RF24Mesh mesh(radio, network);
+RF24Gateway gw(radio, network, mesh);
/******************************************************************/
-WINDOW * win;
-WINDOW * meshPad;
-WINDOW * connPad;
-WINDOW * devPad;
-WINDOW * rf24Pad;
-WINDOW * cfgPad;
-WINDOW * renewPad;
-
- void drawMain(void);
- void drawHelp(void);
- void drawCfg(bool isConf);
-
- void drawDevPad(void);
- void drawMeshPad(void);
- void drawConnPad(void);
- void drawRF24Pad(void);
-
- int maxX,maxY;
- int padSelection = 0;
- int meshScroll = 0;
- int connScroll = 0;
- int rf24Scroll = 0;
- unsigned long updateRate = 1000;
-
- uint32_t meshInfoTimer = 0;
- uint32_t mesh_timer = 0;
- std::string subIP;
- std::string tunStr ("tun_nrf24");
- bool showConnPad;
-
- size_t bRX;
- size_t bTX;
-
-
-/******************************************************************/
-/***********************MAIN***************************************/
-
-int main() {
-
- gw.begin();
- mesh.setStaticAddress(8,1);
-
- //uint8_t nodeID = 22;
- //gw.begin(nodeID,3,RF24_2MBPS);
-
- //uint16_t address = 0;
- //gw.begin(address,3,RF24_2MBPS);
-
- /** Setup NCurses**/
- /*******************************/
- win = initscr();
- cbreak();
- noecho();
- getmaxyx(win,maxX,maxY);
-
- start_color();
- curs_set(0);
- init_pair(1, COLOR_GREEN, COLOR_BLACK);
- init_pair(2, COLOR_RED, COLOR_BLACK);
-
- /** Setup Pads**/
- /*******************************/
- devPad = newpad(11,40);
- meshPad = newpad(50,50);
- rf24Pad = newpad(11,40);
- connPad = newpad(21,150);
- cfgPad = newpad(10,40);
- renewPad = newpad(1,35);
-
- scrollok(meshPad,true);
- scrollok(connPad,true);
- scrollok(rf24Pad,true);
- timeout(0);
-
- drawMain();
-
-
-
-/******************************************************************/
-/***********************LOOP***************************************/
-bool ok = true;
-uint32_t failCounter = 0;
-
- while(1){
-
- /**
- * The gateway handles all IP traffic (marked as EXTERNAL_DATA_TYPE) and passes it to the associated network interface
- * RF24Network user payloads are loaded into the user cache
- */
-
- if(millis()-mesh_timer > 30000 && mesh.getNodeID()){ //Every 30 seconds, test mesh connectivity
- mesh_timer = millis();
- if( ! mesh.checkConnection() ){
- wclear(renewPad);
- mvwprintw(renewPad,0,0,"*Renewing Address*");
- prefresh(renewPad,0,0, 3,26, 4, 55);
- if( (ok = mesh.renewAddress()) ){
- wclear(renewPad);
- prefresh(renewPad,0,0, 3,26, 3, 55);
+WINDOW *win;
+WINDOW *meshPad;
+WINDOW *connPad;
+WINDOW *devPad;
+WINDOW *rf24Pad;
+WINDOW *cfgPad;
+WINDOW *renewPad;
+
+void drawMain(void);
+void drawHelp(void);
+void drawCfg(bool isConf);
+
+void drawDevPad(void);
+void drawMeshPad(void);
+void drawConnPad(void);
+void drawRF24Pad(void);
+
+int maxX, maxY;
+int padSelection = 0;
+int meshScroll = 0;
+int connScroll = 0;
+int rf24Scroll = 0;
+unsigned long updateRate = 1000;
+
+uint32_t meshInfoTimer = 0;
+uint32_t mesh_timer = 0;
+std::string subIP;
+std::string tunStr("tun_nrf24");
+bool showConnPad;
+
+size_t bRX;
+size_t bTX;
+
+/******************************************************************/
+/***********************MAIN***************************************/
+
+int main()
+{
+
+ gw.begin();
+ mesh.setStaticAddress(8, 1);
+
+ //uint8_t nodeID = 22;
+ //gw.begin(nodeID,3,RF24_2MBPS);
+
+ //uint16_t address = 0;
+ //gw.begin(address,3,RF24_2MBPS);
+
+ /** Setup NCurses**/
+ /*******************************/
+ win = initscr();
+ cbreak();
+ noecho();
+ getmaxyx(win, maxX, maxY);
+
+ start_color();
+ curs_set(0);
+ init_pair(1, COLOR_GREEN, COLOR_BLACK);
+ init_pair(2, COLOR_RED, COLOR_BLACK);
+
+ /** Setup Pads**/
+ /*******************************/
+ devPad = newpad(11, 40);
+ meshPad = newpad(50, 50);
+ rf24Pad = newpad(11, 40);
+ connPad = newpad(21, 150);
+ cfgPad = newpad(10, 40);
+ renewPad = newpad(1, 35);
+
+ scrollok(meshPad, true);
+ scrollok(connPad, true);
+ scrollok(rf24Pad, true);
+ timeout(0);
+
+ drawMain();
+
+ /******************************************************************/
+ /***********************LOOP***************************************/
+ bool ok = true;
+ uint32_t failCounter = 0;
+
+ while (1)
+ {
+
+ /**
+ * The gateway handles all IP traffic (marked as EXTERNAL_DATA_TYPE) and passes it to the associated network interface
+ * RF24Network user payloads are loaded into the user cache
+ */
+
+ if (millis() - mesh_timer > 30000 && mesh.getNodeID())
+ { //Every 30 seconds, test mesh connectivity
+ mesh_timer = millis();
+ if (!mesh.checkConnection())
+ {
+ wclear(renewPad);
+ mvwprintw(renewPad, 0, 0, "*Renewing Address*");
+ prefresh(renewPad, 0, 0, 3, 26, 4, 55);
+ if ((ok = mesh.renewAddress()))
+ {
+ wclear(renewPad);
+ prefresh(renewPad, 0, 0, 3, 26, 3, 55);
+ }
+ }
+ }
+ if (ok)
+ {
+ gw.update();
+
+ /** Read RF24Network Payloads (Do nothing with them currently) **/
+ /*******************************/
+ if (network.available())
+ {
+ RF24NetworkHeader header;
+ size_t size = network.peek(header);
+ uint8_t buf[size];
+
+ if (header.type == 1)
+ {
+ struct timeStruct
+ {
+ uint8_t hr;
+ uint8_t min;
+ } myTime;
+
+ time_t mTime;
+ time(&mTime);
+ struct tm *tm = localtime(&mTime);
+
+ myTime.hr = tm->tm_hour;
+ myTime.min = tm->tm_min;
+ RF24NetworkHeader hdr(header.from_node, 1);
+ network.write(hdr, &myTime, sizeof(myTime));
+ }
+ network.read(header, &buf, size);
+ }
+ }
+
+ /** Mesh address/id printout **/
+ /*******************************/
+ if (millis() - meshInfoTimer > updateRate)
+ {
+
+ getmaxyx(win, maxX, maxY);
+
+ // Draw the pads on screen
+ drawDevPad();
+ prefresh(devPad, 0, 0, 4, 1, 14, 25);
+
+ drawMeshPad();
+ wscrl(meshPad, meshScroll);
+ prefresh(meshPad, 0, 0, 4, 26, 14, 47);
+
+ drawRF24Pad();
+ prefresh(rf24Pad, 0, 0, 4, 51, 14, 73);
+
+ if (showConnPad)
+ {
+ drawConnPad();
+ wscrl(connPad, connScroll);
+ prefresh(connPad, 0, 0, 15, 1, maxX - 1, maxY - 2);
+ }
+ } //MeshInfo Timer
+
+ /** Handle keyboard input **/
+ /*******************************/
+ int myChar = getch();
+
+ if (myChar > -1)
+ {
+ //cout << myChar << endl;
+ switch (myChar)
+ {
+ // a: En/Disable display of active connections
+ case 'a':
+ showConnPad = !showConnPad;
+ if (!showConnPad)
+ {
+ wclear(connPad);
+ prefresh(connPad, 0, 0, 15, 1, maxX - 1, maxY - 2);
+ drawMain();
+ }
+ break;
+ // w: Increase frame-rate of curses display
+ case 'w':
+ if (updateRate > 100)
+ {
+ updateRate -= 100;
+ }
+ mvwprintw(win, 2, 27, "Refresh Rate: %.1f fps", 1000.0 / updateRate);
+ refresh();
+ break;
+ // s: Decrease frame-rate of curses display
+ case 's':
+ updateRate += 100;
+ mvwprintw(win, 2, 27, "Refresh Rate: %.1f fps \t", 1000.0 / updateRate);
+ refresh();
+ break;
+ // c: Display IP configuration menu
+ case 'c':
+ drawCfg(1);
+ break;
+ // h: Display help menu
+ case 'h':
+ drawHelp();
+ break;
+ case 'x':
+ clear();
+ endwin();
+ return 0;
+ break;
+ case 'A':
+ if (padSelection == 0)
+ {
+ meshScroll++;
+ }
+ else if (padSelection == 1)
+ {
+ connScroll++;
+ }
+ break;
+ case 'B':
+ if (padSelection == 0)
+ {
+ meshScroll--;
+ }
+ else if (padSelection == 1)
+ {
+ connScroll--;
+ }
+ break;
+ case 'C':
+ padSelection++;
+ padSelection = std::min(padSelection, 1);
+ break; //right
+ case 'D':
+ padSelection--;
+ padSelection = std::max(padSelection, 0);
+ break; //left
+ meshScroll = std::max(meshScroll, 0);
+ connScroll = std::max(connScroll, 0);
+ meshInfoTimer = 0;
+ }
+ }
+
+ //This section checks for failures detected by RF24 & RF24Network as well as
+ //checking for deviations from the default configuration (1MBPS data rate)
+ //The mesh is restarted on failure and failure count logged to failLog.txt
+ //This makes the radios hot-swappable, disconnect & reconnect as desired, it should come up automatically
+ if (radio.failureDetected > 0 || radio.getDataRate() != RF24_1MBPS)
+ {
+ radio.failureDetected = 0;
+ std::ofstream myFile;
+ myFile.open("failLog.txt");
+ if (myFile.is_open())
+ {
+ myFile << ++failCounter << "\n";
+ myFile.close();
+ }
+ delay(500);
+ mesh.begin();
+ }
+
+ delay(2);
+ } //while 1
+
+ //delwin(meshPad);
+ //delwin(connPad);
+ clear();
+ endwin();
+ return 0;
+
+} //main
+
+/******************************************************************/
+/******************Main Drawing Functions**************************/
+
+void drawMain()
+{
+
+ clear();
+
+ attron(COLOR_PAIR(1));
+ wprintw(win, "RF24Gateway Ncurses Interface by TMRh20 - 2015\n");
+ whline(win, ACS_HLINE, maxY - 2);
+ attroff(COLOR_PAIR(1));
+ refresh();
+ /** Display Network Interface Info **/
+ /*******************************/
+
+ //Interface Information
+ struct ifaddrs *ifap, *ifa;
+ int family, s, n;
+ char host[NI_MAXHOST];
+
+retryIF:
+
+ getifaddrs(&ifap);
+ for (ifa = ifap, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++)
+ {
+ if (tunStr.compare(ifa->ifa_name) != 0 || ifa->ifa_addr == NULL)
+ {
+
+ if (ifa->ifa_next == NULL)
+ {
+ drawCfg(0);
+ goto retryIF;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ mvwprintw(win, 2, 0, "%8s ", ifa->ifa_name);
+
+ family = ifa->ifa_addr->sa_family;
+
+ //This is an IP interface, display the IP
+ if (family == AF_INET || family == AF_INET6)
+ {
+ s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ if (s == 0)
+ {
+ wprintw(win, "IP: %s\n", host);
+ std::string str1 = host;
+ unsigned found = str1.find_last_of(".");
+ subIP = str1.substr(0, found);
+ break;
+ }
}
- }
- }
- if(ok){
- gw.update();
-
- /** Read RF24Network Payloads (Do nothing with them currently) **/
- /*******************************/
- if( network.available() ){
- RF24NetworkHeader header;
- size_t size = network.peek(header);
- uint8_t buf[size];
-
- if(header.type == 1){
- struct timeStruct{
- uint8_t hr;
- uint8_t min;
- }myTime;
-
- time_t mTime;
- time(&mTime);
- struct tm* tm = localtime(&mTime);
-
- myTime.hr = tm->tm_hour;
- myTime.min = tm->tm_min;
- RF24NetworkHeader hdr(header.from_node,1);
- network.write(hdr,&myTime,sizeof(myTime));
-
- }
- network.read(header,&buf,size);
- }
-
- }
-
- /** Mesh address/id printout **/
- /*******************************/
- if(millis() - meshInfoTimer > updateRate){
-
- getmaxyx(win,maxX,maxY);
-
- // Draw the pads on screen
- drawDevPad();
- prefresh(devPad,0,0, 4,1, 14,25);
-
- drawMeshPad();
- wscrl(meshPad,meshScroll);
- prefresh(meshPad,0,0, 4,26, 14,47);
-
- drawRF24Pad();
- prefresh(rf24Pad,0,0, 4,51, 14, 73);
-
- if(showConnPad){
- drawConnPad();
- wscrl(connPad,connScroll);
- prefresh(connPad,0,0, 15,1, maxX-1,maxY-2);
- }
- } //MeshInfo Timer
-
-
- /** Handle keyboard input **/
- /*******************************/
- int myChar = getch();
-
- if(myChar > -1){
- //cout << myChar << endl;
- switch(myChar){
- // a: En/Disable display of active connections
- case 'a' : showConnPad = !showConnPad; if(!showConnPad){ wclear(connPad); prefresh(connPad,0,0, 15,1, maxX-1,maxY-2); drawMain();} break;
- // w: Increase frame-rate of curses display
- case 'w' : if(updateRate > 100){updateRate-=100;} mvwprintw(win,2,27,"Refresh Rate: %.1f fps",1000.0/updateRate); refresh(); break;
- // s: Decrease frame-rate of curses display
- case 's' : updateRate+=100; mvwprintw(win,2,27,"Refresh Rate: %.1f fps \t",1000.0/updateRate); refresh(); break;
- // c: Display IP configuration menu
- case 'c' : drawCfg(1); break;
- // h: Display help menu
- case 'h' : drawHelp(); break;
- case 'x' : clear(); endwin(); return 0; break;
- case 'A': if(padSelection == 0){meshScroll++;}else if(padSelection == 1){connScroll++;} break;
- case 'B': if(padSelection == 0){meshScroll--;}else if(padSelection == 1){connScroll--;} break;
- case 'C': padSelection++; padSelection= std::min(padSelection,1); break; //right
- case 'D': padSelection--; padSelection= std::max(padSelection,0); break; //left
- meshScroll = std::max(meshScroll,0);
- connScroll = std::max(connScroll,0);
- meshInfoTimer = 0;
- }
-
-
- }
-
- //This section checks for failures detected by RF24 & RF24Network as well as
- //checking for deviations from the default configuration (1MBPS data rate)
- //The mesh is restarted on failure and failure count logged to failLog.txt
- //This makes the radios hot-swappable, disconnect & reconnect as desired, it should come up automatically
- if(radio.failureDetected > 0 || radio.getDataRate() != RF24_1MBPS){
- radio.failureDetected = 0;
- std::ofstream myFile;
- myFile.open ("failLog.txt");
- if (myFile.is_open()){
- myFile << ++failCounter << "\n";
- myFile.close();
- }
- delay(500);
- mesh.begin();
}
-
- delay(2);
- }//while 1
-
-
- //delwin(meshPad);
- //delwin(connPad);
- clear();
- endwin();
- return 0;
-
-}//main
-
-
-
-/******************************************************************/
-/******************Main Drawing Functions**************************/
-
-void drawMain(){
-
- clear();
-
- attron(COLOR_PAIR(1));
- wprintw(win,"RF24Gateway Ncurses Interface by TMRh20 - 2015\n");
- whline(win,ACS_HLINE, maxY-2);
- attroff(COLOR_PAIR(1));
- refresh();
- /** Display Network Interface Info **/
- /*******************************/
-
-
-
- //Interface Information
- struct ifaddrs *ifap, *ifa;
- int family,s,n;
- char host[NI_MAXHOST];
-
-retryIF:
-
- getifaddrs (&ifap);
- for (ifa = ifap, n=0; ifa != NULL; ifa = ifa->ifa_next, n++) {
- if ( tunStr.compare(ifa->ifa_name) != 0 || ifa->ifa_addr == NULL){
-
- if(ifa->ifa_next == NULL ){
- drawCfg(0);
- goto retryIF;
- }else{
- continue;
- }
- }
- mvwprintw(win,2,0,"%8s ", ifa->ifa_name);
-
- family = ifa->ifa_addr->sa_family;
-
- //This is an IP interface, display the IP
- if (family == AF_INET || family == AF_INET6) {
- s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
- if (s == 0) {
- wprintw(win,"IP: %s\n", host);
- std::string str1 = host;
- unsigned found = str1.find_last_of(".");
- subIP = str1.substr(0,found);
- break;
- }
- }
- }
-
- mvwhline(win,15,1,ACS_HLINE, maxY-2);
-
-refresh();
+ mvwhline(win, 15, 1, ACS_HLINE, maxY - 2);
+
+ refresh();
}
/******************************************************************/
-void drawHelp(){
-
- drawMain();
-
- attron(COLOR_PAIR(1));
- mvwprintw(win, 4,1,"**RF24Gateway NCurses Help Menu**");
- wprintw(win," Controls:\n");
- wprintw(win," ARROW_UP/DOWN: Scroll up/down in supported menus\n");
- wprintw(win," ARROW_LEFT/RIGHT: Scroll between supported menus\n");
- wprintw(win," 'c' key: Open IP configuration menu\n");
- wprintw(win," 'w' key: Increase frame-rate of display\n");
- wprintw(win," 's' key: Decrease frame-rate of display\n");
- wprintw(win," 'a' key: Display active IP connections\n");
- wprintw(win," 'h' key: Display this menu\n");
-
- timeout(30000);
- getch();
- timeout(0);
-
- drawMain();
-
+void drawHelp()
+{
+
+ drawMain();
+
+ attron(COLOR_PAIR(1));
+ mvwprintw(win, 4, 1, "**RF24Gateway NCurses Help Menu**");
+ wprintw(win, " Controls:\n");
+ wprintw(win, " ARROW_UP/DOWN: Scroll up/down in supported menus\n");
+ wprintw(win, " ARROW_LEFT/RIGHT: Scroll between supported menus\n");
+ wprintw(win, " 'c' key: Open IP configuration menu\n");
+ wprintw(win, " 'w' key: Increase frame-rate of display\n");
+ wprintw(win, " 's' key: Decrease frame-rate of display\n");
+ wprintw(win, " 'a' key: Display active IP connections\n");
+ wprintw(win, " 'h' key: Display this menu\n");
+
+ timeout(30000);
+ getch();
+ timeout(0);
+
+ drawMain();
}
/******************************************************************/
-void drawCfg(bool isConf){
-
- if(isConf){drawMain();}
- nocbreak();
- echo();
- timeout(30000);
-
- sleep(1);
- wattron(win,COLOR_PAIR(1));
- mvwprintw(win,5,1, isConf ? "IP Configuration\n" : "**Interface Not Configured:**\n");
- wattroff(win,COLOR_PAIR(1));
- mvwprintw(win,6,1,"Enter IP Address: \n");
- refresh();
-
- char ip[20],mask[20];
- mvgetstr(6,19,ip);
-
- mvwprintw(win,7,1,"Enter Subnet Mask: \n");
- refresh();
-
- mvgetstr(7,20,mask);
-
- if(strlen(ip) >= 6 && strlen(mask) >= 7){
- gw.setIP(ip,mask);
- }else{
- mvwprintw(win,8,1,"Unable to set IP/Subnet \n");
- refresh();
- sleep(3);
- }
-
- timeout(0);
+void drawCfg(bool isConf)
+{
+
+ if (isConf)
+ {
+ drawMain();
+ }
+ nocbreak();
+ echo();
+ timeout(30000);
+
+ sleep(1);
+ wattron(win, COLOR_PAIR(1));
+ mvwprintw(win, 5, 1, isConf ? "IP Configuration\n" : "**Interface Not Configured:**\n");
+ wattroff(win, COLOR_PAIR(1));
+ mvwprintw(win, 6, 1, "Enter IP Address: \n");
+ refresh();
+
+ char ip[20], mask[20];
+ mvgetstr(6, 19, ip);
+
+ mvwprintw(win, 7, 1, "Enter Subnet Mask: \n");
+ refresh();
+
+ mvgetstr(7, 20, mask);
+
+ if (strlen(ip) >= 6 && strlen(mask) >= 7)
+ {
+ gw.setIP(ip, mask);
+ }
+ else
+ {
+ mvwprintw(win, 8, 1, "Unable to set IP/Subnet \n");
+ refresh();
+ sleep(3);
+ }
+
+ timeout(0);
cbreak();
- noecho();
+ noecho();
drawMain();
}
+/******************************************************************/
+/******************Curses Pad Functions****************************/
-/******************************************************************/
-/******************Curses Pad Functions****************************/
-
-void drawDevPad() {
-
-
- wclear(devPad);
-
- std::string line;
- std::ifstream inFile;
- inFile.open("/proc/net/dev");
- while(inFile.good()){
- getline(inFile,line); // get line from file
- // search
- if(line.find(tunStr) != std::string::npos ) {
-
- char txBytes[20], txPackets[20], txErrs[20];
- char rxBytes[20], rxPackets[20], rxErrs[20];
- char dummy[20];
-
- whline(devPad,ACS_HLINE, 20);
- mvwprintw(devPad,0,3," IF Stats: ");
-
- sscanf(line.c_str(), "%s %s %s %s %s %s %s %s %s %s %s %s", dummy, rxBytes,rxPackets,rxErrs,dummy,dummy,dummy,dummy,dummy, txBytes,txPackets,txErrs);
-
- mvwprintw(devPad,1,0,"RX Bytes %s\nRX Packets %s\nRX Errs %s\nTX Bytes %s\nTX Packets %s\nTX Errs %s\n",rxBytes,rxPackets,rxErrs,txBytes,txPackets,txErrs);
-
- float bytesRNow = strtof (rxBytes,NULL) - bRX;
- float bytesTNow = strtof (txBytes,NULL) - bTX;
-
- float RKBS = bytesRNow > 0 ? bytesRNow/updateRate : 0.0 ;
- float TKBS = bytesRNow > 0 ? bytesTNow/updateRate : 0.0 ;
-
- wprintw(devPad,"\nRX %.03f KB/s\n",RKBS);
- wprintw(devPad,"TX %.03f KB/s\n",TKBS);
-
- bRX = strtol (rxBytes,NULL,10);
- bTX = strtol (txBytes,NULL,10);
-
- }
- }
- inFile.close();
-
-}
+void drawDevPad()
+{
-/******************************************************************/
+ wclear(devPad);
-void drawMeshPad(){
-
- wclear(meshPad);
-
- meshInfoTimer = millis();
- //uint8_t pos=5;
- for(int i=0; i 0 ? bytesRNow / updateRate : 0.0;
+ float TKBS = bytesRNow > 0 ? bytesTNow / updateRate : 0.0;
+
+ wprintw(devPad, "\nRX %.03f KB/s\n", RKBS);
+ wprintw(devPad, "TX %.03f KB/s\n", TKBS);
+
+ bRX = strtol(rxBytes, NULL, 10);
+ bTX = strtol(txBytes, NULL, 10);
+ }
+ }
+ inFile.close();
}
/******************************************************************/
-void drawRF24Pad(){
-
- wclear(rf24Pad);
- mvwprintw(rf24Pad,1,0,"Address: 0%o\n",mesh.mesh_address);
- wprintw(rf24Pad,"nodeID: %d\n",mesh.getNodeID());
- wprintw(rf24Pad,"En Mesh: %s\n", gw.meshEnabled() ? "True" : "False");
- int dr = radio.getDataRate();
- wprintw(rf24Pad,"Data-Rate: %s\n", dr == 0 ? "1MBPS" : dr == 1 ? "2MBPS" : dr == 2 ? "250KBPS" : "ERROR" );
- int pa = radio.getPALevel();
- wprintw(rf24Pad,"PA Level: %s\n", pa == 0 ? "MIN" : pa == 1 ? "LOW" : pa == 2 ? "HIGH" : pa == 3 ? "MAX" : "ERROR" );
- wprintw(rf24Pad,"IF Type: %s\n", gw.config_TUN == 1 ? "TUN" : "TAP" );
- wprintw(rf24Pad,"IF Drops: %u\n", gw.ifDropped() );
- #if defined (ENABLE_NETWORK_STATS)
- uint32_t ok,fail;
- network.failures(&fail,&ok);
- wprintw(rf24Pad,"TX Packets: %u\n", ok );
- wprintw(rf24Pad,"TX Drops: %u\n", fail );
- #endif
-
- if(padSelection == 1){
- wattron(rf24Pad,COLOR_PAIR(1));
- mvwhline(rf24Pad,rf24Scroll,0,ACS_HLINE, maxY);
- wattroff(rf24Pad,COLOR_PAIR(1));
- mvwprintw(rf24Pad,rf24Scroll,3," RF24Network Info: ");
- }else{
- wattroff(rf24Pad,COLOR_PAIR(1));
- mvwhline(rf24Pad,rf24Scroll,0,ACS_HLINE, maxY);
- mvwprintw(rf24Pad,rf24Scroll,3," RF24Network Info: ");
-
- }
+void drawMeshPad()
+{
+
+ wclear(meshPad);
+ meshInfoTimer = millis();
+ //uint8_t pos=5;
+ for (int i = 0; i < mesh.addrListTop; i++)
+ {
+ mvwprintw(meshPad, i + 1, 0, " Address: 0%o ID: %d \n", mesh.addrList[i].address, mesh.addrList[i].nodeID);
+ }
+
+ if (padSelection == 0)
+ {
+ wattron(meshPad, COLOR_PAIR(1));
+ mvwhline(meshPad, meshScroll, 0, ACS_HLINE, maxY);
+ wattroff(meshPad, COLOR_PAIR(1));
+ mvwprintw(meshPad, meshScroll, 3, " Mesh Info: ");
+ }
+ else
+ {
+ wattroff(meshPad, COLOR_PAIR(1));
+ mvwhline(meshPad, meshScroll, 0, ACS_HLINE, maxY);
+ mvwprintw(meshPad, meshScroll, 3, " Mesh Info: ");
+ }
}
/******************************************************************/
-void drawConnPad(){
-
- int ctr = 2;
- size_t lCtr = 1;
- std::string line;
- wclear(connPad);
- //box(connPad,ACS_VLINE,ACS_HLINE);
-
-
- std::ifstream inFile;
- inFile.open("/proc/net/nf_conntrack");
- while(inFile.good()){
- getline(inFile,line); // get line from file
- // search
- if(line.find(subIP) != std::string::npos ) {
-
- std::string src = "src";
- unsigned fnd = line.find(src);
- fnd = line.find_last_of("0123456789",fnd-2);
- fnd = line.find_last_of(" ",fnd-2);
- unsigned findEnd = line.find(" mark=");
- line = line.substr(fnd,findEnd-fnd);
- mvwprintw(connPad,ctr++,0,"%d %s\n",lCtr++,line.c_str());
-
- if(ctr > maxX-15){
- break;
- }
- }
- }
-
- inFile.close();
-
- if(padSelection == 2){
- wattron(connPad,COLOR_PAIR(1));
- mvwhline(connPad,connScroll,0,ACS_HLINE, maxY);
- wattroff(connPad,COLOR_PAIR(1));
- mvwprintw(connPad,connScroll,5," Active IP Connections: ");
- }else{
- wattroff(connPad,COLOR_PAIR(1));
- mvwhline(connPad,connScroll,0,ACS_HLINE, maxY);
- mvwprintw(connPad,connScroll,5," Active IP Connections: ");
- }
-
+void drawRF24Pad()
+{
+
+ wclear(rf24Pad);
+ mvwprintw(rf24Pad, 1, 0, "Address: 0%o\n", mesh.mesh_address);
+ wprintw(rf24Pad, "nodeID: %d\n", mesh.getNodeID());
+ wprintw(rf24Pad, "En Mesh: %s\n", gw.meshEnabled() ? "True" : "False");
+ int dr = radio.getDataRate();
+ wprintw(rf24Pad, "Data-Rate: %s\n", dr == 0 ? "1MBPS" : dr == 1 ? "2MBPS"
+ : dr == 2 ? "250KBPS"
+ : "ERROR");
+ int pa = radio.getPALevel();
+ wprintw(rf24Pad, "PA Level: %s\n", pa == 0 ? "MIN" : pa == 1 ? "LOW"
+ : pa == 2 ? "HIGH"
+ : pa == 3 ? "MAX"
+ : "ERROR");
+ wprintw(rf24Pad, "IF Type: %s\n", gw.config_TUN == 1 ? "TUN" : "TAP");
+ wprintw(rf24Pad, "IF Drops: %u\n", gw.ifDropped());
+#if defined(ENABLE_NETWORK_STATS)
+ uint32_t ok, fail;
+ network.failures(&fail, &ok);
+ wprintw(rf24Pad, "TX Packets: %u\n", ok);
+ wprintw(rf24Pad, "TX Drops: %u\n", fail);
+#endif
+
+ if (padSelection == 1)
+ {
+ wattron(rf24Pad, COLOR_PAIR(1));
+ mvwhline(rf24Pad, rf24Scroll, 0, ACS_HLINE, maxY);
+ wattroff(rf24Pad, COLOR_PAIR(1));
+ mvwprintw(rf24Pad, rf24Scroll, 3, " RF24Network Info: ");
+ }
+ else
+ {
+ wattroff(rf24Pad, COLOR_PAIR(1));
+ mvwhline(rf24Pad, rf24Scroll, 0, ACS_HLINE, maxY);
+ mvwprintw(rf24Pad, rf24Scroll, 3, " RF24Network Info: ");
+ }
}
/******************************************************************/
+void drawConnPad()
+{
+
+ int ctr = 2;
+ size_t lCtr = 1;
+ std::string line;
+ wclear(connPad);
+ //box(connPad,ACS_VLINE,ACS_HLINE);
+
+ std::ifstream inFile;
+ inFile.open("/proc/net/nf_conntrack");
+ while (inFile.good())
+ {
+ getline(inFile, line); // get line from file
+ // search
+ if (line.find(subIP) != std::string::npos)
+ {
+
+ std::string src = "src";
+ unsigned fnd = line.find(src);
+ fnd = line.find_last_of("0123456789", fnd - 2);
+ fnd = line.find_last_of(" ", fnd - 2);
+ unsigned findEnd = line.find(" mark=");
+ line = line.substr(fnd, findEnd - fnd);
+ mvwprintw(connPad, ctr++, 0, "%d %s\n", lCtr++, line.c_str());
+
+ if (ctr > maxX - 15)
+ {
+ break;
+ }
+ }
+ }
+
+ inFile.close();
+
+ if (padSelection == 2)
+ {
+ wattron(connPad, COLOR_PAIR(1));
+ mvwhline(connPad, connScroll, 0, ACS_HLINE, maxY);
+ wattroff(connPad, COLOR_PAIR(1));
+ mvwprintw(connPad, connScroll, 5, " Active IP Connections: ");
+ }
+ else
+ {
+ wattroff(connPad, COLOR_PAIR(1));
+ mvwhline(connPad, connScroll, 0, ACS_HLINE, maxY);
+ mvwprintw(connPad, connScroll, 5, " Active IP Connections: ");
+ }
+}
+/******************************************************************/
diff --git a/examples/ncursesInt/CMakeLists.txt b/examples/ncursesInt/CMakeLists.txt
index b27803e..ce2b35b 100644
--- a/examples/ncursesInt/CMakeLists.txt
+++ b/examples/ncursesInt/CMakeLists.txt
@@ -1,3 +1,7 @@
+# this example needs the ncurses package installed
+find_package(Curses REQUIRED)
+include_directories(${CURSES_INCLUDE_DIR})
+
set(example RF24Gateway_ncursesInt)
# make a target
@@ -10,4 +14,5 @@ target_link_libraries(${example} PUBLIC
${RF24Network}
${RF24Mesh}
${RF24Gateway}
- )
+ ${CURSES_LIBRARIES}
+)
diff --git a/examples/ncursesInt/RF24Gateway_ncursesInt.cpp b/examples/ncursesInt/RF24Gateway_ncursesInt.cpp
index a05bcbd..be8b91d 100644
--- a/examples/ncursesInt/RF24Gateway_ncursesInt.cpp
+++ b/examples/ncursesInt/RF24Gateway_ncursesInt.cpp
@@ -1,16 +1,14 @@
-
-
/**
* RF24Gateway NCurses interface - TMRh20 2015
* This is a generic tool for nodes supporting or combining with RF24Ethernet and/or RF24Network.
-*
+*
* The tool provides a simple interface for monitoring information and activity regarding the RF24Gateway:
* a: Interface statistics from /proc/net/dev
* b: RF24Mesh address/id assignments
* c: RF24Network/Radio information
* d: Active IP connections (optional)
*
-* **Requirements: NCurses**
+* **Requirements: NCurses**
* Install NCurses: apt-get install libncurses5-dev
*
* **Controls**
@@ -21,7 +19,7 @@
#include
#include
-#include
+#include
#include
#include
@@ -46,546 +44,628 @@
/******************************************************************/
//User Configuration
-RF24 radio(22,0);
+RF24 radio(22, 0);
RF24Network network(radio);
-RF24Mesh mesh(radio,network);
-RF24Gateway gw(radio,network,mesh);
+RF24Mesh mesh(radio, network);
+RF24Gateway gw(radio, network, mesh);
uint8_t nodeID = 0;
int interruptPin = 24;
/******************************************************************/
-WINDOW * win;
-WINDOW * meshPad;
-WINDOW * connPad;
-WINDOW * devPad;
-WINDOW * rf24Pad;
-WINDOW * cfgPad;
-WINDOW * renewPad;
-
- void drawMain(void);
- void drawHelp(void);
- void drawCfg(bool isConf);
-
- void drawDevPad(void);
- void drawMeshPad(void);
- void drawConnPad(void);
- void drawRF24Pad(void);
-
- int maxX,maxY;
- int padSelection = 0;
- int meshScroll = 0;
- int connScroll = 0;
- int rf24Scroll = 0;
- unsigned long updateRate = 1000;
-
- uint32_t meshInfoTimer = 0;
- uint32_t fifoTimer;
- uint32_t fifoClears;
- uint32_t mesh_timer = 0;
- size_t networkPacketsRX = 0;
- std::string subIP;
- std::string tunStr ("tun_nrf24");
- bool showConnPad;
-
- size_t bRX;
- size_t bTX;
-
-
-/******************************************************************/
-/***********************MAIN***************************************/
-void intHandler(){
+WINDOW *win;
+WINDOW *meshPad;
+WINDOW *connPad;
+WINDOW *devPad;
+WINDOW *rf24Pad;
+WINDOW *cfgPad;
+WINDOW *renewPad;
+
+void drawMain(void);
+void drawHelp(void);
+void drawCfg(bool isConf);
+
+void drawDevPad(void);
+void drawMeshPad(void);
+void drawConnPad(void);
+void drawRF24Pad(void);
+
+int maxX, maxY;
+int padSelection = 0;
+int meshScroll = 0;
+int connScroll = 0;
+int rf24Scroll = 0;
+unsigned long updateRate = 1000;
+
+uint32_t meshInfoTimer = 0;
+uint32_t fifoTimer;
+uint32_t fifoClears;
+uint32_t mesh_timer = 0;
+size_t networkPacketsRX = 0;
+std::string subIP;
+std::string tunStr("tun_nrf24");
+bool showConnPad;
+
+size_t bRX;
+size_t bTX;
+
+/******************************************************************/
+/***********************MAIN***************************************/
+void intHandler()
+{
gw.update(true);
}
+int main()
+{
+
+ gw.begin(nodeID);
+ //mesh.setStaticAddress(8,1);
+
+ //uint8_t nodeID = 22;
+ //gw.begin(nodeID,3,RF24_2MBPS);
+
+ //uint16_t address = 0;
+ //gw.begin(address,3,RF24_2MBPS);
+
+ /** Setup NCurses**/
+ /*******************************/
+ win = initscr();
+ cbreak();
+ noecho();
+ getmaxyx(win, maxX, maxY);
+
+ keypad(win, TRUE);
+ start_color();
+ curs_set(0);
+ init_pair(1, COLOR_GREEN, COLOR_BLACK);
+ init_pair(2, COLOR_RED, COLOR_BLACK);
+
+ /** Setup Pads**/
+ /*******************************/
+ devPad = newpad(11, 40);
+ meshPad = newpad(50, 50);
+ rf24Pad = newpad(11, 40);
+ connPad = newpad(21, 150);
+ cfgPad = newpad(10, 40);
+ renewPad = newpad(1, 35);
+
+ scrollok(meshPad, true);
+ scrollok(connPad, true);
+ scrollok(rf24Pad, true);
+ timeout(0);
+
+ //MANUAL IP
+ //char ip[] = "10.10.3.1";
+ //char subnet[] = "255.255.255.0";
+ //gw.setIP(ip,subnet);
+
+ drawMain();
-int main() {
-
- gw.begin(nodeID);
- //mesh.setStaticAddress(8,1);
-
- //uint8_t nodeID = 22;
- //gw.begin(nodeID,3,RF24_2MBPS);
-
- //uint16_t address = 0;
- //gw.begin(address,3,RF24_2MBPS);
-
- /** Setup NCurses**/
- /*******************************/
- win = initscr();
- cbreak();
- noecho();
- getmaxyx(win,maxX,maxY);
-
- keypad(win, TRUE);
- start_color();
- curs_set(0);
- init_pair(1, COLOR_GREEN, COLOR_BLACK);
- init_pair(2, COLOR_RED, COLOR_BLACK);
-
- /** Setup Pads**/
- /*******************************/
- devPad = newpad(11,40);
- meshPad = newpad(50,50);
- rf24Pad = newpad(11,40);
- connPad = newpad(21,150);
- cfgPad = newpad(10,40);
- renewPad = newpad(1,35);
-
- scrollok(meshPad,true);
- scrollok(connPad,true);
- scrollok(rf24Pad,true);
- timeout(0);
-
-
- //MANUAL IP
- //char ip[] = "10.10.3.1";
- //char subnet[] = "255.255.255.0";
- //gw.setIP(ip,subnet);
-
- drawMain();
-
- radio.maskIRQ(1,1,0);
- attachInterrupt(interruptPin, INT_EDGE_FALLING, intHandler);
-
-/******************************************************************/
-/***********************LOOP***************************************/
-bool ok = true;
-uint32_t failCounter = 0;
-
- while(1){
-
-
- gw.interrupts(0); //Disable interrupts before accessing the radio
-
- if(millis()-mesh_timer > 30000 && mesh.getNodeID() > 0){ //Every 30 seconds, test mesh connectivity
- if( ! mesh.checkConnection() ){
- wclear(renewPad);
- mvwprintw(renewPad,0,0,"*Renewing Address*");
- prefresh(renewPad,0,0, 3,26, 4, 55);
- if( (ok = mesh.renewAddress()) ){
- wclear(renewPad);
- prefresh(renewPad,0,0, 3,26, 4, 55);
+ radio.maskIRQ(1, 1, 0);
+ attachInterrupt(interruptPin, INT_EDGE_FALLING, intHandler);
+
+ /******************************************************************/
+ /***********************LOOP***************************************/
+ bool ok = true;
+ uint32_t failCounter = 0;
+
+ while (1)
+ {
+
+ gw.interrupts(0); //Disable interrupts before accessing the radio
+
+ if (millis() - mesh_timer > 30000 && mesh.getNodeID() > 0)
+ { //Every 30 seconds, test mesh connectivity
+ if (!mesh.checkConnection())
+ {
+ wclear(renewPad);
+ mvwprintw(renewPad, 0, 0, "*Renewing Address*");
+ prefresh(renewPad, 0, 0, 3, 26, 4, 55);
+ if ((ok = mesh.renewAddress()))
+ {
+ wclear(renewPad);
+ prefresh(renewPad, 0, 0, 3, 26, 4, 55);
+ }
+ }
+ mesh_timer = millis();
+ }
+ gw.interrupts();
+
+ if (ok)
+ { //Non-master nodes need an active connection to the mesh in order to handle data
+
+ /** Read RF24Network Payloads (Do nothing with them currently) **/
+ /*******************************/
+ gw.interrupts(0);
+ if (network.available())
+ {
+ ++networkPacketsRX;
+ RF24NetworkHeader header;
+
+ // un-needed variables
+ // size_t size = network.peek(header);
+ // uint8_t buf[size];
+
+ if (header.type == 1) // header.type is uninitialized
+ {
+ struct timeStruct
+ {
+ uint8_t hr;
+ uint8_t min;
+ } myTime;
+
+ time_t mTime;
+ time(&mTime);
+ struct tm *tm = localtime(&mTime);
+
+ myTime.hr = tm->tm_hour;
+ myTime.min = tm->tm_min;
+ RF24NetworkHeader hdr(header.from_node, 1);
+ network.write(hdr, &myTime, sizeof(myTime));
+ }
+ network.read(header, 0, 0);
+ }
+ gw.interrupts(); //Re-enable interrupts when done accessing the radio
+ }
+ else
+ {
+ delay(100); //Big delay if connection to RF24Mesh is failing
}
- }
- mesh_timer = millis();
- }
- gw.interrupts();
-
- if(ok){ //Non-master nodes need an active connection to the mesh in order to handle data
-
-
- /** Read RF24Network Payloads (Do nothing with them currently) **/
- /*******************************/
- gw.interrupts(0);
- if( network.available() ){
- ++networkPacketsRX;
- RF24NetworkHeader header;
- size_t size = network.peek(header);
- uint8_t buf[size];
-
- if(header.type == 1){
- struct timeStruct{
- uint8_t hr;
- uint8_t min;
- }myTime;
-
- time_t mTime;
- time(&mTime);
- struct tm* tm = localtime(&mTime);
-
- myTime.hr = tm->tm_hour;
- myTime.min = tm->tm_min;
- RF24NetworkHeader hdr(header.from_node,1);
- network.write(hdr,&myTime,sizeof(myTime));
-
- }
- network.read(header,0,0);
- }
- gw.interrupts(); //Re-enable interrupts when done accessing the radio
-
- }else{
- delay(100); //Big delay if connection to RF24Mesh is failing
- }
-
- /**
- * The gateway handles all IP traffic (marked as EXTERNAL_DATA_TYPE) and passes it to the associated network interface
- * RF24Network user payloads are loaded into the user cache
- */
- gw.poll(10);
-
- /** Mesh address/id printout **/
- /*******************************/
- if(millis() - meshInfoTimer > updateRate){
-
- getmaxyx(win,maxX,maxY);
-
- // Draw the pads on screen
- drawDevPad();
- prefresh(devPad,0,0, 4,1, 14,25);
-
- drawMeshPad();
- wscrl(meshPad,meshScroll);
- prefresh(meshPad,0,0, 4,26, 14,47);
-
- drawRF24Pad();
- prefresh(rf24Pad,0,0, 4,51, 14, 73);
-
- if(showConnPad){
- drawConnPad();
- wscrl(connPad,connScroll);
- prefresh(connPad,0,0, 15,1, maxX-1,maxY-2);
- }
- } //MeshInfo Timer
-
-
- /** Handle keyboard input **/
- /*******************************/
- int myChar = getch();
-
- if(myChar > -1){
- //cout << myChar << endl;
- switch(myChar){
- // a: En/Disable display of active connections
- case 'a' : showConnPad = !showConnPad; if(!showConnPad){ wclear(connPad); prefresh(connPad,0,0, 15,1, maxX-1,maxY-2); drawMain();} break;
- // w: Increase frame-rate of curses display
- case 'w' : if(updateRate > 100){updateRate-=100;} mvwprintw(win,2,27,"Refresh Rate: %.1f fps",1000.0/updateRate); refresh(); break;
- // s: Decrease frame-rate of curses display
- case 's' : updateRate+=100; mvwprintw(win,2,27,"Refresh Rate: %.1f fps \t",1000.0/updateRate); refresh(); break;
- // c: Display IP configuration menu
- case 'c' : drawCfg(1); break;
- // h: Display help menu
- case 'h' : drawHelp(); break;
- case 'x' : clear(); endwin(); return 0; break;
- case KEY_UP: if(padSelection == 0){meshScroll++;}else if(padSelection == 1){connScroll++;} break;
- case KEY_DOWN: if(padSelection == 0){meshScroll--;}else if(padSelection == 1){connScroll--;} break;
- case KEY_RIGHT: padSelection++; padSelection= std::min(padSelection,1); break; //right
- case KEY_LEFT: padSelection--; padSelection= std::max(padSelection,0); break; //left
- case 'Q': clear(); endwin(); return 0; break;
- meshScroll = std::max(meshScroll,0);
- connScroll = std::max(connScroll,0);
- meshInfoTimer = 0;
- }
-
-
- }
-
- //This section checks for failures detected by RF24 & RF24Network as well as
- //checking for deviations from the default configuration (1MBPS data rate)
- //The mesh is restarted on failure and failure count logged to failLog.txt
- //This makes the radios hot-swappable, disconnect & reconnect as desired, it should come up automatically
- gw.interrupts(0);
- if(radio.failureDetected > 0 || radio.getDataRate() != RF24_1MBPS){
-
- std::ofstream myFile;
- myFile.open ("failLog.txt");
- if (myFile.is_open()){
- myFile << ++failCounter << "\n";
- }
- myFile.close();
- mesh.begin();
- delay(1000);
- radio.failureDetected = 0;
- }
- gw.interrupts(1);
-
- }//while 1
+ /**
+ * The gateway handles all IP traffic (marked as EXTERNAL_DATA_TYPE) and passes it to the associated network interface
+ * RF24Network user payloads are loaded into the user cache
+ */
+ gw.poll(10);
+
+ /** Mesh address/id printout **/
+ /*******************************/
+ if (millis() - meshInfoTimer > updateRate)
+ {
+
+ getmaxyx(win, maxX, maxY);
+
+ // Draw the pads on screen
+ drawDevPad();
+ prefresh(devPad, 0, 0, 4, 1, 14, 25);
+
+ drawMeshPad();
+ wscrl(meshPad, meshScroll);
+ prefresh(meshPad, 0, 0, 4, 26, 14, 47);
+
+ drawRF24Pad();
+ prefresh(rf24Pad, 0, 0, 4, 51, 14, 73);
+
+ if (showConnPad)
+ {
+ drawConnPad();
+ wscrl(connPad, connScroll);
+ prefresh(connPad, 0, 0, 15, 1, maxX - 1, maxY - 2);
+ }
+ } //MeshInfo Timer
+
+ /** Handle keyboard input **/
+ /*******************************/
+ int myChar = getch();
+
+ if (myChar > -1)
+ {
+ //cout << myChar << endl;
+ switch (myChar)
+ {
+ // a: En/Disable display of active connections
+ case 'a':
+ showConnPad = !showConnPad;
+ if (!showConnPad)
+ {
+ wclear(connPad);
+ prefresh(connPad, 0, 0, 15, 1, maxX - 1, maxY - 2);
+ drawMain();
+ }
+ break;
+ // w: Increase frame-rate of curses display
+ case 'w':
+ if (updateRate > 100)
+ {
+ updateRate -= 100;
+ }
+ mvwprintw(win, 2, 27, "Refresh Rate: %.1f fps", 1000.0 / updateRate);
+ refresh();
+ break;
+ // s: Decrease frame-rate of curses display
+ case 's':
+ updateRate += 100;
+ mvwprintw(win, 2, 27, "Refresh Rate: %.1f fps \t", 1000.0 / updateRate);
+ refresh();
+ break;
+ // c: Display IP configuration menu
+ case 'c':
+ drawCfg(1);
+ break;
+ // h: Display help menu
+ case 'h':
+ drawHelp();
+ break;
+ case 'x':
+ clear();
+ endwin();
+ return 0;
+ break;
+ case KEY_UP:
+ if (padSelection == 0)
+ {
+ meshScroll++;
+ }
+ else if (padSelection == 1)
+ {
+ connScroll++;
+ }
+ break;
+ case KEY_DOWN:
+ if (padSelection == 0)
+ {
+ meshScroll--;
+ }
+ else if (padSelection == 1)
+ {
+ connScroll--;
+ }
+ break;
+ case KEY_RIGHT:
+ padSelection++;
+ padSelection = std::min(padSelection, 1);
+ break; //right
+ case KEY_LEFT:
+ padSelection--;
+ padSelection = std::max(padSelection, 0);
+ break; //left
+ case 'Q':
+ clear();
+ endwin();
+ return 0;
+ break;
+ meshScroll = std::max(meshScroll, 0);
+ connScroll = std::max(connScroll, 0);
+ meshInfoTimer = 0;
+ }
+ }
- //delwin(meshPad);
- //delwin(connPad);
- clear();
- endwin();
- return 0;
-
-}//main
+ //This section checks for failures detected by RF24 & RF24Network as well as
+ //checking for deviations from the default configuration (1MBPS data rate)
+ //The mesh is restarted on failure and failure count logged to failLog.txt
+ //This makes the radios hot-swappable, disconnect & reconnect as desired, it should come up automatically
+ gw.interrupts(0);
+ if (radio.failureDetected > 0 || radio.getDataRate() != RF24_1MBPS)
+ {
+
+ std::ofstream myFile;
+ myFile.open("failLog.txt");
+ if (myFile.is_open())
+ {
+ myFile << ++failCounter << "\n";
+ }
+ myFile.close();
+ mesh.begin();
+ delay(1000);
+ radio.failureDetected = 0;
+ }
+ gw.interrupts(1);
+ } //while 1
+ //delwin(meshPad);
+ //delwin(connPad);
+ clear();
+ endwin();
+ return 0;
-/******************************************************************/
-/******************Main Drawing Functions**************************/
+} //main
-void drawMain(){
+/******************************************************************/
+/******************Main Drawing Functions**************************/
- clear();
+void drawMain()
+{
- attron(COLOR_PAIR(1));
- wprintw(win,"RF24Gateway Ncurses Interface by TMRh20 - 2015\n");
- whline(win,ACS_HLINE, maxY-2);
- attroff(COLOR_PAIR(1));
- refresh();
- /** Display Network Interface Info **/
- /*******************************/
+ clear();
+ attron(COLOR_PAIR(1));
+ wprintw(win, "RF24Gateway Ncurses Interface by TMRh20 - 2015\n");
+ whline(win, ACS_HLINE, maxY - 2);
+ attroff(COLOR_PAIR(1));
+ refresh();
+ /** Display Network Interface Info **/
+ /*******************************/
-
- //Interface Information
- struct ifaddrs *ifap, *ifa;
- int family,s,n;
- char host[NI_MAXHOST];
+ //Interface Information
+ struct ifaddrs *ifap, *ifa;
+ int family, s, n;
+ char host[NI_MAXHOST];
-retryIF:
-
- getifaddrs (&ifap);
- for (ifa = ifap, n=0; ifa != NULL; ifa = ifa->ifa_next, n++) {
- if ( tunStr.compare(ifa->ifa_name) != 0 || ifa->ifa_addr == NULL){
-
- if(ifa->ifa_next == NULL ){
+retryIF:
+
+ getifaddrs(&ifap);
+ for (ifa = ifap, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++)
+ {
+ if (tunStr.compare(ifa->ifa_name) != 0 || ifa->ifa_addr == NULL)
+ {
+
+ if (ifa->ifa_next == NULL)
+ {
drawCfg(0);
- goto retryIF;
- }else{
- continue;
- }
- }
- mvwprintw(win,2,0,"%8s ", ifa->ifa_name);
-
- family = ifa->ifa_addr->sa_family;
-
- //This is an IP interface, display the IP
- if (family == AF_INET || family == AF_INET6) {
- s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
- if (s == 0) {
- wprintw(win,"IP: %s\n", host);
- std::string str1 = host;
- unsigned found = str1.find_last_of(".");
- subIP = str1.substr(0,found);
- break;
- }
- }
- }
-
- mvwhline(win,15,1,ACS_HLINE, maxY-2);
-
-refresh();
+ goto retryIF;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ mvwprintw(win, 2, 0, "%8s ", ifa->ifa_name);
+
+ family = ifa->ifa_addr->sa_family;
+
+ //This is an IP interface, display the IP
+ if (family == AF_INET || family == AF_INET6)
+ {
+ s = getnameinfo(ifa->ifa_addr, (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ if (s == 0)
+ {
+ wprintw(win, "IP: %s\n", host);
+ std::string str1 = host;
+ unsigned found = str1.find_last_of(".");
+ subIP = str1.substr(0, found);
+ break;
+ }
+ }
+ }
+ mvwhline(win, 15, 1, ACS_HLINE, maxY - 2);
+
+ refresh();
}
/******************************************************************/
-void drawHelp(){
-
- drawMain();
-
- attron(COLOR_PAIR(1));
- mvwprintw(win, 4,1,"**RF24Gateway NCurses Help Menu**");
- wprintw(win," Controls:\n");
- wprintw(win," ARROW_UP/DOWN: Scroll up/down in supported menus\n");
- wprintw(win," ARROW_LEFT/RIGHT: Scroll between supported menus\n");
- wprintw(win," 'c' key: Open IP configuration menu\n");
- wprintw(win," 'w' key: Increase frame-rate of display\n");
- wprintw(win," 's' key: Decrease frame-rate of display\n");
- wprintw(win," 'a' key: Display active IP connections\n");
- wprintw(win," 'h' key: Display this menu\n");
-
- timeout(30000);
- getch();
- timeout(0);
-
- drawMain();
-
+void drawHelp()
+{
+
+ drawMain();
+
+ attron(COLOR_PAIR(1));
+ mvwprintw(win, 4, 1, "**RF24Gateway NCurses Help Menu**");
+ wprintw(win, " Controls:\n");
+ wprintw(win, " ARROW_UP/DOWN: Scroll up/down in supported menus\n");
+ wprintw(win, " ARROW_LEFT/RIGHT: Scroll between supported menus\n");
+ wprintw(win, " 'c' key: Open IP configuration menu\n");
+ wprintw(win, " 'w' key: Increase frame-rate of display\n");
+ wprintw(win, " 's' key: Decrease frame-rate of display\n");
+ wprintw(win, " 'a' key: Display active IP connections\n");
+ wprintw(win, " 'h' key: Display this menu\n");
+
+ timeout(30000);
+ getch();
+ timeout(0);
+
+ drawMain();
}
/******************************************************************/
-void drawCfg(bool isConf){
-
- if(isConf){drawMain();}
- nocbreak();
- echo();
- timeout(30000);
-
- sleep(1);
- wattron(win,COLOR_PAIR(1));
- mvwprintw(win,5,1, isConf ? "IP Configuration\n" : "**Interface Not Configured:**\n");
- wattroff(win,COLOR_PAIR(1));
- mvwprintw(win,6,1,"Enter IP Address: \n");
- refresh();
-
- char ip[20],mask[20];
- mvgetstr(6,19,ip);
-
- mvwprintw(win,7,1,"Enter Subnet Mask: \n");
- refresh();
-
- mvgetstr(7,20,mask);
-
- if(strlen(ip) >= 6 && strlen(mask) >= 7){
- gw.setIP(ip,mask);
- }else{
- mvwprintw(win,8,1,"Unable to set IP/Subnet \n");
- refresh();
- sleep(3);
- }
-
- timeout(0);
+void drawCfg(bool isConf)
+{
+
+ if (isConf)
+ {
+ drawMain();
+ }
+ nocbreak();
+ echo();
+ timeout(30000);
+
+ sleep(1);
+ wattron(win, COLOR_PAIR(1));
+ mvwprintw(win, 5, 1, isConf ? "IP Configuration\n" : "**Interface Not Configured:**\n");
+ wattroff(win, COLOR_PAIR(1));
+ mvwprintw(win, 6, 1, "Enter IP Address: \n");
+ refresh();
+
+ char ip[20], mask[20];
+ mvgetstr(6, 19, ip);
+
+ mvwprintw(win, 7, 1, "Enter Subnet Mask: \n");
+ refresh();
+
+ mvgetstr(7, 20, mask);
+
+ if (strlen(ip) >= 6 && strlen(mask) >= 7)
+ {
+ gw.setIP(ip, mask);
+ }
+ else
+ {
+ mvwprintw(win, 8, 1, "Unable to set IP/Subnet \n");
+ refresh();
+ sleep(3);
+ }
+
+ timeout(0);
cbreak();
- noecho();
+ noecho();
drawMain();
}
+/******************************************************************/
+/******************Curses Pad Functions****************************/
-/******************************************************************/
-/******************Curses Pad Functions****************************/
-
-void drawDevPad() {
-
-
- wclear(devPad);
-
- std::string line;
- std::ifstream inFile;
- inFile.open("/proc/net/dev");
- while(inFile.good()){
- getline(inFile,line); // get line from file
- // search
- if(line.find(tunStr) != std::string::npos ) {
-
- char txBytes[20], txPackets[20], txErrs[20];
- char rxBytes[20], rxPackets[20], rxErrs[20];
- char dummy[20];
-
- whline(devPad,ACS_HLINE, 20);
- mvwprintw(devPad,0,3," IF Stats: ");
-
- sscanf(line.c_str(), "%s %s %s %s %s %s %s %s %s %s %s %s", dummy, rxBytes,rxPackets,rxErrs,dummy,dummy,dummy,dummy,dummy, txBytes,txPackets,txErrs);
-
- mvwprintw(devPad,1,0,"RX Bytes %s\nRX Packets %s\nRX Errs %s\nTX Bytes %s\nTX Packets %s\nTX Errs %s\n",rxBytes,rxPackets,rxErrs,txBytes,txPackets,txErrs);
-
- float bytesRNow = strtof (rxBytes,NULL) - bRX;
- float bytesTNow = strtof (txBytes,NULL) - bTX;
-
- float RKBS = bytesRNow > 0 ? bytesRNow/updateRate : 0.0 ;
- float TKBS = bytesRNow > 0 ? bytesTNow/updateRate : 0.0 ;
-
- wprintw(devPad,"\nRX %.03f KB/s\n",RKBS);
- wprintw(devPad,"TX %.03f KB/s\n",TKBS);
-
- bRX = strtol (rxBytes,NULL,10);
- bTX = strtol (txBytes,NULL,10);
-
- }
- }
- inFile.close();
-
-}
+void drawDevPad()
+{
-/******************************************************************/
+ wclear(devPad);
+
+ std::string line;
+ std::ifstream inFile;
+ inFile.open("/proc/net/dev");
+ while (inFile.good())
+ {
+ getline(inFile, line); // get line from file
+ // search
+ if (line.find(tunStr) != std::string::npos)
+ {
+
+ char txBytes[20], txPackets[20], txErrs[20];
+ char rxBytes[20], rxPackets[20], rxErrs[20];
+ char dummy[20];
-void drawMeshPad(){
-
- wclear(meshPad);
-
- meshInfoTimer = millis();
- //uint8_t pos=5;
- for(int i=0; i 0 ? bytesRNow / updateRate : 0.0;
+ float TKBS = bytesRNow > 0 ? bytesTNow / updateRate : 0.0;
+
+ wprintw(devPad, "\nRX %.03f KB/s\n", RKBS);
+ wprintw(devPad, "TX %.03f KB/s\n", TKBS);
+
+ bRX = strtol(rxBytes, NULL, 10);
+ bTX = strtol(txBytes, NULL, 10);
+ }
+ }
+ inFile.close();
}
/******************************************************************/
-void drawRF24Pad(){
-
- wclear(rf24Pad);
- mvwprintw(rf24Pad,1,0,"Address: 0%o\n",mesh.mesh_address);
- wprintw(rf24Pad,"nodeID: %d\n",mesh.getNodeID());
- wprintw(rf24Pad,"En Mesh: %s\n", gw.meshEnabled() ? "True" : "False");
- radio.maskIRQ(1,1,1);
- int dr = radio.getDataRate();
- int pa = radio.getPALevel();
- radio.maskIRQ(1,1,0);
- wprintw(rf24Pad,"Data-Rate: %s\n", dr == 0 ? "1MBPS" : dr == 1 ? "2MBPS" : dr == 2 ? "250KBPS" : "ERROR" );
- wprintw(rf24Pad,"PA Level: %s\n", pa == 0 ? "MIN" : pa == 1 ? "LOW" : pa == 2 ? "HIGH" : pa == 3 ? "MAX" : "ERROR" );
- wprintw(rf24Pad,"IF Type: %s\n", gw.config_TUN == 1 ? "TUN" : "TAP" );
- wprintw(rf24Pad,"IF Drops: %u\n", gw.ifDropped() );
- #if defined (ENABLE_NETWORK_STATS)
- uint32_t ok,fail;
- network.failures(&fail,&ok);
- wprintw(rf24Pad,"TX Packets(sys): %u\n", ok );
- wprintw(rf24Pad,"TX Drops: %u\n", fail );
- #endif
- wprintw(rf24Pad,"RX Packets(user): %u\n",networkPacketsRX);
- if(gw.fifoCleared){
- ++fifoClears;
- gw.fifoCleared=false;
- }
- wprintw(rf24Pad,"Interrupt Errors: %u",fifoClears);
-
- if(padSelection == 1){
- wattron(rf24Pad,COLOR_PAIR(1));
- mvwhline(rf24Pad,rf24Scroll,0,ACS_HLINE, maxY);
- wattroff(rf24Pad,COLOR_PAIR(1));
- mvwprintw(rf24Pad,rf24Scroll,3," RF24Network Info: ");
- }else{
- wattroff(rf24Pad,COLOR_PAIR(1));
- mvwhline(rf24Pad,rf24Scroll,0,ACS_HLINE, maxY);
- mvwprintw(rf24Pad,rf24Scroll,3," RF24Network Info: ");
-
- }
+void drawMeshPad()
+{
+ wclear(meshPad);
+
+ meshInfoTimer = millis();
+ //uint8_t pos=5;
+ for (int i = 0; i < mesh.addrListTop; i++)
+ {
+ mvwprintw(meshPad, i + 1, 0, " Address: 0%o ID: %d \n", mesh.addrList[i].address, mesh.addrList[i].nodeID);
+ }
+
+ if (padSelection == 0)
+ {
+ wattron(meshPad, COLOR_PAIR(1));
+ mvwhline(meshPad, meshScroll, 0, ACS_HLINE, maxY);
+ wattroff(meshPad, COLOR_PAIR(1));
+ mvwprintw(meshPad, meshScroll, 3, " Mesh Info: ");
+ }
+ else
+ {
+ wattroff(meshPad, COLOR_PAIR(1));
+ mvwhline(meshPad, meshScroll, 0, ACS_HLINE, maxY);
+ mvwprintw(meshPad, meshScroll, 3, " Mesh Info: ");
+ }
}
/******************************************************************/
-void drawConnPad(){
-
- int ctr = 2;
- size_t lCtr = 1;
- std::string line;
- wclear(connPad);
- //box(connPad,ACS_VLINE,ACS_HLINE);
-
-
- std::ifstream inFile;
- inFile.open("/proc/net/nf_conntrack");
- while(inFile.good()){
- getline(inFile,line); // get line from file
- // search
- if(line.find(subIP) != std::string::npos ) {
-
- std::string src = "src";
- unsigned fnd = line.find(src);
- fnd = line.find_last_of("0123456789",fnd-2);
- fnd = line.find_last_of(" ",fnd-2);
- unsigned findEnd = line.find(" mark=");
- line = line.substr(fnd,findEnd-fnd);
- mvwprintw(connPad,ctr++,0,"%d %s\n",lCtr++,line.c_str());
-
- if(ctr > maxX-15){
- break;
- }
- }
- }
-
- inFile.close();
-
- if(padSelection == 2){
- wattron(connPad,COLOR_PAIR(1));
- mvwhline(connPad,connScroll,0,ACS_HLINE, maxY);
- wattroff(connPad,COLOR_PAIR(1));
- mvwprintw(connPad,connScroll,5," Active IP Connections: ");
- }else{
- wattroff(connPad,COLOR_PAIR(1));
- mvwhline(connPad,connScroll,0,ACS_HLINE, maxY);
- mvwprintw(connPad,connScroll,5," Active IP Connections: ");
- }
-
+void drawRF24Pad()
+{
+
+ wclear(rf24Pad);
+ mvwprintw(rf24Pad, 1, 0, "Address: 0%o\n", mesh.mesh_address);
+ wprintw(rf24Pad, "nodeID: %d\n", mesh.getNodeID());
+ wprintw(rf24Pad, "En Mesh: %s\n", gw.meshEnabled() ? "True" : "False");
+ radio.maskIRQ(1, 1, 1);
+ int dr = radio.getDataRate();
+ int pa = radio.getPALevel();
+ radio.maskIRQ(1, 1, 0);
+ wprintw(rf24Pad, "Data-Rate: %s\n", dr == 0 ? "1MBPS" : dr == 1 ? "2MBPS" : dr == 2 ? "250KBPS" : "ERROR");
+ wprintw(rf24Pad, "PA Level: %s\n", pa == 0 ? "MIN" : pa == 1 ? "LOW" : pa == 2 ? "HIGH" : pa == 3 ? "MAX" : "ERROR");
+ wprintw(rf24Pad, "IF Type: %s\n", gw.config_TUN == 1 ? "TUN" : "TAP");
+ wprintw(rf24Pad, "IF Drops: %u\n", gw.ifDropped());
+#if defined(ENABLE_NETWORK_STATS)
+ uint32_t ok, fail;
+ network.failures(&fail, &ok);
+ wprintw(rf24Pad, "TX Packets(sys): %u\n", ok);
+ wprintw(rf24Pad, "TX Drops: %u\n", fail);
+#endif
+ wprintw(rf24Pad, "RX Packets(user): %u\n", networkPacketsRX);
+ if (gw.fifoCleared)
+ {
+ ++fifoClears;
+ gw.fifoCleared = false;
+ }
+ wprintw(rf24Pad, "Interrupt Errors: %u", fifoClears);
+
+ if (padSelection == 1)
+ {
+ wattron(rf24Pad, COLOR_PAIR(1));
+ mvwhline(rf24Pad, rf24Scroll, 0, ACS_HLINE, maxY);
+ wattroff(rf24Pad, COLOR_PAIR(1));
+ mvwprintw(rf24Pad, rf24Scroll, 3, " RF24Network Info: ");
+ }
+ else
+ {
+ wattroff(rf24Pad, COLOR_PAIR(1));
+ mvwhline(rf24Pad, rf24Scroll, 0, ACS_HLINE, maxY);
+ mvwprintw(rf24Pad, rf24Scroll, 3, " RF24Network Info: ");
+ }
}
/******************************************************************/
+void drawConnPad()
+{
+
+ int ctr = 2;
+ size_t lCtr = 1;
+ std::string line;
+ wclear(connPad);
+ //box(connPad,ACS_VLINE,ACS_HLINE);
+
+ std::ifstream inFile;
+ inFile.open("/proc/net/nf_conntrack");
+ while (inFile.good())
+ {
+ getline(inFile, line); // get line from file
+ // search
+ if (line.find(subIP) != std::string::npos)
+ {
+
+ std::string src = "src";
+ unsigned fnd = line.find(src);
+ fnd = line.find_last_of("0123456789", fnd - 2);
+ fnd = line.find_last_of(" ", fnd - 2);
+ unsigned findEnd = line.find(" mark=");
+ line = line.substr(fnd, findEnd - fnd);
+ mvwprintw(connPad, ctr++, 0, "%d %s\n", lCtr++, line.c_str());
+
+ if (ctr > maxX - 15)
+ {
+ break;
+ }
+ }
+ }
+
+ inFile.close();
+
+ if (padSelection == 2)
+ {
+ wattron(connPad, COLOR_PAIR(1));
+ mvwhline(connPad, connScroll, 0, ACS_HLINE, maxY);
+ wattroff(connPad, COLOR_PAIR(1));
+ mvwprintw(connPad, connScroll, 5, " Active IP Connections: ");
+ }
+ else
+ {
+ wattroff(connPad, COLOR_PAIR(1));
+ mvwhline(connPad, connScroll, 0, ACS_HLINE, maxY);
+ mvwprintw(connPad, connScroll, 5, " Active IP Connections: ");
+ }
+}
+/******************************************************************/
From 2b56b88fc1529fef614700a24aac201beaef107b Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sat, 12 Jun 2021 05:02:48 -0700
Subject: [PATCH 14/24] rename READMEs in uppercase
---
READM.md => README.md | 0
docs/{READM.md => README.md} | 0
examples/{READM.txt => README.txt} | 0
examples/addons/{READM.md => README.md} | 0
examples/clients/BashClient/{READM.md => README.md} | 0
examples/clients/NodeJSClient/{READM.md => README.md} | 0
examples/clients/PythonClient/{READM.md => README.md} | 0
examples/clients/{READM.md => README.md} | 0
8 files changed, 0 insertions(+), 0 deletions(-)
rename READM.md => README.md (100%)
rename docs/{READM.md => README.md} (100%)
rename examples/{READM.txt => README.txt} (100%)
rename examples/addons/{READM.md => README.md} (100%)
rename examples/clients/BashClient/{READM.md => README.md} (100%)
rename examples/clients/NodeJSClient/{READM.md => README.md} (100%)
rename examples/clients/PythonClient/{READM.md => README.md} (100%)
rename examples/clients/{READM.md => README.md} (100%)
diff --git a/READM.md b/README.md
similarity index 100%
rename from READM.md
rename to README.md
diff --git a/docs/READM.md b/docs/README.md
similarity index 100%
rename from docs/READM.md
rename to docs/README.md
diff --git a/examples/READM.txt b/examples/README.txt
similarity index 100%
rename from examples/READM.txt
rename to examples/README.txt
diff --git a/examples/addons/READM.md b/examples/addons/README.md
similarity index 100%
rename from examples/addons/READM.md
rename to examples/addons/README.md
diff --git a/examples/clients/BashClient/READM.md b/examples/clients/BashClient/README.md
similarity index 100%
rename from examples/clients/BashClient/READM.md
rename to examples/clients/BashClient/README.md
diff --git a/examples/clients/NodeJSClient/READM.md b/examples/clients/NodeJSClient/README.md
similarity index 100%
rename from examples/clients/NodeJSClient/READM.md
rename to examples/clients/NodeJSClient/README.md
diff --git a/examples/clients/PythonClient/READM.md b/examples/clients/PythonClient/README.md
similarity index 100%
rename from examples/clients/PythonClient/READM.md
rename to examples/clients/PythonClient/README.md
diff --git a/examples/clients/READM.md b/examples/clients/README.md
similarity index 100%
rename from examples/clients/READM.md
rename to examples/clients/README.md
From d0d12d7edd1b4b18fd2efd2ca3fa1368864ef88a Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sat, 12 Jun 2021 05:04:17 -0700
Subject: [PATCH 15/24] [cmake] remove old STRIP cmds
---
cmake/GetLibInfo.cmake | 2 --
1 file changed, 2 deletions(-)
diff --git a/cmake/GetLibInfo.cmake b/cmake/GetLibInfo.cmake
index 6a58fc6..2d1c602 100644
--- a/cmake/GetLibInfo.cmake
+++ b/cmake/GetLibInfo.cmake
@@ -10,11 +10,9 @@ endif()
# use URL to get repo owner as Contact/Maintainer name
string(REGEX REPLACE "^http[s]?:\/\/github\\.com\/(.+)\/.+$" "\\1" CPACK_PACKAGE_CONTACT "${CMAKE_PROJECT_HOMEPAGE_URL}")
-# string(STRIP "${CPACK_PACKAGE_CONTACT}" CPACK_PACKAGE_CONTACT)
# use URL to get the repo name as the Lib Name. Note that we don't use the folder name for this
string(REGEX REPLACE "^http[s]?:\/\/github\\.com\/.+\/(.+)$" "\\1" LibName "${CMAKE_PROJECT_HOMEPAGE_URL}")
-# string(STRIP "${LibName}" LibName)
# convert the LibName to lower case
string(TOLOWER ${LibName} LibTargetName)
From 43090081954226875f17e1dcf9dc603ab22fc3d1 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sat, 12 Jun 2021 05:13:17 -0700
Subject: [PATCH 16/24] clean up linux CI workflow
---
.github/workflows/build_linux.yml | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index c2b8aaa..d922ae8 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -48,9 +48,6 @@ jobs:
usr_dir: "local"
steps:
- - name: install rpmbuild
- run: sudo apt-get install rpm
-
# - name: provide toolchain (for x86_64)
# if: ${{ matrix.toolchain.compiler == 'x86_64' }}
# run: |
@@ -129,12 +126,6 @@ jobs:
run: cmake -E make_directory ${{ github.workspace }}/build
- name: configure lib
- if: ${{ matrix.toolchain.compiler == 'default' }}
- working-directory: ${{ github.workspace }}/build
- run: cmake .. -D CMAKE_BUILD_TYPE=$BUILD_TYPE
-
- - name: configure lib (with toolchain compilers)
- if: ${{ matrix.toolchain.compiler != 'default' }}
working-directory: ${{ github.workspace }}/build
run: |
cmake .. -D CMAKE_BUILD_TYPE=$BUILD_TYPE \
@@ -178,8 +169,8 @@ jobs:
cmake ../examples \
-D CMAKE_TOOLCHAIN_FILE=../cmake/toolchains/${{ matrix.toolchain.compiler }}.cmake
- - name: build examples (none that use ncurses)
+ - name: build examples
working-directory: ${{ github.workspace }}/build
run: |
- cmake --build . --target RF24GatewayNode --target Sniffer --target RF24GatewayNodeInt
+ cmake --build .
file ./RF24GatewayNode
From 26960fbab2f45a60762f19a6405a023fe4f14d69 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sat, 12 Jun 2021 05:17:08 -0700
Subject: [PATCH 17/24] [no ci] add a comment
---
.github/workflows/build_linux.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index d922ae8..cbe77dd 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -45,7 +45,7 @@ jobs:
# - compiler: "i686"
# usr_dir: "i686-linux-gnu"
- compiler: "default" # github runner is hosted on a "amd64"
- usr_dir: "local"
+ usr_dir: "local" # use default compiler to test build all examples (including the ncurses ones)
steps:
# - name: provide toolchain (for x86_64)
From a76581d5d2b780a7b9d699b3b66e8d4075897652 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sat, 12 Jun 2021 14:49:11 -0700
Subject: [PATCH 18/24] Update CONTRIBUTING.md
---
CONTRIBUTING.md | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3a08eba..9f99c0f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1,4 @@
-These are the current requirements for getting your code included in RF24:
+These are the current requirements for getting your code included in RF24Gateway:
* Try your best to follow the rest of the code, if you're unsure then the NASA C style can help as it's closest to the current style: https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19950022400.pdf
@@ -7,3 +7,8 @@ These are the current requirements for getting your code included in RF24:
* Follow the [Arduino IDE formatting style](https://www.arduino.cc/en/Reference/StyleGuide) for Arduino examples
* Add [doxygen-compatible documentation](https://www.doxygen.nl/manual/docblocks.html) to any new functions you add, or update existing documentation if you change behaviour
+
+* CMake modules and CMakeLists.txt files should also have a uniform syntax.
+ - Indentation is a mandatory 4 spaces (not a `\t` character).
+ - Closing parenthesis for multi-line commands should have the same indentation as the line that opened the parenthesis.
+ - For other useful CMake syntax convention, please see [CMake docs for developers](https://cmake.org/cmake/help/v3.20/manual/cmake-developer.7.html) and [this useful best CMake practices article](https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1). The qiBuild project has some [well-reasoned "Dos & Don'ts" guideline](http://doc.aldebaran.com/qibuild/hacking/contrib/cmake/coding_guide.html), but beware that the nRF24 organization is not related to the qiBuild project in any way.
From b3cb6267bf64cd94314fecf75bc299d74f50cfe4 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sat, 12 Jun 2021 15:13:31 -0700
Subject: [PATCH 19/24] manually trigger CI workflows
---
.github/workflows/build_linux.yml | 28 ++++++++++++++--------------
.github/workflows/doxygen.yml | 30 ++++++++++++++----------------
2 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index cbe77dd..e75a5dd 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -4,22 +4,22 @@ on:
pull_request:
types: [opened, reopened]
paths:
- - '*.h'
- - '*.cpp'
- - 'CMakeLists.txt'
- - 'cmake/**'
- - 'examples/**.cpp'
- - '!**Makefile' # old build system is not tested in this workflow
- - '.github/workflows/build_linux.yml'
+ - "*.h"
+ - "*.cpp"
+ - "CMakeLists.txt"
+ - "cmake/**"
+ - "examples/**.cpp"
+ - "!**Makefile" # old build system is not tested in this workflow
+ - ".github/workflows/build_linux.yml"
push:
paths:
- - '*.h'
- - '*.cpp'
- - 'CMakeLists.txt'
- - 'cmake/**'
- - 'examples/**.cpp'
- - '!**Makefile' # old build system is not tested in this workflow
- - '.github/workflows/build_linux.yml'
+ - "*.h"
+ - "*.cpp"
+ - "CMakeLists.txt"
+ - "cmake/**"
+ - "examples/**.cpp"
+ - "!**Makefile" # old build system is not tested in this workflow
+ - ".github/workflows/build_linux.yml"
release:
types: [published, edited]
diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml
index 37a8b09..c73ac2b 100644
--- a/.github/workflows/doxygen.yml
+++ b/.github/workflows/doxygen.yml
@@ -2,25 +2,23 @@ name: DoxyGen build
on:
pull_request:
- branches: [master]
paths:
- - '*.h'
- - '*.md'
- - 'docs/**'
- - '!**README.md'
- - 'examples**.cpp'
- - '.github/workflows/doxygen.yml'
- - 'Doxyfile'
+ - "*.h"
+ - "*.md"
+ - "docs/**"
+ - "!**README.md"
+ - "examples**.cpp"
+ - ".github/workflows/doxygen.yml"
+ - "Doxyfile"
push:
- branches: [master]
paths:
- - '*.h'
- - '*.md'
- - 'docs/**'
- - '!**README.md'
- - 'examples**.cpp'
- - '.github/workflows/doxygen.yml'
- - 'Doxyfile'
+ - "*.h"
+ - "*.md"
+ - "docs/**"
+ - "!**README.md"
+ - "examples**.cpp"
+ - ".github/workflows/doxygen.yml"
+ - "Doxyfile"
release:
branches: [master]
types: [published, edited]
From 461cb2cabb1ee9351b78de55f8f3927aa52608ed Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Sat, 12 Jun 2021 16:33:11 -0700
Subject: [PATCH 20/24] gimme that badge
---
README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index e93d102..fab59df 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+[![Linux build](https://github.com/nRF24/RF24Gateway/actions/workflows/build_linux.yml/badge.svg)](https://github.com/nRF24/RF24Gateway/actions/workflows/build_linux.yml)
+
## RF24Gateway
A complimentary library to RF24Ethernet, for RPi/Linux devices.
@@ -12,4 +14,4 @@ http://nRF24.github.io/RF24Gateway
http://nRF24.github.io/RF24Ethernet
-All: http://tmrh20.github.io
\ No newline at end of file
+All: http://tmrh20.github.io
From 501d9eab059d3df8c439f0eb5a1a42ce01c3b34e Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Fri, 18 Jun 2021 15:15:00 -0700
Subject: [PATCH 21/24] use CMake CLI to change debugging level
---
CMakeLists.txt | 9 +++++++++
RF24Gateway.cpp | 32 ++++++++++++++++----------------
RF24Gateway.h | 4 +++-
3 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ce4426..63449e0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,6 +10,9 @@ add_library(project_options INTERFACE)
target_compile_features(project_options INTERFACE cxx_std_17)
add_compile_options(-Ofast -Wall)
+# allow using CMake options to adjust RF24Network_config.h without modiying source code
+option(DEBUG_LEVEL "adjust the verbosity of the debugging messages" 0)
+
# detect CPU and add compiler flags accordingly
include(cmake/detectCPU.cmake)
@@ -66,6 +69,12 @@ set_target_properties(
VERSION ${${LibName}_VERSION_STRING}
)
+# assert the appropriate preprocessor macros for RF24Network_config.h
+if(DEBUG_LEVEL GREATER 0)
+ message(STATUS "DEBUG_LEVEL set to ${DEBUG_LEVEL}")
+ target_compile_definitions(${LibTargetName} PUBLIC DEBUG_LEVEL=${DEBUG_LEVEL})
+endif()
+
###########################
# target install rules for the RF24Log lib
###########################
diff --git a/RF24Gateway.cpp b/RF24Gateway.cpp
index 46a87d6..86bba72 100644
--- a/RF24Gateway.cpp
+++ b/RF24Gateway.cpp
@@ -34,7 +34,7 @@ void RF24Gateway::begin(uint16_t address, uint8_t _channel, rf24_datarate_e data
bool RF24Gateway::begin(bool configTUN, bool meshEnable, uint16_t address, uint8_t mesh_nodeID, rf24_datarate_e data_rate, uint8_t _channel)
{
- #if (DEBUG >= 1)
+ #if (DEBUG_LEVEL >= 1)
printf("GW Begin\n");
printf("Config Device address 0%o nodeID %d\n", address, mesh_nodeID);
#endif
@@ -81,7 +81,7 @@ bool RF24Gateway::begin(bool configTUN, bool meshEnable, uint16_t address, uint8
}
network.multicastRelay = 1;
- //#if (DEBUG >= 1)
+ //#if (DEBUG_LEVEL >= 1)
radio.printDetails();
//#endif
@@ -165,7 +165,7 @@ int RF24Gateway::configDevice(uint16_t address)
flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
}
tunFd = allocateTunDevice(tunName, flags, address);
- #if DEBUG >= 1
+ #if DEBUG_LEVEL >= 1
if (tunFd >= 0) {
std::cout << "RF24Gw: Successfully attached to tun/tap device " << tunTapDevice << std::endl;
}
@@ -200,7 +200,7 @@ int RF24Gateway::allocateTunDevice(char *dev, int flags, uint16_t address)
// Create device
if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) {
//close(fd);
- //#if (DEBUG >= 1)
+ //#if (DEBUG_LEVEL >= 1)
std::cerr << "RF24Gw: Error: enabling TUNSETIFF" << std::endl;
std::cerr << "RF24Gw: If changing from TAP/TUN, run 'sudo ip link delete tun_nrf24' to remove the interface" << std::endl;
return -1;
@@ -209,7 +209,7 @@ int RF24Gateway::allocateTunDevice(char *dev, int flags, uint16_t address)
//Make persistent
if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
- #if (DEBUG >= 1)
+ #if (DEBUG_LEVEL >= 1)
std::cerr << "RF24Gw: Error: enabling TUNSETPERSIST" << std::endl;
#endif
return -1;
@@ -229,7 +229,7 @@ int RF24Gateway::allocateTunDevice(char *dev, int flags, uint16_t address)
memcpy((char *)&ifr.ifr_hwaddr, (char *)&sap, sizeof(struct sockaddr));
if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
- #if DEBUG >= 1
+ #if DEBUG_LEVEL >= 1
fprintf(stderr, "RF24Gw: Failed to set MAC address\n");
#endif
}
@@ -396,10 +396,10 @@ void RF24Gateway::handleRadioIn()
memcpy(&msg.message, &f.message_buffer, bytesRead);
msg.size = bytesRead;
- #if (DEBUG >= 1)
+ #if (DEBUG_LEVEL >= 1)
std::cout << "Radio: Received " << bytesRead << " bytes ... " << std::endl;
#endif
- #if (DEBUG >= 3)
+ #if (DEBUG_LEVEL >= 3)
//printPayload(msg.getPayloadStr(),"radio RX");
std::cout << "TunRead: " << std::endl;
for (size_t i = 0; i < msg.size; i++) {
@@ -465,11 +465,11 @@ void RF24Gateway::handleRadioOut()
msgStruct *msgTx = &txQueue.front();
- #if (DEBUG >= 1)
+ #if (DEBUG_LEVEL >= 1)
std::cout << "Radio: Sending " << msgTx->size << " bytes ... ";
std::cout << std::endl;
#endif
- #if (DEBUG >= 3)
+ #if (DEBUG_LEVEL >= 3)
//PrintDebug == 1 does not have an endline.
//printPayload(msg.getPayloadStr(),"radio TX");
#endif
@@ -602,10 +602,10 @@ void RF24Gateway::handleRX(uint32_t waitDelay)
if (FD_ISSET(tunFd, &socketSet)) {
if ((nread = read(tunFd, buffer, MAX_PAYLOAD_SIZE)) >= 0) {
- #if (DEBUG >= 1)
+ #if (DEBUG_LEVEL >= 1)
std::cout << "Tun: Successfully read " << nread << " bytes from tun device" << std::endl;
#endif
- #if (DEBUG >= 3)
+ #if (DEBUG_LEVEL >= 3)
std::cout << "TunRead: " << std::endl;
for (int i = 0; i < nread; i++)
{
@@ -624,7 +624,7 @@ void RF24Gateway::handleRX(uint32_t waitDelay)
}
}
else {
- #if (DEBUG >= 1)
+ #if (DEBUG_LEVEL >= 1)
std::cerr << "Tun: Error while reading from tun/tap interface." << std::endl;
#endif
}
@@ -657,18 +657,18 @@ void RF24Gateway::handleTX()
if (writtenBytes != msg->size)
{
//std::cerr << "Tun: Less bytes written to tun/tap device then requested." << std::endl;
- #if DEBUG >= 1
+ #if DEBUG_LEVEL >= 1
printf("Tun: Less bytes written %d to tun/tap device then requested %d.", writtenBytes, msg->size);
#endif
}
else
{
- #if (DEBUG >= 1)
+ #if (DEBUG_LEVEL >= 1)
std::cout << "Tun: Successfully wrote " << writtenBytes << " bytes to tun device" << std::endl;
#endif
}
- #if (DEBUG >= 3)
+ #if (DEBUG_LEVEL >= 3)
//printPayload(msg.message,"tun write");
std::cout << "TunRead: " << std::endl;
for (size_t i = 0; i < msg->size; i++) {
diff --git a/RF24Gateway.h b/RF24Gateway.h
index e4d35c0..7a8c900 100644
--- a/RF24Gateway.h
+++ b/RF24Gateway.h
@@ -34,7 +34,9 @@
#define IFF_MULTI_QUEUE 0x0100
#endif
-#define DEBUG 0
+#ifndef DEBUG_LEVEL
+ #define DEBUG_LEVEL 0
+#endif // DEBUG_LEVEL
#define BACKLOG 10 /* Passed to listen() */
From 9ea06ee5a45cd7d0be1128fd0f3238fc05478e2d Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Fri, 18 Jun 2021 15:18:22 -0700
Subject: [PATCH 22/24] limit Doxygen CI trigger during open PR
---
.github/workflows/doxygen.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml
index c73ac2b..8301e94 100644
--- a/.github/workflows/doxygen.yml
+++ b/.github/workflows/doxygen.yml
@@ -2,6 +2,7 @@ name: DoxyGen build
on:
pull_request:
+ types: [opened, reopened]
paths:
- "*.h"
- "*.md"
From fecc698e2f595d4266312a182a2df39cbe5204b1 Mon Sep 17 00:00:00 2001
From: 2bndy5 <2bndy5@gmail.com>
Date: Thu, 5 Aug 2021 12:35:53 -0700
Subject: [PATCH 23/24] Update mqttLogger.py
---
examples/addons/mqttLogger.py | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/examples/addons/mqttLogger.py b/examples/addons/mqttLogger.py
index d653ac3..682b3a2 100644
--- a/examples/addons/mqttLogger.py
+++ b/examples/addons/mqttLogger.py
@@ -7,12 +7,16 @@
Simple MQTT data logger, listens for UDP output from RF24Gateway & logs to an MQTT topic
For use with RF24Mesh nodes that are not able to communicate directly via TCP/IP etc
See RF24Gateway examples:
- RF24NetworkFrame frame = RF24NetworkFrame(header,buf,size);
- gw.sendUDP(mesh.getNodeID(header.from_node),frame);
+ RF24NetworkFrame frame = RF24NetworkFrame(header, buf, size);
+ gw.sendUDP(mesh.getNodeID(header.from_node), frame);
"""
import paho.mqtt.client as mqtt
import socket
-import sys
+
+try: #python 2 to 3 hack
+ unicode("") # all strings are unicode in python3
+except NameError:
+ unicode = str # does the same thing as python2's builtin unicode()
### Setup the MQTT host IP & topic to publish to
mqttHost = "10.10.2.2"
@@ -38,4 +42,4 @@
mqttc.connect(mqttHost, 1883)
data = unicode(data, errors="replace")
mqttc.publish(topic, data)
- mqttc.loop(2)
\ No newline at end of file
+ mqttc.loop(2)
From f35b2930032c8351c5d28ecc5a00ec87682967ae Mon Sep 17 00:00:00 2001
From: 2bndy5 <2bndy5@gmail.com>
Date: Sun, 14 Nov 2021 16:04:28 -0800
Subject: [PATCH 24/24] [CI] use RF24* master; save doc builds as artifact
---
.github/workflows/build_linux.yml | 2 --
.github/workflows/doxygen.yml | 58 ++++++++++++++++++-------------
2 files changed, 34 insertions(+), 26 deletions(-)
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
index e75a5dd..265916e 100644
--- a/.github/workflows/build_linux.yml
+++ b/.github/workflows/build_linux.yml
@@ -91,7 +91,6 @@ jobs:
uses: actions/checkout@v2
with:
repository: nRF24/RF24Network
- ref: CMake-4-Linux
- name: build & install RF24Network
run: |
@@ -106,7 +105,6 @@ jobs:
uses: actions/checkout@v2
with:
repository: nRF24/RF24Mesh
- ref: CMake-4-Linux
- name: build & install RF24Mesh
run: |
diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml
index 8301e94..b06d67d 100644
--- a/.github/workflows/doxygen.yml
+++ b/.github/workflows/doxygen.yml
@@ -1,4 +1,4 @@
-name: DoxyGen build
+name: build Docs
on:
pull_request:
@@ -29,26 +29,36 @@ jobs:
runs-on: ubuntu-latest
steps:
- - name: get latest release version number
- id: latest_ver
- uses: pozetroninc/github-action-get-latest-release@master
- with:
- repository: nRF24/RF24Gateway
- - name: checkout
- uses: actions/checkout@v2
- - name: overwrite doxygen tags
- run: |
- touch doxygenAction
- echo "PROJECT_NUMBER = ${{ steps.latest_ver.outputs.release }}" >> doxygenAction
- echo "@INCLUDE = doxygenAction" >> Doxyfile
- - name: build doxygen
- uses: mattnotmitt/doxygen-action@v1
- with:
- working-directory: '.'
- doxyfile-path: './Doxyfile'
- - name: upload to github pages
- if: ${{ github.event_name == 'release'}}
- uses: peaceiris/actions-gh-pages@v3
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- publish_dir: ./docs/html
\ No newline at end of file
+ - name: get latest release version number
+ id: latest_ver
+ uses: pozetroninc/github-action-get-latest-release@master
+ with:
+ repository: nRF24/RF24Gateway
+
+ - name: checkout
+ uses: actions/checkout@v2
+
+ - name: overwrite doxygen tags
+ run: |
+ touch doxygenAction
+ echo "PROJECT_NUMBER = ${{ steps.latest_ver.outputs.release }}" >> doxygenAction
+ echo "@INCLUDE = doxygenAction" >> Doxyfile
+
+ - name: build doxygen
+ uses: mattnotmitt/doxygen-action@v1
+ with:
+ working-directory: '.'
+ doxyfile-path: './Doxyfile'
+
+ - name: Save doxygen docs as artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: "RF24Gateway_doxygen_docs"
+ path: ${{ github.workspace }}/docs/html
+
+ - name: upload to github pages
+ if: ${{ github.event_name == 'release'}}
+ uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./docs/html
\ No newline at end of file