diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..3e4ddd4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,104 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 90 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^"(gnuradio)/' + Priority: 1 + - Regex: '^<(gnuradio)/' + Priority: 2 + - Regex: '^<(boost)/' + Priority: 98 + - Regex: '^<[a-z]*>$' + Priority: 99 + - Regex: '^".*"$' + Priority: 0 + - Regex: '.*' + Priority: 10 + +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never diff --git a/.gitignore b/.gitignore index b92d662..85c92e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ -build/ +*~ *.pyc +*.pyo +build*/ +examples/grc/*.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 3874c97..f67b461 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,81 +1,94 @@ -# Copyright (C) 2016 Bastille Networks +# Copyright 2011-2020 Free Software Foundation, Inc. # -# 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 3 of the License, or -# (at your option) any later version. +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.8) project(gr-nordic CXX C) enable_testing() -#select the release build type by default to get optimization flags +# Install to PyBOMBS target prefix if defined +if(DEFINED ENV{PYBOMBS_PREFIX}) + set(CMAKE_INSTALL_PREFIX $ENV{PYBOMBS_PREFIX}) + message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}") +endif() + +# Select the release build type by default to get optimization flags if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") message(STATUS "Build type not specified: defaulting to release.") endif(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") -#make sure our local CMake Modules path comes first +# Make sure our local CMake Modules path comes first list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) +# Set the version information here +set(VERSION_MAJOR 1) +set(VERSION_API 0) +set(VERSION_ABI 0) +set(VERSION_PATCH 0) + +cmake_policy(SET CMP0011 NEW) + +# Enable generation of compile_commands.json for code completion engines +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + ######################################################################## # Compiler specific setup ######################################################################## -if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) +if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR + CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + AND NOT WIN32) #http://gcc.gnu.org/wiki/Visibility add_definitions(-fvisibility=hidden) endif() -######################################################################## -# Find boost -######################################################################## -if(UNIX AND EXISTS "/usr/lib64") - list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix -endif(UNIX AND EXISTS "/usr/lib64") -set(Boost_ADDITIONAL_VERSIONS - "1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39" - "1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44" - "1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49" - "1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54" - "1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59" - "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64" - "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69" -) -find_package(Boost "1.35" COMPONENTS filesystem system) - -if(NOT Boost_FOUND) - message(FATAL_ERROR "Boost required to compile nordic") -endif() +IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + SET(CMAKE_CXX_STANDARD 14) +ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + SET(CMAKE_CXX_STANDARD 14) +ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + SET(CMAKE_CXX_STANDARD 14) +ELSE() + message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.") +ENDIF() + +IF(CMAKE_C_COMPILER_ID STREQUAL "GNU") + SET(CMAKE_C_STANDARD 11) +ELSEIF(CMAKE_C_COMPILER_ID MATCHES "Clang") + SET(CMAKE_C_STANDARD 11) +ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + SET(CMAKE_C_STANDARD 11) +ELSE() + message(WARNING "C standard could not be set because compiler is not GNU, Clang or MSVC.") +ENDIF() ######################################################################## # Install directories ######################################################################## +include(FindPkgConfig) +find_package(Gnuradio "3.9" REQUIRED) +include(GrVersion) + include(GrPlatform) #define LIB_SUFFIX -set(GR_RUNTIME_DIR bin) -set(GR_LIBRARY_DIR lib${LIB_SUFFIX}) + +if(NOT CMAKE_MODULES_DIR) + set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) +endif(NOT CMAKE_MODULES_DIR) + set(GR_INCLUDE_DIR include/nordic) -set(GR_DATA_DIR share) +set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/nordic) set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME}) -set(GR_DOC_DIR ${GR_DATA_DIR}/doc) set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME}) -set(GR_CONF_DIR etc) set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d) -set(GR_LIBEXEC_DIR libexec) set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME}) -set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks) ######################################################################## # On Apple only, set install name and use rpath correctly, if not already set @@ -100,52 +113,17 @@ endif(APPLE) ######################################################################## # Find gnuradio build dependencies ######################################################################## -find_package(CppUnit) find_package(Doxygen) -# Search for GNU Radio and its components and versions. Add any -# components required to the list of GR_REQUIRED_COMPONENTS (in all -# caps such as FILTER or FFT) and change the version to the minimum -# API compatible version required. -set(GR_REQUIRED_COMPONENTS RUNTIME) -find_package(Gnuradio "3.7.2" REQUIRED) - -if(NOT CPPUNIT_FOUND) - message(FATAL_ERROR "CppUnit required to compile nordic") -endif() - ######################################################################## # Setup doxygen option ######################################################################## if(DOXYGEN_FOUND) - option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) + option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) else(DOXYGEN_FOUND) - option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) + option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) endif(DOXYGEN_FOUND) -######################################################################## -# Setup the include and linker paths -######################################################################## -include_directories( - ${CMAKE_SOURCE_DIR}/lib - ${CMAKE_SOURCE_DIR}/include - ${CMAKE_BINARY_DIR}/lib - ${CMAKE_BINARY_DIR}/include - ${Boost_INCLUDE_DIRS} - ${CPPUNIT_INCLUDE_DIRS} - ${GNURADIO_ALL_INCLUDE_DIRS} -) - -link_directories( - ${Boost_LIBRARY_DIRS} - ${CPPUNIT_LIBRARY_DIRS} - ${GNURADIO_RUNTIME_LIBRARY_DIRS} -) - -# Set component parameters -set(GR_NORDIC_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "" FORCE) -set(GR_NORDIC_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig CACHE INTERNAL "" FORCE) - ######################################################################## # Create uninstall target ######################################################################## @@ -156,25 +134,27 @@ configure_file( add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake -) + ) ######################################################################## # Add subdirectories ######################################################################## add_subdirectory(include/nordic) add_subdirectory(lib) -add_subdirectory(swig) -add_subdirectory(python) -add_subdirectory(grc) add_subdirectory(apps) add_subdirectory(docs) +# NOTE: manually update below to use GRC to generate C++ flowgraphs w/o python +if(ENABLE_PYTHON) + message(STATUS "PYTHON and GRC components are enabled") + add_subdirectory(python) + add_subdirectory(grc) +else(ENABLE_PYTHON) + message(STATUS "PYTHON and GRC components are disabled") +endif(ENABLE_PYTHON) ######################################################################## # Install cmake search helper for this library ######################################################################## -if(NOT CMAKE_MODULES_DIR) - set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) -endif(NOT CMAKE_MODULES_DIR) install(FILES cmake/Modules/nordicConfig.cmake DESTINATION ${CMAKE_MODULES_DIR}/nordic diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 9cecc1d..0000000 --- a/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. 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 -them 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 prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. 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. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey 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; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If 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 convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - 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. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -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. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - 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 -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} - - 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 3 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, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - {project} Copyright (C) {year} {fullname} - This program 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, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU 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. But first, please read -. diff --git a/MANIFEST.md b/MANIFEST.md index 49f9201..3d55e6f 100644 --- a/MANIFEST.md +++ b/MANIFEST.md @@ -7,6 +7,7 @@ author: copyright_owner: - Copyright Owner 1 license: +gr_supported_version: # Put a comma separated list of supported GR versions here #repo: # Put the URL of the repository here, or leave blank for default #website: # If you have a separate project website, put it here #icon: # Put a URL to a square image here that will be used as an icon on CGRAN diff --git a/README.md b/README.md deleted file mode 100644 index 4afb6ab..0000000 --- a/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# gr-nordic - -GNU Radio module and Wireshark dissector for the Nordic Semiconductor nRF24L Enhanced Shockburst protocol. - -## external c++ classes - -### nordic_rx - -Receiver class which consumes a GFSK demodulated bitstream and reconstructs Enhanced Shockburst packets. PDUs are printed standard out and sent to Wireshark. - -### nordic_tx - -Transmitter class which consumes nordictap structs, generates Enhanced Shockburst packets, and produces a byte stream to be fed to a GFSK modulator. - -## python examples - -All python examples use the osmosdr_source/osmosdr_sink blocks, and are SDR agnostic. - -### nordic_receiver.py - -Single channel receiver. Listening on channel 4 (2404MHz) with a 2Mbps data rate, 5 byte address, and 2 byte CRC is invoked as follows: - -```./nordic_receiver.py --channel 4 --data_rate 2e6 --crc_length 2 --address_length 5 --samples_per_symbol 2 --gain 40``` - -### nordic_auto_ack.py - -Single channel receiver with auto-ACK. Listening (and ACKing) on channel 4 (2404MHz) with a 2Mbps data rate, 5 byte address, and 2 byte CRC is invoked as follows: - -```./nordic_auto_ack.py --channel 4 --data_rate 2e6 --crc_length 2 --address_length 5 --samples_per_symbol 2 --gain 40``` - -### nordic_sniffer_scanner.py - -Sweeping single channel receiver, which sweeps between channels 2-83 looking for Enhanced Shockburst packets. During receive activity, it camps on a given channel until idle. - -```./nordic_sniffer_scanner.py ``` - -### microsoft_mouse_sniffer.py - -Microsoft mouse/keyboard following receiver. When launched, this script will sweep between the 24 possible Microsoft wireless keyboard/mouse channels. When a device is found, it switches to that device's 4-channel group, sweeping between that set to follow the device. - -```./microsoft_mouse_sniffer.py ``` - -### nordic_channelized_receiver.py - -Channelized receiver example, which tunes to 2414MHz, and receives 2Mbps Enhanced Shockburst packets on channels 10, 14, and 18. - -```./nordic_channelized_receiver.py ``` - -### nordic_channelized_transmitter.py - -Channelized transmitter example, which tunes to 2414MHz, and transmits 2Mbps Enhanced Shockburst packets on channels 10, 14, and 18. - -```./nordic_channelized_transmitter.py ``` - -## wireshark dissector - -The wireshark dissector will display Enhanced Shockburst packets in Wireshark. The logic is very straightforward, and will be simple to extend to classify various device types. - -### wireshark/nordic_dissector.lua - -```wireshark -X lua_script:wireshark/nordic_dissector.lua -i lo -k -f udp ``` - -## nRF24LU1+ research firmware - -Corresponding research firmware for the nRF24LU1+ chips (including Logitech Unifying dongles) is available [here](https://github.com/BastilleResearch/nrf-research-firmware/). - -Documentation on the packet formats covered by the MouseJack and KeySniffer vulnerability sets is available [here](https://github.com/BastilleResearch/mousejack/tree/master/doc/pdf). diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index d63bda1..1aae27f 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -1,17 +1,10 @@ -# Copyright (C) 2016 Bastille Networks +# Copyright 2011 Free Software Foundation, Inc. # -# 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 3 of the License, or -# (at your option) any later version. +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . include(GrPython) diff --git a/cmake/Modules/CMakeParseArgumentsCopy.cmake b/cmake/Modules/CMakeParseArgumentsCopy.cmake index 7ce4c49..66016cb 100644 --- a/cmake/Modules/CMakeParseArgumentsCopy.cmake +++ b/cmake/Modules/CMakeParseArgumentsCopy.cmake @@ -58,7 +58,7 @@ # the new option. # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would -# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. +# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefore. #============================================================================= # Copyright 2010 Alexander Neundorf diff --git a/cmake/Modules/FindCppUnit.cmake b/cmake/Modules/FindCppUnit.cmake deleted file mode 100644 index f93ade3..0000000 --- a/cmake/Modules/FindCppUnit.cmake +++ /dev/null @@ -1,39 +0,0 @@ -# http://www.cmake.org/pipermail/cmake/2006-October/011446.html -# Modified to use pkg config and use standard var names - -# -# Find the CppUnit includes and library -# -# This module defines -# CPPUNIT_INCLUDE_DIR, where to find tiff.h, etc. -# CPPUNIT_LIBRARIES, the libraries to link against to use CppUnit. -# CPPUNIT_FOUND, If false, do not try to use CppUnit. - -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_CPPUNIT "cppunit") - -FIND_PATH(CPPUNIT_INCLUDE_DIRS - NAMES cppunit/TestCase.h - HINTS ${PC_CPPUNIT_INCLUDE_DIR} - ${CMAKE_INSTALL_PREFIX}/include - PATHS - /usr/local/include - /usr/include -) - -FIND_LIBRARY(CPPUNIT_LIBRARIES - NAMES cppunit - HINTS ${PC_CPPUNIT_LIBDIR} - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 - PATHS - ${CPPUNIT_INCLUDE_DIRS}/../lib - /usr/local/lib - /usr/lib -) - -LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS}) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) -MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) diff --git a/cmake/Modules/FindGnuradioRuntime.cmake b/cmake/Modules/FindGnuradioRuntime.cmake deleted file mode 100644 index afed684..0000000 --- a/cmake/Modules/FindGnuradioRuntime.cmake +++ /dev/null @@ -1,36 +0,0 @@ -INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(PC_GNURADIO_RUNTIME gnuradio-runtime) - -if(PC_GNURADIO_RUNTIME_FOUND) - # look for include files - FIND_PATH( - GNURADIO_RUNTIME_INCLUDE_DIRS - NAMES gnuradio/top_block.h - HINTS $ENV{GNURADIO_RUNTIME_DIR}/include - ${PC_GNURADIO_RUNTIME_INCLUDE_DIRS} - ${CMAKE_INSTALL_PREFIX}/include - PATHS /usr/local/include - /usr/include - ) - - # look for libs - FIND_LIBRARY( - GNURADIO_RUNTIME_LIBRARIES - NAMES gnuradio-runtime - HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib - ${PC_GNURADIO_RUNTIME_LIBDIR} - ${CMAKE_INSTALL_PREFIX}/lib/ - ${CMAKE_INSTALL_PREFIX}/lib64/ - PATHS /usr/local/lib - /usr/local/lib64 - /usr/lib - /usr/lib64 - ) - - set(GNURADIO_RUNTIME_FOUND ${PC_GNURADIO_RUNTIME_FOUND}) -endif(PC_GNURADIO_RUNTIME_FOUND) - -INCLUDE(FindPackageHandleStandardArgs) -# do not check GNURADIO_RUNTIME_INCLUDE_DIRS, is not set when default include path us used. -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES) -MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS) diff --git a/cmake/Modules/GrMiscUtils.cmake b/cmake/Modules/GrMiscUtils.cmake deleted file mode 100644 index 7b8b7ed..0000000 --- a/cmake/Modules/GrMiscUtils.cmake +++ /dev/null @@ -1,521 +0,0 @@ -# Copyright (C) 2016 Bastille Networks -# -# 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 3 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, see . - -if(DEFINED __INCLUDED_GR_MISC_UTILS_CMAKE) - return() -endif() -set(__INCLUDED_GR_MISC_UTILS_CMAKE TRUE) - -######################################################################## -# Set global variable macro. -# Used for subdirectories to export settings. -# Example: include and library paths. -######################################################################## -function(GR_SET_GLOBAL var) - set(${var} ${ARGN} CACHE INTERNAL "" FORCE) -endfunction(GR_SET_GLOBAL) - -######################################################################## -# Set the pre-processor definition if the condition is true. -# - def the pre-processor definition to set and condition name -######################################################################## -function(GR_ADD_COND_DEF def) - if(${def}) - add_definitions(-D${def}) - endif(${def}) -endfunction(GR_ADD_COND_DEF) - -######################################################################## -# Check for a header and conditionally set a compile define. -# - hdr the relative path to the header file -# - def the pre-processor definition to set -######################################################################## -function(GR_CHECK_HDR_N_DEF hdr def) - include(CheckIncludeFileCXX) - CHECK_INCLUDE_FILE_CXX(${hdr} ${def}) - GR_ADD_COND_DEF(${def}) -endfunction(GR_CHECK_HDR_N_DEF) - -######################################################################## -# Include subdirectory macro. -# Sets the CMake directory variables, -# includes the subdirectory CMakeLists.txt, -# resets the CMake directory variables. -# -# This macro includes subdirectories rather than adding them -# so that the subdirectory can affect variables in the level above. -# This provides a work-around for the lack of convenience libraries. -# This way a subdirectory can append to the list of library sources. -######################################################################## -macro(GR_INCLUDE_SUBDIRECTORY subdir) - #insert the current directories on the front of the list - list(INSERT _cmake_source_dirs 0 ${CMAKE_CURRENT_SOURCE_DIR}) - list(INSERT _cmake_binary_dirs 0 ${CMAKE_CURRENT_BINARY_DIR}) - - #set the current directories to the names of the subdirs - set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}) - set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${subdir}) - - #include the subdirectory CMakeLists to run it - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt) - - #reset the value of the current directories - list(GET _cmake_source_dirs 0 CMAKE_CURRENT_SOURCE_DIR) - list(GET _cmake_binary_dirs 0 CMAKE_CURRENT_BINARY_DIR) - - #pop the subdir names of the front of the list - list(REMOVE_AT _cmake_source_dirs 0) - list(REMOVE_AT _cmake_binary_dirs 0) -endmacro(GR_INCLUDE_SUBDIRECTORY) - -######################################################################## -# Check if a compiler flag works and conditionally set a compile define. -# - flag the compiler flag to check for -# - have the variable to set with result -######################################################################## -macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have) - include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG(${flag} ${have}) - if(${have}) - if(${CMAKE_VERSION} VERSION_GREATER "2.8.4") - STRING(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_dup) - if(${flag_dup} EQUAL -1) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}") - endif(${flag_dup} EQUAL -1) - endif(${CMAKE_VERSION} VERSION_GREATER "2.8.4") - endif(${have}) -endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE) - -######################################################################## -# Generates the .la libtool file -# This appears to generate libtool files that cannot be used by auto*. -# Usage GR_LIBTOOL(TARGET [target] DESTINATION [dest]) -# Notice: there is not COMPONENT option, these will not get distributed. -######################################################################## -function(GR_LIBTOOL) - if(NOT DEFINED GENERATE_LIBTOOL) - set(GENERATE_LIBTOOL OFF) #disabled by default - endif() - - if(GENERATE_LIBTOOL) - include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(GR_LIBTOOL "" "TARGET;DESTINATION" "" ${ARGN}) - - find_program(LIBTOOL libtool) - if(LIBTOOL) - include(CMakeMacroLibtoolFile) - CREATE_LIBTOOL_FILE(${GR_LIBTOOL_TARGET} /${GR_LIBTOOL_DESTINATION}) - endif(LIBTOOL) - endif(GENERATE_LIBTOOL) - -endfunction(GR_LIBTOOL) - -######################################################################## -# Do standard things to the library target -# - set target properties -# - make install rules -# Also handle gnuradio custom naming conventions w/ extras mode. -######################################################################## -function(GR_LIBRARY_FOO target) - #parse the arguments for component names - include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN}) - - #set additional target properties - set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER}) - - #install the generated files like so... - install(TARGETS ${target} - LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file - ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file - RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file - ) - - #extras mode enabled automatically on linux - if(NOT DEFINED LIBRARY_EXTRAS) - set(LIBRARY_EXTRAS ${LINUX}) - endif() - - #special extras mode to enable alternative naming conventions - if(LIBRARY_EXTRAS) - - #create .la file before changing props - GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR}) - - #give the library a special name with ultra-zero soversion - set_target_properties(${target} PROPERTIES OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0") - set(target_name lib${target}-${LIBVER}.so.0.0.0) - - #custom command to generate symlinks - add_custom_command( - TARGET ${target} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so - COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0 - COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install - ) - - #and install the extra symlinks - install( - FILES - ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so - ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0 - DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} - ) - - endif(LIBRARY_EXTRAS) -endfunction(GR_LIBRARY_FOO) - -######################################################################## -# Create a dummy custom command that depends on other targets. -# Usage: -# GR_GEN_TARGET_DEPS(unique_name target_deps ...) -# ADD_CUSTOM_COMMAND( ${target_deps}) -# -# Custom command cant depend on targets, but can depend on executables, -# and executables can depend on targets. So this is the process: -######################################################################## -function(GR_GEN_TARGET_DEPS name var) - file( - WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in - "int main(void){return 0;}\n" - ) - execute_process( - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in - ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp - ) - add_executable(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp) - if(ARGN) - add_dependencies(${name} ${ARGN}) - endif(ARGN) - - if(CMAKE_CROSSCOMPILING) - set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross - else() - set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE) - endif() -endfunction(GR_GEN_TARGET_DEPS) - -######################################################################## -# Control use of gr_logger -# Usage: -# GR_LOGGING() -# -# Will set ENABLE_GR_LOG to 1 by default. -# Can manually set with -DENABLE_GR_LOG=0|1 -######################################################################## -function(GR_LOGGING) - find_package(Log4cpp) - - OPTION(ENABLE_GR_LOG "Use gr_logger" ON) - if(ENABLE_GR_LOG) - # If gr_logger is enabled, make it usable - add_definitions( -DENABLE_GR_LOG ) - - # also test LOG4CPP; if we have it, use this version of the logger - # otherwise, default to the stdout/stderr model. - if(LOG4CPP_FOUND) - SET(HAVE_LOG4CPP True CACHE INTERNAL "" FORCE) - add_definitions( -DHAVE_LOG4CPP ) - else(not LOG4CPP_FOUND) - SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE) - SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE) - SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE) - SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE) - endif(LOG4CPP_FOUND) - - SET(ENABLE_GR_LOG ${ENABLE_GR_LOG} CACHE INTERNAL "" FORCE) - - else(ENABLE_GR_LOG) - SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE) - SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE) - SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE) - SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE) - endif(ENABLE_GR_LOG) - - message(STATUS "ENABLE_GR_LOG set to ${ENABLE_GR_LOG}.") - message(STATUS "HAVE_LOG4CPP set to ${HAVE_LOG4CPP}.") - message(STATUS "LOG4CPP_LIBRARIES set to ${LOG4CPP_LIBRARIES}.") - -endfunction(GR_LOGGING) - -######################################################################## -# Run GRCC to compile .grc files into .py files. -# -# Usage: GRCC(filename, directory) -# - filenames: List of file name of .grc file -# - directory: directory of built .py file - usually in -# ${CMAKE_CURRENT_BINARY_DIR} -# - Sets PYFILES: output converted GRC file names to Python files. -######################################################################## -function(GRCC) - # Extract directory from list of args, remove it for the list of filenames. - list(GET ARGV -1 directory) - list(REMOVE_AT ARGV -1) - set(filenames ${ARGV}) - file(MAKE_DIRECTORY ${directory}) - - SET(GRCC_COMMAND ${CMAKE_SOURCE_DIR}/gr-utils/python/grcc) - - # GRCC uses some stuff in grc and gnuradio-runtime, so we force - # the known paths here - list(APPEND PYTHONPATHS - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/gnuradio-runtime/python - ${CMAKE_SOURCE_DIR}/gnuradio-runtime/lib/swig - ${CMAKE_BINARY_DIR}/gnuradio-runtime/lib/swig - ) - - if(WIN32) - #SWIG generates the python library files into a subdirectory. - #Therefore, we must append this subdirectory into PYTHONPATH. - #Only do this for the python directories matching the following: - foreach(pydir ${PYTHONPATHS}) - get_filename_component(name ${pydir} NAME) - if(name MATCHES "^(swig|lib|src)$") - list(APPEND PYTHONPATHS ${pydir}/${CMAKE_BUILD_TYPE}) - endif() - endforeach(pydir) - endif(WIN32) - - file(TO_NATIVE_PATH "${PYTHONPATHS}" pypath) - - if(UNIX) - list(APPEND pypath "$PYTHONPATH") - string(REPLACE ";" ":" pypath "${pypath}") - set(ENV{PYTHONPATH} ${pypath}) - endif(UNIX) - - if(WIN32) - list(APPEND pypath "%PYTHONPATH%") - string(REPLACE ";" "\\;" pypath "${pypath}") - #list(APPEND environs "PYTHONPATH=${pypath}") - set(ENV{PYTHONPATH} ${pypath}) - endif(WIN32) - - foreach(f ${filenames}) - execute_process( - COMMAND ${GRCC_COMMAND} -d ${directory} ${f} - ) - string(REPLACE ".grc" ".py" pyfile "${f}") - string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" pyfile "${pyfile}") - list(APPEND pyfiles ${pyfile}) - endforeach(f) - - set(PYFILES ${pyfiles} PARENT_SCOPE) -endfunction(GRCC) - -######################################################################## -# Check if HAVE_PTHREAD_SETSCHEDPARAM and HAVE_SCHED_SETSCHEDULER -# should be defined -######################################################################## -macro(GR_CHECK_LINUX_SCHED_AVAIL) -set(CMAKE_REQUIRED_LIBRARIES -lpthread) - CHECK_CXX_SOURCE_COMPILES(" - #include - int main(){ - pthread_t pthread; - pthread_setschedparam(pthread, 0, 0); - return 0; - } " HAVE_PTHREAD_SETSCHEDPARAM - ) - GR_ADD_COND_DEF(HAVE_PTHREAD_SETSCHEDPARAM) - - CHECK_CXX_SOURCE_COMPILES(" - #include - int main(){ - pid_t pid; - sched_setscheduler(pid, 0, 0); - return 0; - } " HAVE_SCHED_SETSCHEDULER - ) - GR_ADD_COND_DEF(HAVE_SCHED_SETSCHEDULER) -endmacro(GR_CHECK_LINUX_SCHED_AVAIL) - -######################################################################## -# Macros to generate source and header files from template -######################################################################## -macro(GR_EXPAND_X_H component root) - - include(GrPython) - - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py -"#!${PYTHON_EXECUTABLE} - -import sys, os, re -sys.path.append('${GR_RUNTIME_PYTHONPATH}') -os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' -os.chdir('${CMAKE_CURRENT_BINARY_DIR}') - -if __name__ == '__main__': - import build_utils - root, inp = sys.argv[1:3] - for sig in sys.argv[3:]: - name = re.sub ('X+', sig, root) - d = build_utils.standard_dict2(name, sig, '${component}') - build_utils.expand_template(d, inp) -") - - #make a list of all the generated headers - unset(expanded_files_h) - foreach(sig ${ARGN}) - string(REGEX REPLACE "X+" ${sig} name ${root}) - list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h) - endforeach(sig) - unset(name) - - #create a command to generate the headers - add_custom_command( - OUTPUT ${expanded_files_h} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t - COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} - ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py - ${root} ${root}.h.t ${ARGN} - ) - - #install rules for the generated headers - list(APPEND generated_includes ${expanded_files_h}) - -endmacro(GR_EXPAND_X_H) - -macro(GR_EXPAND_X_CC_H component root) - - include(GrPython) - - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py -"#!${PYTHON_EXECUTABLE} - -import sys, os, re -sys.path.append('${GR_RUNTIME_PYTHONPATH}') -os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' -os.chdir('${CMAKE_CURRENT_BINARY_DIR}') - -if __name__ == '__main__': - import build_utils - root, inp = sys.argv[1:3] - for sig in sys.argv[3:]: - name = re.sub ('X+', sig, root) - d = build_utils.standard_impl_dict2(name, sig, '${component}') - build_utils.expand_template(d, inp) -") - - #make a list of all the generated files - unset(expanded_files_cc) - unset(expanded_files_h) - foreach(sig ${ARGN}) - string(REGEX REPLACE "X+" ${sig} name ${root}) - list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc) - list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h) - endforeach(sig) - unset(name) - - #create a command to generate the source files - add_custom_command( - OUTPUT ${expanded_files_cc} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t - COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} - ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py - ${root} ${root}.cc.t ${ARGN} - ) - - #create a command to generate the header files - add_custom_command( - OUTPUT ${expanded_files_h} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t - COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} - ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py - ${root} ${root}.h.t ${ARGN} - ) - - #make source files depends on headers to force generation - set_source_files_properties(${expanded_files_cc} - PROPERTIES OBJECT_DEPENDS "${expanded_files_h}" - ) - - #install rules for the generated files - list(APPEND generated_sources ${expanded_files_cc}) - list(APPEND generated_headers ${expanded_files_h}) - -endmacro(GR_EXPAND_X_CC_H) - -macro(GR_EXPAND_X_CC_H_IMPL component root) - - include(GrPython) - - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py -"#!${PYTHON_EXECUTABLE} - -import sys, os, re -sys.path.append('${GR_RUNTIME_PYTHONPATH}') -os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' -os.chdir('${CMAKE_CURRENT_BINARY_DIR}') - -if __name__ == '__main__': - import build_utils - root, inp = sys.argv[1:3] - for sig in sys.argv[3:]: - name = re.sub ('X+', sig, root) - d = build_utils.standard_dict(name, sig, '${component}') - build_utils.expand_template(d, inp, '_impl') -") - - #make a list of all the generated files - unset(expanded_files_cc_impl) - unset(expanded_files_h_impl) - unset(expanded_files_h) - foreach(sig ${ARGN}) - string(REGEX REPLACE "X+" ${sig} name ${root}) - list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc) - list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h) - list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/${component}/${name}.h) - endforeach(sig) - unset(name) - - #create a command to generate the _impl.cc files - add_custom_command( - OUTPUT ${expanded_files_cc_impl} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t - COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} - ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py - ${root} ${root}_impl.cc.t ${ARGN} - ) - - #create a command to generate the _impl.h files - add_custom_command( - OUTPUT ${expanded_files_h_impl} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t - COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} - ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py - ${root} ${root}_impl.h.t ${ARGN} - ) - - #make _impl.cc source files depend on _impl.h to force generation - set_source_files_properties(${expanded_files_cc_impl} - PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}" - ) - - #make _impl.h source files depend on headers to force generation - set_source_files_properties(${expanded_files_h_impl} - PROPERTIES OBJECT_DEPENDS "${expanded_files_h}" - ) - - #install rules for the generated files - list(APPEND generated_sources ${expanded_files_cc_impl}) - list(APPEND generated_headers ${expanded_files_h_impl}) - -endmacro(GR_EXPAND_X_CC_H_IMPL) diff --git a/cmake/Modules/GrPlatform.cmake b/cmake/Modules/GrPlatform.cmake deleted file mode 100644 index 1139047..0000000 --- a/cmake/Modules/GrPlatform.cmake +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (C) 2016 Bastille Networks -# -# 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 3 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, see . - -if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE) - return() -endif() -set(__INCLUDED_GR_PLATFORM_CMAKE TRUE) - -######################################################################## -# Setup additional defines for OS types -######################################################################## -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(LINUX TRUE) -endif() - -if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/debian_version") - set(DEBIAN TRUE) -endif() - -if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/redhat-release") - set(REDHAT TRUE) -endif() - -if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/slackware-version") - set(SLACKWARE TRUE) -endif() - -######################################################################## -# when the library suffix should be 64 (applies to redhat linux family) -######################################################################## -if (REDHAT OR SLACKWARE) - set(LIB64_CONVENTION TRUE) -endif() - -if(NOT DEFINED LIB_SUFFIX AND LIB64_CONVENTION AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$") - set(LIB_SUFFIX 64) -endif() -set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix") diff --git a/cmake/Modules/GrPython.cmake b/cmake/Modules/GrPython.cmake deleted file mode 100644 index ca6c34e..0000000 --- a/cmake/Modules/GrPython.cmake +++ /dev/null @@ -1,237 +0,0 @@ -# Copyright (C) 2016 Bastille Networks -# -# 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 3 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, see . - -if(DEFINED __INCLUDED_GR_PYTHON_CMAKE) - return() -endif() -set(__INCLUDED_GR_PYTHON_CMAKE TRUE) - -######################################################################## -# Setup the python interpreter: -# This allows the user to specify a specific interpreter, -# or finds the interpreter via the built-in cmake module. -######################################################################## -#this allows the user to override PYTHON_EXECUTABLE -if(PYTHON_EXECUTABLE) - - set(PYTHONINTERP_FOUND TRUE) - -#otherwise if not set, try to automatically find it -else(PYTHON_EXECUTABLE) - - #use the built-in find script - find_package(PythonInterp 2) - - #and if that fails use the find program routine - if(NOT PYTHONINTERP_FOUND) - find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python2.6 python2.5) - if(PYTHON_EXECUTABLE) - set(PYTHONINTERP_FOUND TRUE) - endif(PYTHON_EXECUTABLE) - endif(NOT PYTHONINTERP_FOUND) - -endif(PYTHON_EXECUTABLE) - -if (CMAKE_CROSSCOMPILING) - set(QA_PYTHON_EXECUTABLE "/usr/bin/python") -else (CMAKE_CROSSCOMPILING) - set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE}) -endif(CMAKE_CROSSCOMPILING) - -#make the path to the executable appear in the cmake gui -set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter") -set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests") - -#make sure we can use -B with python (introduced in 2.6) -if(PYTHON_EXECUTABLE) - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -B -c "" - OUTPUT_QUIET ERROR_QUIET - RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT - ) - if(PYTHON_HAS_DASH_B_RESULT EQUAL 0) - set(PYTHON_DASH_B "-B") - endif() -endif(PYTHON_EXECUTABLE) - -######################################################################## -# Check for the existence of a python module: -# - desc a string description of the check -# - mod the name of the module to import -# - cmd an additional command to run -# - have the result variable to set -######################################################################## -macro(GR_PYTHON_CHECK_MODULE desc mod cmd have) - message(STATUS "") - message(STATUS "Python checking for ${desc}") - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c " -######################################### -try: - import ${mod} - assert ${cmd} -except ImportError, AssertionError: exit(-1) -except: pass -#########################################" - RESULT_VARIABLE ${have} - ) - if(${have} EQUAL 0) - message(STATUS "Python checking for ${desc} - found") - set(${have} TRUE) - else(${have} EQUAL 0) - message(STATUS "Python checking for ${desc} - not found") - set(${have} FALSE) - endif(${have} EQUAL 0) -endmacro(GR_PYTHON_CHECK_MODULE) - -######################################################################## -# Sets the python installation directory GR_PYTHON_DIR -######################################################################## -if(NOT DEFINED GR_PYTHON_DIR) -execute_process(COMMAND ${PYTHON_EXECUTABLE} -c " -from distutils import sysconfig -print sysconfig.get_python_lib(plat_specific=True, prefix='') -" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE -) -endif() -file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR) - -######################################################################## -# Create an always-built target with a unique name -# Usage: GR_UNIQUE_TARGET( ) -######################################################################## -function(GR_UNIQUE_TARGET desc) - file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib -unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5] -print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))" - OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE) - add_custom_target(${_target} ALL DEPENDS ${ARGN}) -endfunction(GR_UNIQUE_TARGET) - -######################################################################## -# Install python sources (also builds and installs byte-compiled python) -######################################################################## -function(GR_PYTHON_INSTALL) - include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN}) - - #################################################################### - if(GR_PYTHON_INSTALL_FILES) - #################################################################### - install(${ARGN}) #installs regular python files - - #create a list of all generated files - unset(pysrcfiles) - unset(pycfiles) - unset(pyofiles) - foreach(pyfile ${GR_PYTHON_INSTALL_FILES}) - get_filename_component(pyfile ${pyfile} ABSOLUTE) - list(APPEND pysrcfiles ${pyfile}) - - #determine if this file is in the source or binary directory - file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile}) - string(LENGTH "${source_rel_path}" source_rel_path_len) - file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile}) - string(LENGTH "${binary_rel_path}" binary_rel_path_len) - - #and set the generated path appropriately - if(${source_rel_path_len} GREATER ${binary_rel_path_len}) - set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path}) - else() - set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path}) - endif() - list(APPEND pycfiles ${pygenfile}c) - list(APPEND pyofiles ${pygenfile}o) - - #ensure generation path exists - get_filename_component(pygen_path ${pygenfile} PATH) - file(MAKE_DIRECTORY ${pygen_path}) - - endforeach(pyfile) - - #the command to generate the pyc files - add_custom_command( - DEPENDS ${pysrcfiles} OUTPUT ${pycfiles} - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles} - ) - - #the command to generate the pyo files - add_custom_command( - DEPENDS ${pysrcfiles} OUTPUT ${pyofiles} - COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles} - ) - - #create install rule and add generated files to target list - set(python_install_gen_targets ${pycfiles} ${pyofiles}) - install(FILES ${python_install_gen_targets} - DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} - COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} - ) - - #################################################################### - elseif(GR_PYTHON_INSTALL_PROGRAMS) - #################################################################### - file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native) - - if (CMAKE_CROSSCOMPILING) - set(pyexe_native "/usr/bin/env python") - endif() - - foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS}) - get_filename_component(pyfile_name ${pyfile} NAME) - get_filename_component(pyfile ${pyfile} ABSOLUTE) - string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe") - list(APPEND python_install_gen_targets ${pyexefile}) - - get_filename_component(pyexefile_path ${pyexefile} PATH) - file(MAKE_DIRECTORY ${pyexefile_path}) - - add_custom_command( - OUTPUT ${pyexefile} DEPENDS ${pyfile} - COMMAND ${PYTHON_EXECUTABLE} -c - "import re; R=re.compile('^\#!.*$\\n',flags=re.MULTILINE); open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+R.sub('',open('${pyfile}','r').read()))" - COMMENT "Shebangin ${pyfile_name}" - VERBATIM - ) - - #on windows, python files need an extension to execute - get_filename_component(pyfile_ext ${pyfile} EXT) - if(WIN32 AND NOT pyfile_ext) - set(pyfile_name "${pyfile_name}.py") - endif() - - install(PROGRAMS ${pyexefile} RENAME ${pyfile_name} - DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} - COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} - ) - endforeach(pyfile) - - endif() - - GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets}) - -endfunction(GR_PYTHON_INSTALL) - -######################################################################## -# Write the python helper script that generates byte code files -######################################################################## -file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py " -import sys, py_compile -files = sys.argv[1:] -srcs, gens = files[:len(files)/2], files[len(files)/2:] -for src, gen in zip(srcs, gens): - py_compile.compile(file=src, cfile=gen, doraise=True) -") diff --git a/cmake/Modules/GrSwig.cmake b/cmake/Modules/GrSwig.cmake deleted file mode 100644 index 59720ca..0000000 --- a/cmake/Modules/GrSwig.cmake +++ /dev/null @@ -1,247 +0,0 @@ -# Copyright (C) 2016 Bastille Networks -# -# 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 3 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, see . - -if(DEFINED __INCLUDED_GR_SWIG_CMAKE) - return() -endif() -set(__INCLUDED_GR_SWIG_CMAKE TRUE) - -include(GrPython) - -######################################################################## -# Builds a swig documentation file to be generated into python docstrings -# Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....) -# -# Set the following variable to specify extra dependent targets: -# - GR_SWIG_DOCS_SOURCE_DEPS -# - GR_SWIG_DOCS_TARGET_DEPS -######################################################################## -function(GR_SWIG_MAKE_DOCS output_file) - if(ENABLE_DOXYGEN) - - #setup the input files variable list, quote formated - set(input_files) - unset(INPUT_PATHS) - foreach(input_path ${ARGN}) - if(IS_DIRECTORY ${input_path}) #when input path is a directory - file(GLOB input_path_h_files ${input_path}/*.h) - else() #otherwise its just a file, no glob - set(input_path_h_files ${input_path}) - endif() - list(APPEND input_files ${input_path_h_files}) - set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"") - endforeach(input_path) - - #determine the output directory - get_filename_component(name ${output_file} NAME_WE) - get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH) - set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs) - make_directory(${OUTPUT_DIRECTORY}) - - #generate the Doxyfile used by doxygen - configure_file( - ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in - ${OUTPUT_DIRECTORY}/Doxyfile - @ONLY) - - #Create a dummy custom command that depends on other targets - include(GrMiscUtils) - GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS}) - - #call doxygen on the Doxyfile + input headers - add_custom_command( - OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml - DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps} - COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile - COMMENT "Generating doxygen xml for ${name} docs" - ) - - #call the swig_doc script on the xml files - add_custom_command( - OUTPUT ${output_file} - DEPENDS ${input_files} ${stamp-file} ${OUTPUT_DIRECTORY}/xml/index.xml - COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} - ${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py - ${OUTPUT_DIRECTORY}/xml - ${output_file} - COMMENT "Generating python docstrings for ${name}" - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen - ) - - else(ENABLE_DOXYGEN) - file(WRITE ${output_file} "\n") #no doxygen -> empty file - endif(ENABLE_DOXYGEN) -endfunction(GR_SWIG_MAKE_DOCS) - -######################################################################## -# Build a swig target for the common gnuradio use case. Usage: -# GR_SWIG_MAKE(target ifile ifile ifile...) -# -# Set the following variables before calling: -# - GR_SWIG_FLAGS -# - GR_SWIG_INCLUDE_DIRS -# - GR_SWIG_LIBRARIES -# - GR_SWIG_SOURCE_DEPS -# - GR_SWIG_TARGET_DEPS -# - GR_SWIG_DOC_FILE -# - GR_SWIG_DOC_DIRS -######################################################################## -macro(GR_SWIG_MAKE name) - set(ifiles ${ARGN}) - - # Shimming this in here to take care of a SWIG bug with handling - # vector and vector (on 32-bit machines) and - # vector (on 64-bit machines). Use this to test - # the size of size_t, then set SIZE_T_32 if it's a 32-bit machine - # or not if it's 64-bit. The logic in gr_type.i handles the rest. - INCLUDE(CheckTypeSize) - CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T) - CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT) - if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) - list(APPEND GR_SWIG_FLAGS -DSIZE_T_32) - endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) - - #do swig doc generation if specified - if(GR_SWIG_DOC_FILE) - set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS}) - list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS}) - GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS}) - add_custom_target(${name}_swig_doc DEPENDS ${GR_SWIG_DOC_FILE}) - list(APPEND GR_SWIG_TARGET_DEPS ${name}_swig_doc ${GR_RUNTIME_SWIG_DOC_FILE}) - endif() - - #append additional include directories - find_package(PythonLibs 2) - list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs) - list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) - - #prepend local swig directories - list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_SOURCE_DIR}) - list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_BINARY_DIR}) - - #determine include dependencies for swig file - execute_process( - COMMAND ${PYTHON_EXECUTABLE} - ${CMAKE_BINARY_DIR}/get_swig_deps.py - "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}" - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - ) - - #Create a dummy custom command that depends on other targets - include(GrMiscUtils) - GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS}) - set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag) - add_custom_command( - OUTPUT ${tag_file} - DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps} - COMMAND ${CMAKE_COMMAND} -E touch ${tag_file} - ) - - #append the specified include directories - include_directories(${GR_SWIG_INCLUDE_DIRS}) - list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file}) - - #setup the swig flags with flags and include directories - set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS}) - foreach(dir ${GR_SWIG_INCLUDE_DIRS}) - list(APPEND CMAKE_SWIG_FLAGS "-I${dir}") - endforeach(dir) - - #set the C++ property on the swig .i file so it builds - set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON) - - #setup the actual swig library target to be built - include(UseSWIG) - SWIG_ADD_MODULE(${name} python ${ifiles}) - SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES}) - if(${name} STREQUAL "runtime_swig") - SET_TARGET_PROPERTIES(${SWIG_MODULE_runtime_swig_REAL_NAME} PROPERTIES DEFINE_SYMBOL "gnuradio_runtime_EXPORTS") - endif(${name} STREQUAL "runtime_swig") - -endmacro(GR_SWIG_MAKE) - -######################################################################## -# Install swig targets generated by GR_SWIG_MAKE. Usage: -# GR_SWIG_INSTALL( -# TARGETS target target target... -# [DESTINATION destination] -# [COMPONENT component] -# ) -######################################################################## -macro(GR_SWIG_INSTALL) - - include(CMakeParseArgumentsCopy) - CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN}) - - foreach(name ${GR_SWIG_INSTALL_TARGETS}) - install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME} - DESTINATION ${GR_SWIG_INSTALL_DESTINATION} - COMPONENT ${GR_SWIG_INSTALL_COMPONENT} - ) - - include(GrPython) - GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py - DESTINATION ${GR_SWIG_INSTALL_DESTINATION} - COMPONENT ${GR_SWIG_INSTALL_COMPONENT} - ) - - GR_LIBTOOL( - TARGET ${SWIG_MODULE_${name}_REAL_NAME} - DESTINATION ${GR_SWIG_INSTALL_DESTINATION} - ) - - endforeach(name) - -endmacro(GR_SWIG_INSTALL) - -######################################################################## -# Generate a python file that can determine swig dependencies. -# Used by the make macro above to determine extra dependencies. -# When you build C++, CMake figures out the header dependencies. -# This code essentially performs that logic for swig includes. -######################################################################## -file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py " - -import os, sys, re - -i_include_matcher = re.compile('%(include|import)\\s*[<|\"](.*)[>|\"]') -h_include_matcher = re.compile('#(include)\\s*[<|\"](.*)[>|\"]') -include_dirs = sys.argv[2].split(';') - -def get_swig_incs(file_path): - if file_path.endswith('.i'): matcher = i_include_matcher - else: matcher = h_include_matcher - file_contents = open(file_path, 'r').read() - return matcher.findall(file_contents, re.MULTILINE) - -def get_swig_deps(file_path, level): - deps = [file_path] - if level == 0: return deps - for keyword, inc_file in get_swig_incs(file_path): - for inc_dir in include_dirs: - inc_path = os.path.join(inc_dir, inc_file) - if not os.path.exists(inc_path): continue - deps.extend(get_swig_deps(inc_path, level-1)) - break #found, we dont search in lower prio inc dirs - return deps - -if __name__ == '__main__': - ifiles = sys.argv[1].split(';') - deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], []) - #sys.stderr.write(';'.join(set(deps)) + '\\n\\n') - print(';'.join(set(deps))) -") diff --git a/cmake/Modules/GrTest.cmake b/cmake/Modules/GrTest.cmake deleted file mode 100644 index 8660715..0000000 --- a/cmake/Modules/GrTest.cmake +++ /dev/null @@ -1,139 +0,0 @@ -# Copyright (C) 2016 Bastille Networks -# -# 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 3 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, see . - -if(DEFINED __INCLUDED_GR_TEST_CMAKE) - return() -endif() -set(__INCLUDED_GR_TEST_CMAKE TRUE) - -######################################################################## -# Add a unit test and setup the environment for a unit test. -# Takes the same arguments as the ADD_TEST function. -# -# Before calling set the following variables: -# GR_TEST_TARGET_DEPS - built targets for the library path -# GR_TEST_LIBRARY_DIRS - directories for the library path -# GR_TEST_PYTHON_DIRS - directories for the python path -# GR_TEST_ENVIRONS - other environment key/value pairs -######################################################################## -function(GR_ADD_TEST test_name) - - #Ensure that the build exe also appears in the PATH. - list(APPEND GR_TEST_TARGET_DEPS ${ARGN}) - - #In the land of windows, all libraries must be in the PATH. - #Since the dependent libraries are not yet installed, - #we must manually set them in the PATH to run tests. - #The following appends the path of a target dependency. - foreach(target ${GR_TEST_TARGET_DEPS}) - get_target_property(location ${target} LOCATION) - if(location) - get_filename_component(path ${location} PATH) - string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path}) - list(APPEND GR_TEST_LIBRARY_DIRS ${path}) - endif(location) - endforeach(target) - - if(WIN32) - #SWIG generates the python library files into a subdirectory. - #Therefore, we must append this subdirectory into PYTHONPATH. - #Only do this for the python directories matching the following: - foreach(pydir ${GR_TEST_PYTHON_DIRS}) - get_filename_component(name ${pydir} NAME) - if(name MATCHES "^(swig|lib|src)$") - list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE}) - endif() - endforeach(pydir) - endif(WIN32) - - file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir) - file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list? - file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list? - - set(environs "VOLK_GENERIC=1" "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}") - list(APPEND environs ${GR_TEST_ENVIRONS}) - - #http://www.cmake.org/pipermail/cmake/2009-May/029464.html - #Replaced this add test + set environs code with the shell script generation. - #Its nicer to be able to manually run the shell script to diagnose problems. - #ADD_TEST(${ARGV}) - #SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}") - - if(UNIX) - set(LD_PATH_VAR "LD_LIBRARY_PATH") - if(APPLE) - set(LD_PATH_VAR "DYLD_LIBRARY_PATH") - endif() - - set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH") - list(APPEND libpath "$${LD_PATH_VAR}") - list(APPEND pypath "$PYTHONPATH") - - #replace list separator with the path separator - string(REPLACE ";" ":" libpath "${libpath}") - string(REPLACE ";" ":" pypath "${pypath}") - list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}" "PYTHONPATH=${pypath}") - - #generate a bat file that sets the environment and runs the test - if (CMAKE_CROSSCOMPILING) - set(SHELL "/bin/sh") - else(CMAKE_CROSSCOMPILING) - find_program(SHELL sh) - endif(CMAKE_CROSSCOMPILING) - set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh) - file(WRITE ${sh_file} "#!${SHELL}\n") - #each line sets an environment variable - foreach(environ ${environs}) - file(APPEND ${sh_file} "export ${environ}\n") - endforeach(environ) - #load the command to run with its arguments - foreach(arg ${ARGN}) - file(APPEND ${sh_file} "${arg} ") - endforeach(arg) - file(APPEND ${sh_file} "\n") - - #make the shell file executable - execute_process(COMMAND chmod +x ${sh_file}) - - add_test(${test_name} ${SHELL} ${sh_file}) - - endif(UNIX) - - if(WIN32) - list(APPEND libpath ${DLL_PATHS} "%PATH%") - list(APPEND pypath "%PYTHONPATH%") - - #replace list separator with the path separator (escaped) - string(REPLACE ";" "\\;" libpath "${libpath}") - string(REPLACE ";" "\\;" pypath "${pypath}") - list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}") - - #generate a bat file that sets the environment and runs the test - set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat) - file(WRITE ${bat_file} "@echo off\n") - #each line sets an environment variable - foreach(environ ${environs}) - file(APPEND ${bat_file} "SET ${environ}\n") - endforeach(environ) - #load the command to run with its arguments - foreach(arg ${ARGN}) - file(APPEND ${bat_file} "${arg} ") - endforeach(arg) - file(APPEND ${bat_file} "\n") - - add_test(${test_name} ${bat_file}) - endif(WIN32) - -endfunction(GR_ADD_TEST) diff --git a/cmake/Modules/UseSWIG.cmake b/cmake/Modules/UseSWIG.cmake deleted file mode 100644 index c0f1728..0000000 --- a/cmake/Modules/UseSWIG.cmake +++ /dev/null @@ -1,304 +0,0 @@ -# - SWIG module for CMake -# Defines the following macros: -# SWIG_ADD_MODULE(name language [ files ]) -# - Define swig module with given name and specified language -# SWIG_LINK_LIBRARIES(name [ libraries ]) -# - Link libraries to swig module -# All other macros are for internal use only. -# To get the actual name of the swig module, -# use: ${SWIG_MODULE_${name}_REAL_NAME}. -# Set Source files properties such as CPLUSPLUS and SWIG_FLAGS to specify -# special behavior of SWIG. Also global CMAKE_SWIG_FLAGS can be used to add -# special flags to all swig calls. -# Another special variable is CMAKE_SWIG_OUTDIR, it allows one to specify -# where to write all the swig generated module (swig -outdir option) -# The name-specific variable SWIG_MODULE__EXTRA_DEPS may be used -# to specify extra dependencies for the generated modules. -# If the source file generated by swig need some special flag you can use -# set_source_files_properties( ${swig_generated_file_fullname} -# PROPERTIES COMPILE_FLAGS "-bla") - - -#============================================================================= -# Copyright 2004-2009 Kitware, Inc. -# Copyright 2009 Mathieu Malaterre -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -set(SWIG_CXX_EXTENSION "cxx") -set(SWIG_EXTRA_LIBRARIES "") - -set(SWIG_PYTHON_EXTRA_FILE_EXTENSION "py") - -# -# For given swig module initialize variables associated with it -# -macro(SWIG_MODULE_INITIALIZE name language) - string(TOUPPER "${language}" swig_uppercase_language) - string(TOLOWER "${language}" swig_lowercase_language) - set(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}") - set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}") - - set(SWIG_MODULE_${name}_REAL_NAME "${name}") - if("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "UNKNOWN") - message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found") - elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PYTHON") - # when swig is used without the -interface it will produce in the module.py - # a 'import _modulename' statement, which implies having a corresponding - # _modulename.so (*NIX), _modulename.pyd (Win32). - set(SWIG_MODULE_${name}_REAL_NAME "_${name}") - elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PERL") - set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") - endif() -endmacro() - -# -# For a given language, input file, and output file, determine extra files that -# will be generated. This is internal swig macro. -# - -macro(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile) - set(${outfiles} "") - get_source_file_property(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename - ${infile} SWIG_MODULE_NAME) - if(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND") - get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${infile}" NAME_WE) - endif() - foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSION}) - set(${outfiles} ${${outfiles}} - "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}.${it}") - endforeach() -endmacro() - -# -# Take swig (*.i) file and add proper custom commands for it -# -macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) - set(swig_full_infile ${infile}) - get_filename_component(swig_source_file_path "${infile}" PATH) - get_filename_component(swig_source_file_name_we "${infile}" NAME_WE) - get_source_file_property(swig_source_file_generated ${infile} GENERATED) - get_source_file_property(swig_source_file_cplusplus ${infile} CPLUSPLUS) - get_source_file_property(swig_source_file_flags ${infile} SWIG_FLAGS) - if("${swig_source_file_flags}" STREQUAL "NOTFOUND") - set(swig_source_file_flags "") - endif() - set(swig_source_file_fullname "${infile}") - if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}") - string(REGEX REPLACE - "^${CMAKE_CURRENT_SOURCE_DIR}" "" - swig_source_file_relative_path - "${swig_source_file_path}") - else() - if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}") - string(REGEX REPLACE - "^${CMAKE_CURRENT_BINARY_DIR}" "" - swig_source_file_relative_path - "${swig_source_file_path}") - set(swig_source_file_generated 1) - else() - set(swig_source_file_relative_path "${swig_source_file_path}") - if(swig_source_file_generated) - set(swig_source_file_fullname "${CMAKE_CURRENT_BINARY_DIR}/${infile}") - else() - set(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}") - endif() - endif() - endif() - - set(swig_generated_file_fullname - "${CMAKE_CURRENT_BINARY_DIR}") - if(swig_source_file_relative_path) - set(swig_generated_file_fullname - "${swig_generated_file_fullname}/${swig_source_file_relative_path}") - endif() - # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir - if(CMAKE_SWIG_OUTDIR) - set(swig_outdir ${CMAKE_SWIG_OUTDIR}) - else() - set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR}) - endif() - SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE} - swig_extra_generated_files - "${swig_outdir}" - "${infile}") - set(swig_generated_file_fullname - "${swig_generated_file_fullname}/${swig_source_file_name_we}") - # add the language into the name of the file (i.e. TCL_wrap) - # this allows for the same .i file to be wrapped into different languages - set(swig_generated_file_fullname - "${swig_generated_file_fullname}${SWIG_MODULE_${name}_LANGUAGE}_wrap") - - if(swig_source_file_cplusplus) - set(swig_generated_file_fullname - "${swig_generated_file_fullname}.${SWIG_CXX_EXTENSION}") - else() - set(swig_generated_file_fullname - "${swig_generated_file_fullname}.c") - endif() - - # Shut up some warnings from poor SWIG code generation that we - # can do nothing about, when this flag is available - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag("-Wno-unused-but-set-variable" HAVE_WNO_UNUSED_BUT_SET_VARIABLE) - if(HAVE_WNO_UNUSED_BUT_SET_VARIABLE) - set_source_files_properties(${swig_generated_file_fullname} - PROPERTIES COMPILE_FLAGS "-Wno-unused-but-set-variable") - endif(HAVE_WNO_UNUSED_BUT_SET_VARIABLE) - - get_directory_property(cmake_include_directories INCLUDE_DIRECTORIES) - set(swig_include_dirs) - foreach(it ${cmake_include_directories}) - set(swig_include_dirs ${swig_include_dirs} "-I${it}") - endforeach() - - set(swig_special_flags) - # default is c, so add c++ flag if it is c++ - if(swig_source_file_cplusplus) - set(swig_special_flags ${swig_special_flags} "-c++") - endif() - set(swig_extra_flags) - if(SWIG_MODULE_${name}_EXTRA_FLAGS) - set(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS}) - endif() - - # hack to work around CMake bug in add_custom_command with multiple OUTPUT files - - file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib -unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5] -print(re.sub('\\W', '_', '${name} ${reldir} ' + unique))" - OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - file( - WRITE ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in - "int main(void){return 0;}\n" - ) - - # create dummy dependencies - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in - ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp - DEPENDS "${swig_source_file_fullname}" ${SWIG_MODULE_${name}_EXTRA_DEPS} - COMMENT "" - ) - - # create the dummy target - add_executable(${_target} ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp) - - # add a custom command to the dummy target - add_custom_command( - TARGET ${_target} - # Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir) - COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir} - COMMAND "${SWIG_EXECUTABLE}" - ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}" - ${swig_source_file_flags} - ${CMAKE_SWIG_FLAGS} - -outdir ${swig_outdir} - ${swig_special_flags} - ${swig_extra_flags} - ${swig_include_dirs} - -o "${swig_generated_file_fullname}" - "${swig_source_file_fullname}" - COMMENT "Swig source" - ) - - #add dummy independent dependencies from the _target to each file - #that will be generated by the SWIG command above - - set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files}) - - foreach(swig_gen_file ${${outfiles}}) - add_custom_command( - OUTPUT ${swig_gen_file} - COMMAND "" - DEPENDS ${_target} - COMMENT "" - ) - endforeach() - - set_source_files_properties( - ${outfiles} PROPERTIES GENERATED 1 - ) - -endmacro() - -# -# Create Swig module -# -macro(SWIG_ADD_MODULE name language) - SWIG_MODULE_INITIALIZE(${name} ${language}) - set(swig_dot_i_sources) - set(swig_other_sources) - foreach(it ${ARGN}) - if(${it} MATCHES ".*\\.i$") - set(swig_dot_i_sources ${swig_dot_i_sources} "${it}") - else() - set(swig_other_sources ${swig_other_sources} "${it}") - endif() - endforeach() - - set(swig_generated_sources) - foreach(it ${swig_dot_i_sources}) - SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it}) - set(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}") - endforeach() - get_directory_property(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES) - set_directory_properties(PROPERTIES - ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}") - add_library(${SWIG_MODULE_${name}_REAL_NAME} - MODULE - ${swig_generated_sources} - ${swig_other_sources}) - string(TOLOWER "${language}" swig_lowercase_language) - if ("${swig_lowercase_language}" STREQUAL "java") - if (APPLE) - # In java you want: - # System.loadLibrary("LIBRARY"); - # then JNI will look for a library whose name is platform dependent, namely - # MacOS : libLIBRARY.jnilib - # Windows: LIBRARY.dll - # Linux : libLIBRARY.so - set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib") - endif () - endif () - if ("${swig_lowercase_language}" STREQUAL "python") - # this is only needed for the python case where a _modulename.so is generated - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "") - # Python extension modules on Windows must have the extension ".pyd" - # instead of ".dll" as of Python 2.5. Older python versions do support - # this suffix. - # http://docs.python.org/whatsnew/ports.html#SECTION0001510000000000000000 - # - # Windows: .dll is no longer supported as a filename extension for extension modules. - # .pyd is now the only filename extension that will be searched for. - # - if(WIN32 AND NOT CYGWIN) - set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd") - endif() - endif () -endmacro() - -# -# Like TARGET_LINK_LIBRARIES but for swig modules -# -macro(SWIG_LINK_LIBRARIES name) - if(SWIG_MODULE_${name}_REAL_NAME) - target_link_libraries(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN}) - else() - message(SEND_ERROR "Cannot find Swig library \"${name}\".") - endif() -endmacro() diff --git a/cmake/Modules/nordicConfig.cmake b/cmake/Modules/nordicConfig.cmake index 366ceeb..54442a7 100644 --- a/cmake/Modules/nordicConfig.cmake +++ b/cmake/Modules/nordicConfig.cmake @@ -1,4 +1,6 @@ -INCLUDE(FindPkgConfig) +if(NOT PKG_CONFIG_FOUND) + INCLUDE(FindPkgConfig) +endif() PKG_CHECK_MODULES(PC_NORDIC nordic) FIND_PATH( @@ -22,9 +24,10 @@ FIND_LIBRARY( /usr/local/lib64 /usr/lib /usr/lib64 -) + ) + +include("${CMAKE_CURRENT_LIST_DIR}/nordicTarget.cmake") INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(NORDIC DEFAULT_MSG NORDIC_LIBRARIES NORDIC_INCLUDE_DIRS) MARK_AS_ADVANCED(NORDIC_LIBRARIES NORDIC_INCLUDE_DIRS) - diff --git a/cmake/Modules/targetConfig.cmake.in b/cmake/Modules/targetConfig.cmake.in new file mode 100644 index 0000000..4a1fb31 --- /dev/null +++ b/cmake/Modules/targetConfig.cmake.in @@ -0,0 +1,14 @@ +# Copyright 2018 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +include(CMakeFindDependencyMacro) + +set(target_deps "@TARGET_DEPENDENCIES@") +foreach(dep IN LISTS target_deps) + find_dependency(${dep}) +endforeach() +include("${CMAKE_CURRENT_LIST_DIR}/@TARGET@Targets.cmake") diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 32aedd1..109b0c9 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,17 +1,10 @@ -# Copyright (C) 2016 Bastille Networks +# Copyright 2011 Free Software Foundation, Inc. # -# 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 3 of the License, or -# (at your option) any later version. +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . ######################################################################## # Setup dependencies diff --git a/docs/doxygen/CMakeLists.txt b/docs/doxygen/CMakeLists.txt index 107f05e..618c7ff 100644 --- a/docs/doxygen/CMakeLists.txt +++ b/docs/doxygen/CMakeLists.txt @@ -1,17 +1,10 @@ -# Copyright (C) 2016 Bastille Networks +# Copyright 2011 Free Software Foundation, Inc. # -# 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 3 of the License, or -# (at your option) any later version. +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . ######################################################################## # Create the doxygen configuration file @@ -24,6 +17,7 @@ file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir) set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) set(enable_html_docs YES) set(enable_latex_docs NO) +set(enable_mathjax NO) set(enable_xml_docs YES) configure_file( diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index 17a451d..6b638d2 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -199,13 +199,6 @@ TAB_SIZE = 8 ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list @@ -654,8 +647,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @top_srcdir@ \ - @top_builddir@ +INPUT = "@top_srcdir@" \ + "@top_builddir@" # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -723,8 +716,6 @@ EXCLUDE_PATTERNS = */.deps/* \ EXCLUDE_SYMBOLS = ad9862 \ numpy \ - *swig* \ - *Swig* \ *my_top_block* \ *my_graph* \ *app_top_block* \ @@ -790,7 +781,7 @@ INPUT_FILTER = # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. -FILTER_PATTERNS = *.py=@top_srcdir@/doc/doxygen/other/doxypy.py +FILTER_PATTERNS = *.py="@top_srcdir@"/doc/doxygen/other/doxypy.py # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source @@ -945,7 +936,7 @@ HTML_STYLESHEET = # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more +# since it does not replace the standard style sheet and is therefore more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. @@ -989,7 +980,7 @@ HTML_COLORSTYLE_GAMMA = 80 # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. -HTML_TIMESTAMP = YES +HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1220,14 +1211,14 @@ FORMULA_TRANSPARENT = YES # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. -USE_MATHJAX = NO +USE_MATHJAX = @enable_mathjax@ # When MathJax is enabled you can set the default output format to be used for # the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. -MATHJAX_FORMAT = HTML-CSS +MATHJAX_FORMAT = SVG # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination @@ -1239,12 +1230,12 @@ MATHJAX_FORMAT = HTML-CSS # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_RELPATH = @MATHJAX2_PATH@ # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # The MATHJAX_CODEFILE tag can be used to specify a file with javascript # pieces of code that will be used on startup of the MathJax code. @@ -1503,18 +1494,6 @@ GENERATE_XML = @enable_xml_docs@ XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that @@ -1692,11 +1671,6 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- @@ -1709,15 +1683,6 @@ PERL_PATH = /usr/bin/perl CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. @@ -1846,7 +1811,7 @@ DIRECTORY_GRAPH = YES # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. diff --git a/docs/doxygen/Doxyfile.swig_doc.in b/docs/doxygen/Doxyfile.swig_doc.in index 57736d7..cbe06d6 100644 --- a/docs/doxygen/Doxyfile.swig_doc.in +++ b/docs/doxygen/Doxyfile.swig_doc.in @@ -54,7 +54,7 @@ PROJECT_LOGO = # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = @OUTPUT_DIRECTORY@ +OUTPUT_DIRECTORY = "@OUTPUT_DIRECTORY@" # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output @@ -121,7 +121,7 @@ INLINE_INHERITED_MEMB = NO # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. -FULL_PATH_NAMES = YES +FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is @@ -913,7 +913,7 @@ HTML_STYLESHEET = # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more +# since it does not replace the standard style sheet and is therefore more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. @@ -957,7 +957,7 @@ HTML_COLORSTYLE_GAMMA = 80 # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. -HTML_TIMESTAMP = YES +HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1471,18 +1471,6 @@ GENERATE_XML = YES XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that diff --git a/docs/doxygen/doxyxml/__init__.py b/docs/doxygen/doxyxml/__init__.py index 6df88dc..5d0f587 100644 --- a/docs/doxygen/doxyxml/__init__.py +++ b/docs/doxygen/doxyxml/__init__.py @@ -1,20 +1,12 @@ -''' - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -''' - +# +# Copyright 2010 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# """ Python interface to contents of doxygen xml documentation. @@ -61,7 +53,7 @@ """ -from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther +from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther def _test(): import os diff --git a/docs/doxygen/doxyxml/base.py b/docs/doxygen/doxyxml/base.py index 383dc26..00caa02 100644 --- a/docs/doxygen/doxyxml/base.py +++ b/docs/doxygen/doxyxml/base.py @@ -1,20 +1,12 @@ -''' - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -''' - +# +# Copyright 2010 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# """ A base class is created. @@ -27,18 +19,18 @@ from xml.parsers.expat import ExpatError -from generated import compound +from .generated import compound class Base(object): - class Duplicate(StandardError): + class Duplicate(Exception): pass - class NoSuchMember(StandardError): + class NoSuchMember(Exception): pass - class ParsingError(StandardError): + class ParsingError(Exception): pass def __init__(self, parse_data, top=None): @@ -91,7 +83,7 @@ def get_cls(self, mem): for cls in self.mem_classes: if cls.can_parse(mem): return cls - raise StandardError(("Did not find a class for object '%s'." \ + raise Exception(("Did not find a class for object '%s'." \ % (mem.get_name()))) def convert_mem(self, mem): @@ -99,11 +91,11 @@ def convert_mem(self, mem): cls = self.get_cls(mem) converted = cls.from_parse_data(mem, self.top) if converted is None: - raise StandardError('No class matched this object.') + raise Exception('No class matched this object.') self.add_ref(converted) return converted - except StandardError, e: - print e + except Exception as e: + print(e) @classmethod def includes(cls, inst): diff --git a/docs/doxygen/doxyxml/doxyindex.py b/docs/doxygen/doxyxml/doxyindex.py index 8fed1b4..0903cd5 100644 --- a/docs/doxygen/doxyxml/doxyindex.py +++ b/docs/doxygen/doxyxml/doxyindex.py @@ -1,20 +1,12 @@ -''' - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -''' - +# +# Copyright 2010 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# """ Classes providing more user-friendly interfaces to the doxygen xml docs than the generated classes provide. @@ -22,9 +14,9 @@ import os -from generated import index -from base import Base -from text import description +from .generated import index +from .base import Base +from .text import description class DoxyIndex(Base): """ @@ -40,25 +32,20 @@ def _parse(self): self._root = index.parse(os.path.join(self._xml_path, 'index.xml')) for mem in self._root.compound: converted = self.convert_mem(mem) - # For files we want the contents to be accessible directly - # from the parent rather than having to go through the file - # object. + # For files and namespaces we want the contents to be + # accessible directly from the parent rather than having + # to go through the file object. if self.get_cls(mem) == DoxyFile: if mem.name.endswith('.h'): self._members += converted.members() self._members.append(converted) + elif self.get_cls(mem) == DoxyNamespace: + self._members += converted.members() + self._members.append(converted) else: self._members.append(converted) -def generate_swig_doc_i(self): - """ - %feature("docstring") gr_make_align_on_samplenumbers_ss::align_state " - Wraps the C++: gr_align_on_samplenumbers_ss::align_state"; - """ - pass - - class DoxyCompMem(Base): @@ -77,13 +64,29 @@ def set_descriptions(self, parse_data): self._data['brief_description'] = bd self._data['detailed_description'] = dd + def set_parameters(self, data): + vs = [ddc.value for ddc in data.detaileddescription.content_] + pls = [] + for v in vs: + if hasattr(v, 'parameterlist'): + pls += v.parameterlist + pis = [] + for pl in pls: + pis += pl.parameteritem + dpis = [] + for pi in pis: + dpi = DoxyParameterItem(pi) + dpi._parse() + dpis.append(dpi) + self._data['params'] = dpis + + class DoxyCompound(DoxyCompMem): pass class DoxyMember(DoxyCompMem): pass - class DoxyFunction(DoxyMember): __module__ = "gnuradio.utils.doxyxml" @@ -95,10 +98,13 @@ def _parse(self): return super(DoxyFunction, self)._parse() self.set_descriptions(self._parse_data) - self._data['params'] = [] - prms = self._parse_data.param - for prm in prms: - self._data['params'].append(DoxyParam(prm)) + self.set_parameters(self._parse_data) + if not self._data['params']: + # If the params weren't set by a comment then just grab the names. + self._data['params'] = [] + prms = self._parse_data.param + for prm in prms: + self._data['params'].append(DoxyParam(prm)) brief_description = property(lambda self: self.data()['brief_description']) detailed_description = property(lambda self: self.data()['detailed_description']) @@ -118,9 +124,39 @@ def _parse(self): self.set_descriptions(self._parse_data) self._data['declname'] = self._parse_data.declname + @property + def description(self): + descriptions = [] + if self.brief_description: + descriptions.append(self.brief_description) + if self.detailed_description: + descriptions.append(self.detailed_description) + return '\n\n'.join(descriptions) + brief_description = property(lambda self: self.data()['brief_description']) detailed_description = property(lambda self: self.data()['detailed_description']) - declname = property(lambda self: self.data()['declname']) + name = property(lambda self: self.data()['declname']) + +class DoxyParameterItem(DoxyMember): + """A different representation of a parameter in Doxygen.""" + + def _parse(self): + if self._parsed: + return + super(DoxyParameterItem, self)._parse() + names = [] + for nl in self._parse_data.parameternamelist: + for pn in nl.parametername: + names.append(description(pn)) + # Just take first name + self._data['name'] = names[0] + # Get description + pd = description(self._parse_data.get_parameterdescription()) + self._data['description'] = pd + + description = property(lambda self: self.data()['description']) + name = property(lambda self: self.data()['name']) + class DoxyClass(DoxyCompound): @@ -136,12 +172,14 @@ def _parse(self): if self._error: return self.set_descriptions(self._retrieved_data.compounddef) + self.set_parameters(self._retrieved_data.compounddef) # Sectiondef.kind tells about whether private or public. # We just ignore this for now. self.process_memberdefs() brief_description = property(lambda self: self.data()['brief_description']) detailed_description = property(lambda self: self.data()['detailed_description']) + params = property(lambda self: self.data()['params']) Base.mem_classes.append(DoxyClass) @@ -174,6 +212,16 @@ class DoxyNamespace(DoxyCompound): kind = 'namespace' + def _parse(self): + if self._parsed: + return + super(DoxyNamespace, self)._parse() + self.retrieve_data() + self.set_descriptions(self._retrieved_data.compounddef) + if self._error: + return + self.process_memberdefs() + Base.mem_classes.append(DoxyNamespace) @@ -224,11 +272,11 @@ class DoxyOther(Base): __module__ = "gnuradio.utils.doxyxml" - kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 'dir', 'page']) + kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', + 'dir', 'page', 'signal', 'slot', 'property']) @classmethod def can_parse(cls, obj): return obj.kind in cls.kinds Base.mem_classes.append(DoxyOther) - diff --git a/docs/doxygen/doxyxml/generated/compound.py b/docs/doxygen/doxyxml/generated/compound.py index 1522ac2..d0b164e 100644 --- a/docs/doxygen/doxyxml/generated/compound.py +++ b/docs/doxygen/doxyxml/generated/compound.py @@ -4,14 +4,14 @@ Generated Mon Feb 9 19:08:05 2009 by generateDS.py. """ -from string import lower as str_lower + from xml.dom import minidom from xml.dom import Node import sys -import compoundsuper as supermod -from compoundsuper import MixedContainer +from . import compoundsuper as supermod +from .compoundsuper import MixedContainer class DoxygenTypeSub(supermod.DoxygenType): diff --git a/docs/doxygen/doxyxml/generated/compoundsuper.py b/docs/doxygen/doxyxml/generated/compoundsuper.py index 6255dda..05c4928 100644 --- a/docs/doxygen/doxyxml/generated/compoundsuper.py +++ b/docs/doxygen/doxyxml/generated/compoundsuper.py @@ -4,9 +4,9 @@ # Generated Thu Jun 11 18:44:25 2009 by generateDS.py. # + import sys -import getopt -from string import lower as str_lower + from xml.dom import minidom from xml.dom import Node @@ -19,9 +19,9 @@ try: from generatedssuper import GeneratedsSuper -except ImportError, exp: +except ImportError as exp: - class GeneratedsSuper: + class GeneratedsSuper(object): def format_string(self, input_data, input_name=''): return input_data def format_integer(self, input_data, input_name=''): @@ -64,7 +64,7 @@ def showIndent(outfile, level): outfile.write(' ') def quote_xml(inStr): - s1 = (isinstance(inStr, basestring) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -72,7 +72,7 @@ def quote_xml(inStr): return s1 def quote_attrib(inStr): - s1 = (isinstance(inStr, basestring) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -102,7 +102,7 @@ def quote_python(inStr): return '"""%s"""' % s1 -class MixedContainer: +class MixedContainer(object): # Constants for category: CategoryNone = 0 CategoryText = 1 @@ -4221,7 +4221,7 @@ def buildAttributes(self, attrs): if attrs.get('lineno'): try: self.lineno = int(attrs.get('lineno').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (lineno): %s' % exp) if attrs.get('refkind'): self.refkind = attrs.get('refkind').value @@ -4504,12 +4504,12 @@ def buildAttributes(self, attrs): if attrs.get('endline'): try: self.endline = int(attrs.get('endline').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (endline): %s' % exp) if attrs.get('startline'): try: self.startline = int(attrs.get('startline').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (startline): %s' % exp) if attrs.get('refid'): self.refid = attrs.get('refid').value @@ -4627,17 +4627,17 @@ def buildAttributes(self, attrs): if attrs.get('bodystart'): try: self.bodystart = int(attrs.get('bodystart').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (bodystart): %s' % exp) if attrs.get('line'): try: self.line = int(attrs.get('line').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (line): %s' % exp) if attrs.get('bodyend'): try: self.bodyend = int(attrs.get('bodyend').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (bodyend): %s' % exp) if attrs.get('bodyfile'): self.bodyfile = attrs.get('bodyfile').value @@ -6778,12 +6778,12 @@ def buildAttributes(self, attrs): if attrs.get('rows'): try: self.rows = int(attrs.get('rows').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (rows): %s' % exp) if attrs.get('cols'): try: self.cols = int(attrs.get('cols').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (cols): %s' % exp) def buildChildren(self, child_, nodeName_): if child_.nodeType == Node.ELEMENT_NODE and \ @@ -7108,7 +7108,7 @@ def buildAttributes(self, attrs): if attrs.get('level'): try: self.level = int(attrs.get('level').value) - except ValueError, exp: + except ValueError as exp: raise ValueError('Bad integer attribute (level): %s' % exp) def buildChildren(self, child_, nodeName_): if child_.nodeType == Node.TEXT_NODE: @@ -8283,7 +8283,7 @@ def buildChildren(self, child_, nodeName_): """ def usage(): - print USAGE_TEXT + print(USAGE_TEXT) sys.exit(1) @@ -8339,4 +8339,3 @@ def main(): main() #import pdb #pdb.run('main()') - diff --git a/docs/doxygen/doxyxml/generated/index.py b/docs/doxygen/doxyxml/generated/index.py index 7a70e14..c58407d 100644 --- a/docs/doxygen/doxyxml/generated/index.py +++ b/docs/doxygen/doxyxml/generated/index.py @@ -8,9 +8,9 @@ import os import sys -import compound +from . import compound -import indexsuper as supermod +from . import indexsuper as supermod class DoxygenTypeSub(supermod.DoxygenType): def __init__(self, version=None, compound=None): diff --git a/docs/doxygen/doxyxml/generated/indexsuper.py b/docs/doxygen/doxyxml/generated/indexsuper.py index a991530..cc2c112 100644 --- a/docs/doxygen/doxyxml/generated/indexsuper.py +++ b/docs/doxygen/doxyxml/generated/indexsuper.py @@ -4,9 +4,9 @@ # Generated Thu Jun 11 18:43:54 2009 by generateDS.py. # + import sys -import getopt -from string import lower as str_lower + from xml.dom import minidom from xml.dom import Node @@ -19,9 +19,9 @@ try: from generatedssuper import GeneratedsSuper -except ImportError, exp: +except ImportError as exp: - class GeneratedsSuper: + class GeneratedsSuper(object): def format_string(self, input_data, input_name=''): return input_data def format_integer(self, input_data, input_name=''): @@ -64,7 +64,7 @@ def showIndent(outfile, level): outfile.write(' ') def quote_xml(inStr): - s1 = (isinstance(inStr, basestring) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -72,7 +72,7 @@ def quote_xml(inStr): return s1 def quote_attrib(inStr): - s1 = (isinstance(inStr, basestring) and inStr or + s1 = (isinstance(inStr, str) and inStr or '%s' % inStr) s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') @@ -102,7 +102,7 @@ def quote_python(inStr): return '"""%s"""' % s1 -class MixedContainer: +class MixedContainer(object): # Constants for category: CategoryNone = 0 CategoryText = 1 @@ -462,7 +462,7 @@ def buildChildren(self, child_, nodeName_): """ def usage(): - print USAGE_TEXT + print(USAGE_TEXT) sys.exit(1) @@ -520,4 +520,3 @@ def main(): main() #import pdb #pdb.run('main()') - diff --git a/docs/doxygen/doxyxml/text.py b/docs/doxygen/doxyxml/text.py index 4a79d0a..5dff37c 100644 --- a/docs/doxygen/doxyxml/text.py +++ b/docs/doxygen/doxyxml/text.py @@ -1,20 +1,12 @@ -''' - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -''' - +# +# Copyright 2010 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# """ Utilities for extracting text from generated classes. """ @@ -23,7 +15,7 @@ def is_string(txt): if isinstance(txt, str): return True try: - if isinstance(txt, unicode): + if isinstance(txt, str): return True except NameError: pass @@ -46,7 +38,7 @@ def description_bit(obj): elif is_string(obj): return obj else: - raise StandardError('Expecting a string or something with content, content_ or value attribute') + raise Exception('Expecting a string or something with content, content_ or value attribute') # If this bit is a paragraph then add one some line breaks. if hasattr(obj, 'name') and obj.name == 'para': result += "\n\n" diff --git a/docs/doxygen/pydoc_macros.h b/docs/doxygen/pydoc_macros.h new file mode 100644 index 0000000..98bf7cd --- /dev/null +++ b/docs/doxygen/pydoc_macros.h @@ -0,0 +1,19 @@ +#ifndef PYDOC_MACROS_H +#define PYDOC_MACROS_H + +#define __EXPAND(x) x +#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT +#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) +#define __CAT1(a, b) a##b +#define __CAT2(a, b) __CAT1(a, b) +#define __DOC1(n1) __doc_##n1 +#define __DOC2(n1, n2) __doc_##n1##_##n2 +#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3 +#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4 +#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5 +#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6 +#define __DOC7(n1, n2, n3, n4, n5, n6, n7) \ + __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7 +#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) + +#endif // PYDOC_MACROS_H \ No newline at end of file diff --git a/docs/doxygen/swig_doc.py b/docs/doxygen/swig_doc.py index 0d4af35..e6b74a7 100644 --- a/docs/doxygen/swig_doc.py +++ b/docs/doxygen/swig_doc.py @@ -1,20 +1,24 @@ -''' - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -''' - +# +# Copyright 2010-2012 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# """ Creates the swig_doc.i SWIG interface file. Execute using: python swig_doc.py xml_path outputfilename @@ -23,14 +27,12 @@ python docstrings. """ +from __future__ import unicode_literals -import sys - -try: - from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base -except ImportError: - from gnuradio.doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base +import sys, time +from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile +from doxyxml import DoxyOther, base def py_name(name): bits = name.split('_') @@ -53,18 +55,41 @@ def includes(cls, item): # Check for a parsing error. if item.error(): return False - return item.has_member(make_name(item.name()), DoxyFriend) + friendname = make_name(item.name()) + is_a_block = item.has_member(friendname, DoxyFriend) + # But now sometimes the make function isn't a friend so check again. + if not is_a_block: + is_a_block = di.has_member(friendname, DoxyFunction) + return is_a_block + +class Block2(object): + """ + Checks if doxyxml produced objects correspond to a new style + gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther) + return is_a_block2 def utoascii(text): """ - Convert unicode text into ascii and escape quotes. + Convert unicode text into ascii and escape quotes and backslashes. """ if text is None: return '' out = text.encode('ascii', 'replace') - out = out.replace('"', '\\"') - return out + # swig will require us to replace blackslash with 4 backslashes + out = out.replace(b'\\', b'\\\\\\\\') + out = out.replace(b'"', b'\\"').decode('ascii') + return str(out) def combine_descriptions(obj): @@ -80,9 +105,15 @@ def combine_descriptions(obj): description.append(dd) return utoascii('\n\n'.join(description)).strip() +def format_params(parameteritems): + output = ['Args:'] + template = ' {0} : {1}' + for pi in parameteritems: + output.append(template.format(pi.name, pi.description)) + return '\n'.join(output) entry_templ = '%feature("docstring") {name} "{docstring}"' -def make_entry(obj, name=None, templ="{description}", description=None): +def make_entry(obj, name=None, templ="{description}", description=None, params=[]): """ Create a docstring entry for a swig interface file. @@ -99,6 +130,9 @@ def make_entry(obj, name=None, templ="{description}", description=None): return '' if description is None: description = combine_descriptions(obj) + if params: + description += '\n\n' + description += utoascii(format_params(params)) docstring = templ.format(description=description) if not docstring: return '' @@ -118,27 +152,31 @@ def make_func_entry(func, name=None, description=None, params=None): used as the description instead of extracting it from func. params - a parameter list that overrides using func.params. """ - if params is None: - params = func.params - params = [prm.declname for prm in params] - if params: - sig = "Params: (%s)" % ", ".join(params) - else: - sig = "Params: (NONE)" - templ = "{description}\n\n" + sig - return make_entry(func, name=name, templ=utoascii(templ), - description=description) - - -def make_class_entry(klass, description=None): + #if params is None: + # params = func.params + #params = [prm.declname for prm in params] + #if params: + # sig = "Params: (%s)" % ", ".join(params) + #else: + # sig = "Params: (NONE)" + #templ = "{description}\n\n" + sig + #return make_entry(func, name=name, templ=utoascii(templ), + # description=description) + return make_entry(func, name=name, description=description, params=params) + + +def make_class_entry(klass, description=None, ignored_methods=[], params=None): """ Create a class docstring for a swig interface file. """ + if params is None: + params = klass.params output = [] - output.append(make_entry(klass, description=description)) + output.append(make_entry(klass, description=description, params=params)) for func in klass.in_category(DoxyFunction): - name = klass.name() + '::' + func.name() - output.append(make_func_entry(func, name=name)) + if func.name() not in ignored_methods: + name = klass.name() + '::' + func.name() + output.append(make_func_entry(func, name=name)) return "\n\n".join(output) @@ -172,11 +210,33 @@ def make_block_entry(di, block): # the make function. output = [] output.append(make_class_entry(block, description=super_description)) - creator = block.get_member(block.name(), DoxyFunction) output.append(make_func_entry(make_func, description=super_description, - params=creator.params)) + params=block.params)) return "\n\n".join(output) +def make_block2_entry(di, block): + """ + Create class and function docstrings of a new style gnuradio block for a + swig interface file. + """ + descriptions = [] + # For new style blocks all the relevant documentation should be + # associated with the 'make' method. + class_description = combine_descriptions(block) + make_func = block.get_member('make', DoxyFunction) + make_description = combine_descriptions(make_func) + description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description + # Associate the combined description with the class and + # the make function. + output = [] + output.append(make_class_entry( + block, description=description, + ignored_methods=['make'], params=make_func.params)) + makename = block.name() + '::make' + output.append(make_func_entry( + make_func, name=makename, description=description, + params=make_func.params)) + return "\n\n".join(output) def make_swig_interface_file(di, swigdocfilename, custom_output=None): @@ -193,39 +253,59 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None): # Create docstrings for the blocks. blocks = di.in_category(Block) + blocks2 = di.in_category(Block2) + make_funcs = set([]) for block in blocks: try: make_func = di.get_member(make_name(block.name()), DoxyFunction) - make_funcs.add(make_func.name()) - output.append(make_block_entry(di, block)) + # Don't want to risk writing to output twice. + if make_func.name() not in make_funcs: + make_funcs.add(make_func.name()) + output.append(make_block_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + for block in blocks2: + try: + make_func = block.get_member('make', DoxyFunction) + make_func_name = block.name() +'::make' + # Don't want to risk writing to output twice. + if make_func_name not in make_funcs: + make_funcs.add(make_func_name) + output.append(make_block2_entry(di, block)) except block.ParsingError: - print('Parsing error for block %s' % block.name()) + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise # Create docstrings for functions # Don't include the make functions since they have already been dealt with. - funcs = [f for f in di.in_category(DoxyFunction) if f.name() not in make_funcs] + funcs = [f for f in di.in_category(DoxyFunction) + if f.name() not in make_funcs and not f.name().startswith('std::')] for f in funcs: try: output.append(make_func_entry(f)) except f.ParsingError: - print('Parsing error for function %s' % f.name()) + sys.stderr.write('Parsing error for function {0}\n'.format(f.name())) # Create docstrings for classes block_names = [block.name() for block in blocks] - klasses = [k for k in di.in_category(DoxyClass) if k.name() not in block_names] + block_names += [block.name() for block in blocks2] + klasses = [k for k in di.in_category(DoxyClass) + if k.name() not in block_names and not k.name().startswith('std::')] for k in klasses: try: output.append(make_class_entry(k)) except k.ParsingError: - print('Parsing error for class %s' % k.name()) + sys.stderr.write('Parsing error for class {0}\n'.format(k.name())) # Docstrings are not created for anything that is not a function or a class. # If this excludes anything important please add it here. output = "\n\n".join(output) - swig_doc = file(swigdocfilename, 'w') + swig_doc = open(swigdocfilename, 'w') swig_doc.write(output) swig_doc.close() @@ -233,7 +313,7 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None): # Parse command line options and set up doxyxml. err_msg = "Execute using: python swig_doc.py xml_path outputfilename" if len(sys.argv) != 3: - raise StandardError(err_msg) + raise Exception(err_msg) xml_path = sys.argv[1] swigdocfilename = sys.argv[2] di = DoxyIndex(xml_path) diff --git a/docs/doxygen/update_pydoc.py b/docs/doxygen/update_pydoc.py new file mode 100644 index 0000000..ccf982a --- /dev/null +++ b/docs/doxygen/update_pydoc.py @@ -0,0 +1,342 @@ +# +# Copyright 2010-2012 Free Software Foundation, Inc. +# +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gnuradio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +""" +Updates the *pydoc_h files for a module +Execute using: python update_pydoc.py xml_path outputfilename + +The file instructs Pybind11 to transfer the doxygen comments into the +python docstrings. + +""" + +import os, sys, time, glob, re, json +from argparse import ArgumentParser + +from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile +from doxyxml import DoxyOther, base + +def py_name(name): + bits = name.split('_') + return '_'.join(bits[1:]) + +def make_name(name): + bits = name.split('_') + return bits[0] + '_make_' + '_'.join(bits[1:]) + + +class Block(object): + """ + Checks if doxyxml produced objects correspond to a gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + friendname = make_name(item.name()) + is_a_block = item.has_member(friendname, DoxyFriend) + # But now sometimes the make function isn't a friend so check again. + if not is_a_block: + is_a_block = di.has_member(friendname, DoxyFunction) + return is_a_block + +class Block2(object): + """ + Checks if doxyxml produced objects correspond to a new style + gnuradio block. + """ + + @classmethod + def includes(cls, item): + if not isinstance(item, DoxyClass): + return False + # Check for a parsing error. + if item.error(): + return False + is_a_block2 = item.has_member('make', DoxyFunction) and item.has_member('sptr', DoxyOther) + return is_a_block2 + + +def utoascii(text): + """ + Convert unicode text into ascii and escape quotes and backslashes. + """ + if text is None: + return '' + out = text.encode('ascii', 'replace') + # swig will require us to replace blackslash with 4 backslashes + # TODO: evaluate what this should be for pybind11 + out = out.replace(b'\\', b'\\\\\\\\') + out = out.replace(b'"', b'\\"').decode('ascii') + return str(out) + + +def combine_descriptions(obj): + """ + Combines the brief and detailed descriptions of an object together. + """ + description = [] + bd = obj.brief_description.strip() + dd = obj.detailed_description.strip() + if bd: + description.append(bd) + if dd: + description.append(dd) + return utoascii('\n\n'.join(description)).strip() + +def format_params(parameteritems): + output = ['Args:'] + template = ' {0} : {1}' + for pi in parameteritems: + output.append(template.format(pi.name, pi.description)) + return '\n'.join(output) + +entry_templ = '%feature("docstring") {name} "{docstring}"' +def make_entry(obj, name=None, templ="{description}", description=None, params=[]): + """ + Create a docstring key/value pair, where the key is the object name. + + obj - a doxyxml object from which documentation will be extracted. + name - the name of the C object (defaults to obj.name()) + templ - an optional template for the docstring containing only one + variable named 'description'. + description - if this optional variable is set then it's value is + used as the description instead of extracting it from obj. + """ + if name is None: + name=obj.name() + if hasattr(obj,'_parse_data') and hasattr(obj._parse_data,'definition'): + name=obj._parse_data.definition.split(' ')[-1] + if "operator " in name: + return '' + if description is None: + description = combine_descriptions(obj) + if params: + description += '\n\n' + description += utoascii(format_params(params)) + docstring = templ.format(description=description) + + return {name: docstring} + + +def make_class_entry(klass, description=None, ignored_methods=[], params=None): + """ + Create a class docstring key/value pair. + """ + if params is None: + params = klass.params + output = {} + output.update(make_entry(klass, description=description, params=params)) + for func in klass.in_category(DoxyFunction): + if func.name() not in ignored_methods: + name = klass.name() + '::' + func.name() + output.update(make_entry(func, name=name)) + return output + + +def make_block_entry(di, block): + """ + Create class and function docstrings of a gnuradio block + """ + descriptions = [] + # Get the documentation associated with the class. + class_desc = combine_descriptions(block) + if class_desc: + descriptions.append(class_desc) + # Get the documentation associated with the make function + make_func = di.get_member(make_name(block.name()), DoxyFunction) + make_func_desc = combine_descriptions(make_func) + if make_func_desc: + descriptions.append(make_func_desc) + # Get the documentation associated with the file + try: + block_file = di.get_member(block.name() + ".h", DoxyFile) + file_desc = combine_descriptions(block_file) + if file_desc: + descriptions.append(file_desc) + except base.Base.NoSuchMember: + # Don't worry if we can't find a matching file. + pass + # And join them all together to make a super duper description. + super_description = "\n\n".join(descriptions) + # Associate the combined description with the class and + # the make function. + output = {} + output.update(make_class_entry(block, description=super_description)) + output.update(make_entry(make_func, description=super_description, + params=block.params)) + return output + +def make_block2_entry(di, block): + """ + Create class and function docstrings of a new style gnuradio block + """ + # For new style blocks all the relevant documentation should be + # associated with the 'make' method. + class_description = combine_descriptions(block) + make_func = block.get_member('make', DoxyFunction) + make_description = combine_descriptions(make_func) + description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description + # Associate the combined description with the class and + # the make function. + output = {} + output.update(make_class_entry( + block, description=description, + ignored_methods=['make'], params=make_func.params)) + makename = block.name() + '::make' + output.update(make_entry( + make_func, name=makename, description=description, + params=make_func.params)) + return output + +def get_docstrings_dict(di, custom_output=None): + + output = {} + if custom_output: + output.update(custom_output) + + # Create docstrings for the blocks. + blocks = di.in_category(Block) + blocks2 = di.in_category(Block2) + + make_funcs = set([]) + for block in blocks: + try: + make_func = di.get_member(make_name(block.name()), DoxyFunction) + # Don't want to risk writing to output twice. + if make_func.name() not in make_funcs: + make_funcs.add(make_func.name()) + output.update(make_block_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + for block in blocks2: + try: + make_func = block.get_member('make', DoxyFunction) + make_func_name = block.name() +'::make' + # Don't want to risk writing to output twice. + if make_func_name not in make_funcs: + make_funcs.add(make_func_name) + output.update(make_block2_entry(di, block)) + except block.ParsingError: + sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) + raise + + # Create docstrings for functions + # Don't include the make functions since they have already been dealt with. + funcs = [f for f in di.in_category(DoxyFunction) + if f.name() not in make_funcs and not f.name().startswith('std::')] + for f in funcs: + try: + output.update(make_entry(f)) + except f.ParsingError: + sys.stderr.write('Parsing error for function {0}\n'.format(f.name())) + + # Create docstrings for classes + block_names = [block.name() for block in blocks] + block_names += [block.name() for block in blocks2] + klasses = [k for k in di.in_category(DoxyClass) + if k.name() not in block_names and not k.name().startswith('std::')] + for k in klasses: + try: + output.update(make_class_entry(k)) + except k.ParsingError: + sys.stderr.write('Parsing error for class {0}\n'.format(k.name())) + + # Docstrings are not created for anything that is not a function or a class. + # If this excludes anything important please add it here. + + return output + +def sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, output_dir, filter_str=None): + if filter_str: + docstrings_dict = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str)} + + with open(os.path.join(output_dir,'docstring_status'),'w') as status_file: + + for pydoc_file in pydoc_files: + if filter_str: + filter_str2 = "::".join((filter_str,os.path.split(pydoc_file)[-1].split('_pydoc_template.h')[0])) + docstrings_dict2 = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str2)} + else: + docstrings_dict2 = docstrings_dict + + + + file_in = open(pydoc_file,'r').read() + for key, value in docstrings_dict2.items(): + file_in_tmp = file_in + try: + doc_key = key.split("::") + # if 'gr' in doc_key: + # doc_key.remove('gr') + doc_key = '_'.join(doc_key) + regexp = r'(__doc_{} =\sR\"doc\()[^)]*(\)doc\")'.format(doc_key) + regexp = re.compile(regexp, re.MULTILINE) + + (file_in, nsubs) = regexp.subn(r'\1'+value+r'\2', file_in, count=1) + if nsubs == 1: + status_file.write("PASS: " + pydoc_file + "\n") + except KeyboardInterrupt: + raise KeyboardInterrupt + except: # be permissive, TODO log, but just leave the docstring blank + status_file.write("FAIL: " + pydoc_file + "\n") + file_in = file_in_tmp + + output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h')) + with open(output_pathname,'w') as file_out: + file_out.write(file_in) + +def copy_docstring_templates(pydoc_files, output_dir): + with open(os.path.join(output_dir,'docstring_status'),'w') as status_file: + for pydoc_file in pydoc_files: + file_in = open(pydoc_file,'r').read() + output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h')) + with open(output_pathname,'w') as file_out: + file_out.write(file_in) + status_file.write("DONE") + +def argParse(): + """Parses commandline args.""" + desc='Scrape the doxygen generated xml for docstrings to insert into python bindings' + parser = ArgumentParser(description=desc) + + parser.add_argument("function", help="Operation to perform on docstrings", choices=["scrape","sub","copy"]) + + parser.add_argument("--xml_path") + parser.add_argument("--bindings_dir") + parser.add_argument("--output_dir") + parser.add_argument("--json_path") + parser.add_argument("--filter", default=None) + + return parser.parse_args() + +if __name__ == "__main__": + # Parse command line options and set up doxyxml. + args = argParse() + if args.function.lower() == 'scrape': + di = DoxyIndex(args.xml_path) + docstrings_dict = get_docstrings_dict(di) + with open(args.json_path, 'w') as fp: + json.dump(docstrings_dict, fp) + elif args.function.lower() == 'sub': + with open(args.json_path, 'r') as fp: + docstrings_dict = json.load(fp) + pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h')) + sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, args.output_dir, args.filter) + elif args.function.lower() == 'copy': + pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h')) + copy_docstring_templates(pydoc_files, args.output_dir) + + diff --git a/examples/README b/examples/README new file mode 100644 index 0000000..c012bdf --- /dev/null +++ b/examples/README @@ -0,0 +1,4 @@ +It is considered good practice to add examples in here to demonstrate the +functionality of your OOT module. Python scripts, GRC flow graphs or other +code can go here. + diff --git a/examples/data_tr.bin b/examples/data_tr.bin new file mode 100644 index 0000000..c0579ec Binary files /dev/null and b/examples/data_tr.bin differ diff --git a/examples/microsoft_mouse_sniffer.py b/examples/microsoft_mouse_sniffer.py deleted file mode 100755 index 8b18aca..0000000 --- a/examples/microsoft_mouse_sniffer.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env python2 - -from gnuradio import gr, blocks, digital, filter -from gnuradio.filter import firdes -import thread -import osmosdr -import nordic -import pmt -import struct -import time - - -class top_block(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self, "Microsoft Mouse Sniffer") - - # SDR configuration - self.freq = 2403e6 - self.gain = 70 - self.symbol_rate = 2e6 - self.sample_rate = 4e6 - - # SDR source (gr-osmosdr source) - self.osmosdr_source = osmosdr.source() - self.osmosdr_source.set_sample_rate(self.sample_rate) - self.osmosdr_source.set_center_freq(self.freq) - self.osmosdr_source.set_gain(self.gain) - self.osmosdr_source.set_antenna('TX/RX') - - # Low pass filter - self.lpf = filter.fir_filter_ccf( - 1, firdes.low_pass_2(1, self.sample_rate, self.symbol_rate / 2, 50e3, 50)) - - # GFSK demod, defaults to 2 samples per symbol - self.gfsk_demod = digital.gfsk_demod() - - # Nordic RX - self.nordic_rx = nordic.nordic_rx(3, 5, 2, 2) - - # Connect the blocks - self.connect((self.osmosdr_source, 0), (self.lpf, 0)) - self.connect((self.lpf, 0), (self.gfsk_demod, 0)) - self.connect((self.gfsk_demod, 0), (self.nordic_rx, 0)) - - # Handle incoming packets - self.nordictap_handler = microsoft_nordictap_handler(self) - self.msg_connect( - self.nordic_rx, "nordictap_out", self.nordictap_handler, "nordictap_in") - - # Tune the USRP by nRF24L channel number - def set_channel(self, channel): - - new_channel = 2400e6 + channel * 1e6 - self.osmosdr_source.set_center_freq(2400e6 + channel * 1e6) - self.nordic_rx.set_channel(channel) - - -# Microsoft mouse nordictap handler -class microsoft_nordictap_handler(gr.sync_block): - - def __init__(self, tb): - gr.sync_block.__init__( - self, name="Nordictap Handler", in_sig=None, out_sig=None) - - self.tb = tb - self.message_port_register_in(pmt.intern("nordictap_in")) - self.set_msg_handler( - pmt.intern("nordictap_in"), self.nordictap_handler) - - # Tick / channel hopping state and logic - self.last_rx = time.time() - self.last_tune = time.time() - self.ch_timeout = 0.4 # timeout a channel after 200ms - self.last_ch = 0 - thread.start_new_thread(self.tick, ()) - - # Channels and channel groups - self.channels = [3, 29, 21, 5, 23, 17, 19, 50, 31, 25, - 46, 27, 78, 70, 72, 44, 56, 48, 68, 80, 54, 52, 74, 76] - self.channel_groups = [] - for x in range(6): - chs = [] - for y in range(4): - chs.append(self.channels[y * 6 + x]) - self.channel_groups.append(chs) - - # Discovered device state - self.mouse_address = None - - # 10ms tick - def tick(self): - - while True: - - # Check for a stale channel - if ((time.time() - self.last_rx) > self.ch_timeout * 5) and \ - ((time.time() - self.last_tune) > self.ch_timeout): - - self.last_ch += 1 - if self.last_ch >= len(self.channels): - self.last_ch = 0 - print 'Tuning to 24%02i MHz' % self.channels[self.last_ch] - self.last_tune = time.time() - self.tb.set_channel(self.channels[self.last_ch]) - - # Wait 10ms - time.sleep(0.01) - - def nordictap_handler(self, msg): - - data = pmt.to_python(msg).tostring() - - # Unpack the header - values = struct.unpack('BBBBBBB', data[0:7]) - channel = values[0] - data_rate = values[1] - address_length = values[2] - payload_length = values[3] - sequence_number = values[4] - no_ack = values[5] - crc_length = values[6] - - # Parse the address, payload, and crc - address = data[7:7 + address_length] - payload = data[7 + address_length:7 + address_length + payload_length] - crc = data[7 + address_length + payload_length: - 7 + address_length + payload_length + crc_length] - - # Check for a Microsoft mouse - if self.mouse_address is None: - if ((ord(address[0]) & 0xF0) == 0xA0) and \ - ((ord(address[4]) & 0x0F) == 0x06) and \ - payload_length == 19: - - # Set the mouse address - self.mouse_address = address - - # Set the channel group - for x in range(6): - if channel in self.channel_groups[x]: - self.channels = self.channel_groups[x] - break - - # Camp on the channel and print out the packet if this is our target - # device - if self.mouse_address == address: - - self.last_rx = time.time() - - # Print the channel, sequence number, address and payload - print 'CH=' + str(2400 + channel), - print 'SEQ=' + str(sequence_number), - print 'ADDR=' + ':'.join('%02X' % ord(b) for b in address), - print 'PLD=' + ':'.join('%02X' % ord(b) for b in payload), - print 'CRC=' + ':'.join('%02X' % ord(b) for b in crc) - - -def main(): - tb = top_block() - tb.start() - try: - raw_input('Press Enter to quit: ') - except EOFError: - pass - tb.stop() - tb.wait() - - -if __name__ == '__main__': - main() diff --git a/examples/nordic_auto_ack.py b/examples/nordic_auto_ack.py deleted file mode 100755 index c2b77c6..0000000 --- a/examples/nordic_auto_ack.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python2 - -from gnuradio import gr, blocks, digital, filter -from gnuradio.filter import firdes -import thread -import nordic -import pmt -import struct -import time -import numpy -import array -import osmosdr -import argparse -from bitstring import BitArray -from gnuradio import uhd -from Queue import Queue - - -class top_block(gr.top_block): - - def __init__(self, args): - gr.top_block.__init__(self, "Nordic Auto-ACK Example") - - # SDR configuration - self.freq = 2400e6 + args.channel * 1e6 - self.gain = args.gain - self.symbol_rate = args.data_rate - self.sample_rate = args.data_rate * args.samples_per_symbol - - # SDR source (gr-osmosdr source) - self.osmosdr_source = osmosdr.source() - self.osmosdr_source.set_sample_rate(self.sample_rate) - self.osmosdr_source.set_center_freq(self.freq) - self.osmosdr_source.set_gain(self.gain) - self.osmosdr_source.set_antenna('TX/RX') - - # SDR sink (gr-osmosdr source) - self.osmosdr_sink = osmosdr.sink() - self.osmosdr_sink.set_sample_rate(self.sample_rate) - self.osmosdr_sink.set_center_freq(self.freq) - self.osmosdr_sink.set_gain(self.gain) - self.osmosdr_sink.set_antenna('TX/RX') - - # Transmit chain - self.tx = nordic.nordic_tx() - self.gfsk_mod = digital.gfsk_mod( - samples_per_symbol=args.samples_per_symbol) - self.connect(self.tx, self.gfsk_mod) - self.connect(self.gfsk_mod, self.osmosdr_sink) - - # Receive chain - dr = 0 - if args.data_rate == 1e6: - dr = 1 - elif args.data_rate == 2e6: - dr = 2 - self.rx = nordic.nordic_rx( - args.channel, args.address_length, args.crc_length, dr) - self.gfsk_demod = digital.gfsk_demod( - samples_per_symbol=args.samples_per_symbol) - self.lpf = filter.fir_filter_ccf( - 1, firdes.low_pass_2(1, self.sample_rate, self.symbol_rate / 2, 50e3, 50)) - self.connect(self.osmosdr_source, self.lpf) - self.connect(self.lpf, self.gfsk_demod) - self.connect(self.gfsk_demod, self.rx) - - # Handle incoming packets - self.nordictap_ack_handler = nordictap_ack_handler() - self.msg_connect(self.rx, "nordictap_out", - self.nordictap_ack_handler, "nordictap_in") - - # Reply with ACKs - self.msg_connect(self.nordictap_ack_handler, - "nordictap_out", self.tx, "nordictap_in") - - -# Nordic Auto-ACK handler -class nordictap_ack_handler(gr.sync_block): - - # Constructor - - def __init__(self): - gr.sync_block.__init__( - self, name="Nordictap Handler", in_sig=None, out_sig=None) - - # Received packet input port - self.message_port_register_in(pmt.intern("nordictap_in")) - self.set_msg_handler( - pmt.intern("nordictap_in"), self.nordictap_handler) - - # ACK output port - self.message_port_register_out(pmt.intern("nordictap_out")) - - # Handle incoming packets, and reply with ACKs - def nordictap_handler(self, msg): - - # PMT to byte string - data = pmt.to_python(msg).tostring() - - # Unpack the header - values = struct.unpack('BBBBBBBB', data[0:8]) - channel = values[0] - data_rate = values[1] - address_length = values[2] - payload_length = values[3] - sequence_number = values[4] - no_ack = values[5] - crc_length = values[6] - - # Parse the address, payload, and crc - address = data[7:7 + address_length] - payload = data[7 + address_length:7 + address_length + payload_length] - crc = data[7 + address_length + payload_length: - 7 + address_length + payload_length + crc_length] - - # ACK if needed - if payload_length > 0 and no_ack == 0: - - # Print the channel, sequence number, address and payload - print "ACK'd Packet: ", - print 'CH=' + str(2400 + channel), - print 'SEQ=' + str(sequence_number), - print 'ADDR=' + ':'.join('%02X' % ord(b) for b in address), - print 'PLD=' + ':'.join('%02X' % ord(b) for b in payload), - print 'CRC=' + ':'.join('%02X' % ord(b) for b in crc) - - # Build an ACK - nordictap = [0] + [4, 2, 5, 0, sequence_number, 0, 2] - for c in address: - nordictap.append(ord(c)) - - # Transmit an ACK - vec = pmt.make_u8vector(len(nordictap), 0) - for x in range(len(nordictap)): - pmt.u8vector_set(vec, x, nordictap[x]) - self.message_port_pub(pmt.intern("nordictap_out"), vec) - - -def main(): - - # Parse command line arguments - parser = argparse.ArgumentParser('Nordic Auto-ACK Example', - formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=50, width=120)) - parser.add_argument( - '-c', '--channel', type=int, help='RF channel (0-125)', default=4) - parser.add_argument('-r', '--data_rate', type=float, - help='Data Rate (250e3, 1e6 or 2e6', default=2e6, choices=[250e3, 1e6, 2e6]) - parser.add_argument('-l', '--crc_length', type=int, - help='CRC Length (1-2)', default=2, choices=[1, 2]) - parser.add_argument('-a', '--address_length', type=int, - help='Address Length (3-5)', default=5, choices=[3, 4, 5]) - parser.add_argument('-s', '--samples_per_symbol', - type=int, help='Samples Per Symbol', default=2) - parser.add_argument( - '-g', '--gain', type=float, help='Radio Gain', default=80) - - args = parser.parse_args() - - tb = top_block(args) - tb.start() - try: - raw_input('Press Enter to quit: ') - except EOFError: - pass - tb.stop() - tb.wait() - - -if __name__ == '__main__': - main() diff --git a/examples/nordic_channelized_receiver.py b/examples/nordic_channelized_receiver.py deleted file mode 100755 index af9179d..0000000 --- a/examples/nordic_channelized_receiver.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python2 - -from gnuradio import gr, blocks, digital, filter -from gnuradio.filter import firdes -import thread -import nordic -import pmt -import struct -import time -import numpy -import array -import osmosdr -import argparse -from bitstring import BitArray -from gnuradio import uhd -from Queue import Queue - - -class top_block(gr.top_block): - - def __init__(self, args): - gr.top_block.__init__(self, "Nordic Single-Channel Receiver Example") - - self.freq = 2414e6 - self.gain = args.gain - self.symbol_rate = 2e6 - self.sample_rate = 4e6 - - # Channel map - channel_count = 3 - channel_map = [14, 18, 10] - - # Data rate index - dr = 2 # 2M - - # SDR source (gr-osmosdr source) - self.osmosdr_source = osmosdr.source() - self.osmosdr_source.set_sample_rate(self.sample_rate * channel_count) - self.osmosdr_source.set_center_freq(self.freq) - self.osmosdr_source.set_gain(self.gain) - self.osmosdr_source.set_antenna('TX/RX') - - # PFB channelizer - taps = firdes.low_pass_2( - 1, self.sample_rate, self.symbol_rate / 2, 100e3, 30) - self.channelizer = filter.pfb_channelizer_ccf(channel_count, taps, 1) - - # Stream to streams (PFB channelizer input) - self.s2ss = blocks.stream_to_streams( - gr.sizeof_gr_complex, channel_count) - self.connect(self.osmosdr_source, self.s2ss) - - # Demodulators and packet deframers - self.nordictap_printer = nordictap_printer() - self.demods = [] - self.rxs = [] - for x in range(channel_count): - self.connect((self.s2ss, x), (self.channelizer, x)) - self.demods.append(digital.gfsk_demod()) - self.rxs.append(nordic.nordic_rx(x, 5, 2, dr)) - self.connect((self.channelizer, x), self.demods[x]) - self.connect(self.demods[x], self.rxs[x]) - self.msg_connect( - self.rxs[x], "nordictap_out", self.nordictap_printer, "nordictap_in") - - -# Nordic Printer -class nordictap_printer(gr.sync_block): - - # Constructor - - def __init__(self): - gr.sync_block.__init__( - self, name="Nordictap Printer", in_sig=None, out_sig=None) - - # Received packet input port - self.message_port_register_in(pmt.intern("nordictap_in")) - self.set_msg_handler( - pmt.intern("nordictap_in"), self.nordictap_handler) - - # Handle incoming packets, and print payloads - def nordictap_handler(self, msg): - - # PMT to byte string - data = pmt.to_python(msg).tostring() - - # Unpack the header - values = struct.unpack('BBBBBBBB', data[0:8]) - channel = values[0] - data_rate = values[1] - address_length = values[2] - payload_length = values[3] - sequence_number = values[4] - no_ack = values[5] - crc_length = values[6] - - # Parse the address, payload, and crc - address = data[7:7 + address_length] - payload = data[7 + address_length:7 + address_length + payload_length] - crc = data[7 + address_length + payload_length: - 7 + address_length + payload_length + crc_length] - - # Print the channel, sequence number, address and payload - print 'CH=' + str(2400 + channel), - print 'SEQ=' + str(sequence_number), - print 'ADDR=' + ':'.join('%02X' % ord(b) for b in address), - print 'PLD=' + ':'.join('%02X' % ord(b) for b in payload), - print 'CRC=' + ':'.join('%02X' % ord(b) for b in crc) - - -def main(): - - # Parse command line arguments - parser = argparse.ArgumentParser('Nordic Channelized Receiver Example', - formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=50, width=120)) - parser.add_argument( - '-g', '--gain', type=float, help='Radio Gain', default=30) - - args = parser.parse_args() - - tb = top_block(args) - tb.start() - try: - raw_input('Press Enter to quit: ') - except EOFError: - pass - tb.stop() - tb.wait() - - -if __name__ == '__main__': - main() diff --git a/examples/nordic_channelized_transmitter.py b/examples/nordic_channelized_transmitter.py deleted file mode 100755 index bdf5462..0000000 --- a/examples/nordic_channelized_transmitter.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env python2 - -from gnuradio import gr, blocks, digital, filter -from gnuradio.filter import firdes -import thread -import nordic -import pmt -import struct -import time -import numpy -import array -import random -import osmosdr -import argparse -from bitstring import BitArray -from gnuradio import uhd -from Queue import Queue - - -class top_block(gr.top_block): - - def __init__(self, args): - gr.top_block.__init__(self, "Nordic Single-Channel Receiver Example") - - self.freq = 2414e6 - self.gain = args.gain - self.symbol_rate = 2e6 - self.sample_rate = 4e6 - - # Channel map - channel_count = 3 - channel_map = [14, 18, 10] - - # Data rate index - dr = 2 # 2M - - # SDR sink (gr-osmosdr sink) - self.osmosdr_sink = osmosdr.sink() - self.osmosdr_sink.set_sample_rate(self.sample_rate * channel_count) - self.osmosdr_sink.set_center_freq(self.freq) - self.osmosdr_sink.set_gain(self.gain) - self.osmosdr_sink.set_antenna('TX/RX') - - # PFB channelizer - taps = firdes.low_pass_2( - 1, self.sample_rate, self.symbol_rate / 2, 100e3, 30) - self.synthesizer = filter.pfb_synthesizer_ccf(channel_count, taps) - - # Modulators and packet framers - self.nordictap_transmitter = nordictap_transmitter(channel_map) - self.mods = [] - self.tx = nordic.nordic_tx(channel_count) - for x in range(channel_count): - self.mods.append(digital.gfsk_mod()) - self.connect((self.tx, x), self.mods[x]) - self.connect(self.mods[x], (self.synthesizer, x)) - self.connect(self.synthesizer, self.osmosdr_sink) - - # Wire up output packet connection - self.msg_connect(self.nordictap_transmitter, - "nordictap_out", self.tx, "nordictap_in") - - -# Nordic transmitter strobe -class nordictap_transmitter(gr.sync_block): - - # Constructor - - def __init__(self, channel_map): - gr.sync_block.__init__( - self, name="Nordictap Printer/Transmitter", in_sig=None, out_sig=None) - - self.channel_map = channel_map - - # Packet output port - self.message_port_register_out(pmt.intern("nordictap_out")) - - # Transmit a packet - def transmit(self, address, payload, channel_index, sequence_number): - - channel = self.channel_map[channel_index] - - # Build a payload - nordictap = [channel_index] + [ - channel, 2, len(address), len(payload), sequence_number, 0, 2] - for c in address: - nordictap.append(ord(c)) - for c in payload: - nordictap.append(ord(c)) - - # Transmit packet - vec = pmt.make_u8vector(len(nordictap), 0) - for x in range(len(nordictap)): - pmt.u8vector_set(vec, x, nordictap[x]) - self.message_port_pub(pmt.intern("nordictap_out"), vec) - - -def main(): - - # Parse command line arguments - parser = argparse.ArgumentParser('Nordic Channelized Transmitter Example', - formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=50, width=120)) - parser.add_argument( - '-g', '--gain', type=float, help='Radio Gain', default=30) - - args = parser.parse_args() - - tb = top_block(args) - tb.start() - - # Transmit some packets, hopping between three channels - address = '\x11\x22\x11\x22\x11' - payload = '\x55\x44\x33\x22\x11' - sequence_number = 0 - while True: - for x in range(3): - tb.nordictap_transmitter.transmit( - address, payload, x, sequence_number) - sequence_number += 1 - if sequence_number > 3: - sequence_number = 0 - time.sleep(0.1) - - try: - raw_input('Press Enter to quit: ') - except EOFError: - pass - tb.stop() - tb.wait() - - -if __name__ == '__main__': - main() diff --git a/examples/nordic_receiver.py b/examples/nordic_receiver.py deleted file mode 100755 index e362e78..0000000 --- a/examples/nordic_receiver.py +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env python2 - -from gnuradio import gr, blocks, digital, filter -from gnuradio.filter import firdes -import thread -import nordic -import pmt -import struct -import time -import numpy -import array -import osmosdr -import argparse -from bitstring import BitArray -from gnuradio import uhd -from Queue import Queue - - -class top_block(gr.top_block): - - def __init__(self, args): - gr.top_block.__init__(self, "Nordic Single-Channel Receiver Example") - - # SDR configuration - self.freq = 2400e6 + args.channel * 1e6 - self.gain = args.gain - self.symbol_rate = args.data_rate - self.sample_rate = args.data_rate * args.samples_per_symbol - - # SDR source (gr-osmosdr source)_tx_queue.push(msg); - self.osmosdr_source = osmosdr.source() - self.osmosdr_source.set_sample_rate(self.sample_rate) - self.osmosdr_source.set_center_freq(self.freq) - self.osmosdr_source.set_gain(self.gain) - self.osmosdr_source.set_antenna('TX/RX') - - # Receive chain - dr = 0 - if args.data_rate == 1e6: - dr = 1 - elif args.data_rate == 2e6: - dr = 2 - self.rx = nordic.nordic_rx( - args.channel, args.address_length, args.crc_length, dr) - self.gfsk_demod = digital.gfsk_demod( - samples_per_symbol=args.samples_per_symbol) - self.lpf = filter.fir_filter_ccf( - 1, firdes.low_pass_2(1, self.sample_rate, self.symbol_rate / 2, 50e3, 50)) - self.connect(self.osmosdr_source, self.lpf) - self.connect(self.lpf, self.gfsk_demod) - self.connect(self.gfsk_demod, self.rx) - - # Handle incoming packets - self.nordictap_printer = nordictap_printer() - self.msg_connect( - self.rx, "nordictap_out", self.nordictap_printer, "nordictap_in") - - -# Nordic Printer -class nordictap_printer(gr.sync_block): - - # Constructor - - def __init__(self): - gr.sync_block.__init__( - self, name="Nordictap Handler", in_sig=None, out_sig=None) - - # Received packet input port - self.message_port_register_in(pmt.intern("nordictap_in")) - self.set_msg_handler( - pmt.intern("nordictap_in"), self.nordictap_handler) - - # Handle incoming packets, and print payloads - def nordictap_handler(self, msg): - - # PMT to byte string - data = pmt.to_python(msg).tostring() - - # Unpack the header - values = struct.unpack('BBBBBBBB', data[0:8]) - channel = values[0] - data_rate = values[1] - address_length = values[2] - payload_length = values[3] - sequence_number = values[4] - no_ack = values[5] - crc_length = values[6] - - # Parse the address, payload, and crc - address = data[7:7 + address_length] - payload = data[7 + address_length:7 + address_length + payload_length] - crc = data[7 + address_length + payload_length: - 7 + address_length + payload_length + crc_length] - - # Print the channel, sequence number, address and payload - print 'CH=' + str(2400 + channel), - print 'SEQ=' + str(sequence_number), - print 'ADDR=' + ':'.join('%02X' % ord(b) for b in address), - print 'PLD=' + ':'.join('%02X' % ord(b) for b in payload), - print 'CRC=' + ':'.join('%02X' % ord(b) for b in crc) - - -def main(): - - # Parse command line arguments - parser = argparse.ArgumentParser('Nordic Single-Channel Receiver Example', - formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=50, width=120)) - parser.add_argument( - '-c', '--channel', type=int, help='RF channel (0-125)', default=4) - parser.add_argument('-r', '--data_rate', type=float, - help='Data Rate (250e3, 1e6 or 2e6', default=2e6, choices=[250e3, 1e6, 2e6]) - parser.add_argument('-l', '--crc_length', type=int, - help='CRC Length (1-2)', default=2, choices=[1, 2]) - parser.add_argument('-a', '--address_length', type=int, - help='Address Length (3-5)', default=5, choices=[3, 4, 5]) - parser.add_argument('-s', '--samples_per_symbol', - type=int, help='Samples Per Symbol', default=2) - parser.add_argument( - '-g', '--gain', type=float, help='Radio Gain', default=80) - - args = parser.parse_args() - - tb = top_block(args) - tb.start() - try: - raw_input('Press Enter to quit: ') - except EOFError: - pass - tb.stop() - tb.wait() - - -if __name__ == '__main__': - main() diff --git a/examples/nordic_sniffer_scanner.py b/examples/nordic_sniffer_scanner.py deleted file mode 100755 index 897e57b..0000000 --- a/examples/nordic_sniffer_scanner.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python2 - -from gnuradio import gr, blocks, digital, filter -from gnuradio.filter import firdes -import thread -import osmosdr -import nordic -import pmt -import struct -import time - - -class top_block(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self, "AirHogs Sync Framer Example") - - # SDR configuration - self.freq = 2402e6 - self.gain = 70 - self.symbol_rate = 2e6 - self.sample_rate = 4e6 - - # SDR source (gr-osmosdr source) - self.osmosdr_source = osmosdr.source() - self.osmosdr_source.set_sample_rate(self.sample_rate) - self.osmosdr_source.set_center_freq(self.freq) - self.osmosdr_source.set_gain(self.gain) - self.osmosdr_source.set_antenna('TX/RX') - - # Low pass filter - self.lpf = filter.fir_filter_ccf( - 1, firdes.low_pass_2(1, self.sample_rate, self.symbol_rate / 2, 50e3, 50)) - - # GFSK demod, defaults to 2 samples per symbol - self.gfsk_demod = digital.gfsk_demod() - - # Nordic RX - self.nordic_rx = nordic.nordic_rx(3, 5, 2, 2) - - # Connect the blocks - self.connect((self.osmosdr_source, 0), (self.lpf, 0)) - self.connect((self.lpf, 0), (self.gfsk_demod, 0)) - self.connect((self.gfsk_demod, 0), (self.nordic_rx, 0)) - - # Handle incoming packets - self.nordictap_handler = microsoft_nordictap_handler(self) - self.msg_connect( - self.nordic_rx, "nordictap_out", self.nordictap_handler, "nordictap_in") - - # Tune the USRP by nRF24L channel number - def set_channel(self, channel): - - new_channel = 2400e6 + channel * 1e6 - self.osmosdr_source.set_center_freq(2400e6 + channel * 1e6) - self.nordic_rx.set_channel(channel) - - -# Microsoft mouse nordictap handler -class microsoft_nordictap_handler(gr.sync_block): - - def __init__(self, tb): - gr.sync_block.__init__( - self, name="Nordictap Handler", in_sig=None, out_sig=None) - - self.tb = tb - self.message_port_register_in(pmt.intern("nordictap_in")) - self.set_msg_handler( - pmt.intern("nordictap_in"), self.nordictap_handler) - - # Tick / channel hopping state and logic - self.last_rx = time.time() - self.last_tune = time.time() - self.ch_timeout = 0.4 # timeout a channel after 200ms - self.last_ch = 0 - thread.start_new_thread(self.tick, ()) - - # Channels and channel groups - self.channels = range(2, 84) - - # 10ms tick - def tick(self): - - while True: - - # Check for a stale channel - if ((time.time() - self.last_rx) > self.ch_timeout * 5) and \ - ((time.time() - self.last_tune) > self.ch_timeout): - - self.last_ch += 1 - if self.last_ch >= len(self.channels): - self.last_ch = 0 - print 'Tuning to 24%02i MHz' % self.channels[self.last_ch] - self.last_tune = time.time() - self.tb.set_channel(self.channels[self.last_ch]) - - # Wait 10ms - time.sleep(0.01) - - def nordictap_handler(self, msg): - - data = pmt.to_python(msg).tostring() - - # Unpack the header - values = struct.unpack('BBBBBBB', data[0:7]) - channel = values[0] - data_rate = values[1] - address_length = values[2] - payload_length = values[3] - sequence_number = values[4] - no_ack = values[5] - crc_length = values[6] - - # Parse the address, payload, and crc - address = data[7:7 + address_length] - payload = data[7 + address_length:7 + address_length + payload_length] - crc = data[7 + address_length + payload_length: - 7 + address_length + payload_length + crc_length] - - self.last_rx = time.time() - - # Print the channel, sequence number, address and payload - print 'CH=' + str(2400 + channel), - print 'SEQ=' + str(sequence_number), - print 'ADDR=' + ':'.join('%02X' % ord(b) for b in address), - print 'PLD=' + ':'.join('%02X' % ord(b) for b in payload), - print 'CRC=' + ':'.join('%02X' % ord(b) for b in crc) - - -def main(): - tb = top_block() - tb.start() - try: - raw_input('Press Enter to quit: ') - except EOFError: - pass - tb.stop() - tb.wait() - - -if __name__ == '__main__': - main() diff --git a/examples/nordictap_test.grc b/examples/nordictap_test.grc new file mode 100644 index 0000000..1be6436 --- /dev/null +++ b/examples/nordictap_test.grc @@ -0,0 +1,106 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: nordictap_test + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: samp_rate + id: variable + parameters: + comment: '' + value: '32000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: blocks_message_debug_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: '' + en_uvec: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [785, 220] + rotation: 0 + state: enabled +- name: blocks_message_strobe_0 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.intern("trig") + period: '1000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [168, 207] + rotation: 0 + state: true +- name: nordic_nordictap_transmitter_0 + id: nordic_nordictap_transmitter + parameters: + address: '''\x55\x55\x55\x55\x55''' + affinity: '' + alias: '' + big_packet: '0' + channel_count: '1' + channel_index: '0' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + payload: '''\x20\x20\x20\x20\x32\x30\x2E\x30''' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [402, 183] + rotation: 0 + state: enabled + +connections: +- [blocks_message_strobe_0, strobe, nordic_nordictap_transmitter_0, trig] +- [nordic_nordictap_transmitter_0, nordictap_out, blocks_message_debug_0, print] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/nrf24_receiver.grc b/examples/nrf24_receiver.grc new file mode 100644 index 0000000..fc78a59 --- /dev/null +++ b/examples/nrf24_receiver.grc @@ -0,0 +1,1128 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: nrf24_receiver + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '1' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: samp_rate + id: variable + parameters: + comment: '' + value: 4e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [10, 160] + rotation: 0 + state: enabled +- name: analog_pwr_squelch_xx_1 + id: analog_pwr_squelch_xx + parameters: + affinity: '' + alias: '' + alpha: 5e-4 + comment: '' + gate: 'False' + maxoutbuf: '0' + minoutbuf: '0' + ramp: '0' + threshold: '-35' + type: complex + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [264, 268.0] + rotation: 0 + state: true +- name: analog_quadrature_demod_cf_0 + id: analog_quadrature_demod_cf + parameters: + affinity: '' + alias: '' + comment: '' + gain: 1/((3.1415/2)/2) + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [448, 524] + rotation: 0 + state: enabled +- name: blocks_char_to_float_0 + id: blocks_char_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + scale: '1' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [896, 212] + rotation: 0 + state: disabled +- name: blocks_char_to_float_0_2 + id: blocks_char_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + scale: '1' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [664, 716] + rotation: 0 + state: enabled +- name: blocks_file_sink_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /home/herve/nrf24_rcv_gr.dat + type: float + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1104, 452] + rotation: 0 + state: disabled +- name: blocks_file_sink_0_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /home/herve/nrf24_rcv_gr_bits.dat + type: byte + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1104, 532] + rotation: 0 + state: disabled +- name: blocks_file_source_0 + id: blocks_file_source + parameters: + affinity: '' + alias: '' + begin_tag: pmt.PMT_NIL + comment: '' + file: /home/bjk/gnuradio/src/to_repair/gr-nordic/examples/nrf_data.bin + length: '0' + maxoutbuf: '0' + minoutbuf: '0' + offset: '0' + repeat: 'True' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [128, 140.0] + rotation: 0 + state: disabled +- name: blocks_message_debug_0_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: 'Display recovered + + message' + en_uvec: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1326, 269] + rotation: 0 + state: disabled +- name: blocks_throttle_0 + id: blocks_throttle + parameters: + affinity: '' + alias: '' + comment: '' + ignoretag: 'True' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_second: samp_rate + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [344, 172.0] + rotation: 0 + state: disabled +- name: digital_binary_slicer_fb_0 + id: digital_binary_slicer_fb + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [904, 528] + rotation: 0 + state: enabled +- name: digital_clock_recovery_mm_xx_0 + id: digital_clock_recovery_mm_xx + parameters: + affinity: '' + alias: '' + comment: '' + gain_mu: '0.175' + gain_omega: 0.25*0.175*0.175 + maxoutbuf: '0' + minoutbuf: '0' + mu: '0.5' + omega: 2*(1+0.0) + omega_relative_limit: '0.005' + type: float + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [672, 496] + rotation: 0 + state: enabled +- name: digital_correlate_access_code_xx_ts_0 + id: digital_correlate_access_code_xx_ts + parameters: + access_code: '10101010' + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + tagname: burst + threshold: '0' + type: byte + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [371, 701] + rotation: 0 + state: true +- name: digital_gfsk_demod_0 + id: digital_gfsk_demod + parameters: + affinity: '' + alias: '' + comment: '' + freq_error: '0' + gain_mu: '0.175' + log: 'False' + maxoutbuf: '0' + minoutbuf: '0' + mu: '0.5' + omega_relative_limit: '0.005' + samples_per_symbol: '2' + sensitivity: ((3.1415/2)/2) + verbose: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [672, 344] + rotation: 0 + state: disabled +- name: iio_pluto_source_0 + id: iio_pluto_source + parameters: + affinity: '' + alias: '' + bandwidth: '2000000' + bbdc: 'True' + buffer_size: '32768' + comment: '' + filter: '' + filter_source: '''Auto''' + fpass: '0' + frequency: '2520000000' + fstop: '0' + gain1: '''fast_attack''' + len_tag_key: packet_len + manual_gain1: '64' + maxoutbuf: '0' + minoutbuf: '0' + quadrature: 'True' + rfdc: 'True' + samplerate: int(samp_rate) + type: fc32 + uri: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [17, 294] + rotation: 0 + state: disabled +- name: low_pass_filter_0 + id: low_pass_filter + parameters: + affinity: '' + alias: '' + beta: '6.76' + comment: '' + cutoff_freq: 1e6 + decim: '1' + gain: '1' + interp: '1' + maxoutbuf: '0' + minoutbuf: '0' + samp_rate: samp_rate + type: fir_filter_ccf + width: 250e3 + win: window.WIN_HAMMING + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [440, 336] + rotation: 0 + state: enabled +- name: nordic_nordic_rx_0 + id: nordic_nordic_rx + parameters: + address_length: '5' + address_match: '' + affinity: '' + alias: '' + channel: '120' + comment: '' + crc_length: '2' + data_rate: '2' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [944, 360] + rotation: 0 + state: enabled +- name: nordic_nordictap_printer_0 + id: nordic_nordictap_printer + parameters: + affinity: '' + alias: '' + comment: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1312, 408.0] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: 1024*256*4 + srate: samp_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"squelch_eob"' + type: float + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1056, 196] + rotation: 0 + state: disabled +- name: qtgui_time_sink_x_0_2 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'True' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: int(1024/4) + srate: samp_rate/2 + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"burst"' + type: float + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [824, 700] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_1 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: '1024' + srate: samp_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"squelch_sob"' + type: complex + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [672, 236] + rotation: 0 + state: enabled +- name: uhd_usrp_source_0 + id: uhd_usrp_source + parameters: + affinity: '' + alias: '' + ant0: TX/RX + ant1: RX2 + ant10: RX2 + ant11: RX2 + ant12: RX2 + ant13: RX2 + ant14: RX2 + ant15: RX2 + ant16: RX2 + ant17: RX2 + ant18: RX2 + ant19: RX2 + ant2: RX2 + ant20: RX2 + ant21: RX2 + ant22: RX2 + ant23: RX2 + ant24: RX2 + ant25: RX2 + ant26: RX2 + ant27: RX2 + ant28: RX2 + ant29: RX2 + ant3: RX2 + ant30: RX2 + ant31: RX2 + ant4: RX2 + ant5: RX2 + ant6: RX2 + ant7: RX2 + ant8: RX2 + ant9: RX2 + bw0: 2e6 + bw1: '0' + bw10: '0' + bw11: '0' + bw12: '0' + bw13: '0' + bw14: '0' + bw15: '0' + bw16: '0' + bw17: '0' + bw18: '0' + bw19: '0' + bw2: '0' + bw20: '0' + bw21: '0' + bw22: '0' + bw23: '0' + bw24: '0' + bw25: '0' + bw26: '0' + bw27: '0' + bw28: '0' + bw29: '0' + bw3: '0' + bw30: '0' + bw31: '0' + bw4: '0' + bw5: '0' + bw6: '0' + bw7: '0' + bw8: '0' + bw9: '0' + center_freq0: '2520000000' + center_freq1: '0' + center_freq10: '0' + center_freq11: '0' + center_freq12: '0' + center_freq13: '0' + center_freq14: '0' + center_freq15: '0' + center_freq16: '0' + center_freq17: '0' + center_freq18: '0' + center_freq19: '0' + center_freq2: '0' + center_freq20: '0' + center_freq21: '0' + center_freq22: '0' + center_freq23: '0' + center_freq24: '0' + center_freq25: '0' + center_freq26: '0' + center_freq27: '0' + center_freq28: '0' + center_freq29: '0' + center_freq3: '0' + center_freq30: '0' + center_freq31: '0' + center_freq4: '0' + center_freq5: '0' + center_freq6: '0' + center_freq7: '0' + center_freq8: '0' + center_freq9: '0' + clock_rate: 0e0 + clock_source0: '' + clock_source1: '' + clock_source2: '' + clock_source3: '' + clock_source4: '' + clock_source5: '' + clock_source6: '' + clock_source7: '' + comment: '' + dc_offs0: 0+0j + dc_offs1: 0+0j + dc_offs10: 0+0j + dc_offs11: 0+0j + dc_offs12: 0+0j + dc_offs13: 0+0j + dc_offs14: 0+0j + dc_offs15: 0+0j + dc_offs16: 0+0j + dc_offs17: 0+0j + dc_offs18: 0+0j + dc_offs19: 0+0j + dc_offs2: 0+0j + dc_offs20: 0+0j + dc_offs21: 0+0j + dc_offs22: 0+0j + dc_offs23: 0+0j + dc_offs24: 0+0j + dc_offs25: 0+0j + dc_offs26: 0+0j + dc_offs27: 0+0j + dc_offs28: 0+0j + dc_offs29: 0+0j + dc_offs3: 0+0j + dc_offs30: 0+0j + dc_offs31: 0+0j + dc_offs4: 0+0j + dc_offs5: 0+0j + dc_offs6: 0+0j + dc_offs7: 0+0j + dc_offs8: 0+0j + dc_offs9: 0+0j + dc_offs_enb0: default + dc_offs_enb1: default + dc_offs_enb10: default + dc_offs_enb11: default + dc_offs_enb12: default + dc_offs_enb13: default + dc_offs_enb14: default + dc_offs_enb15: default + dc_offs_enb16: default + dc_offs_enb17: default + dc_offs_enb18: default + dc_offs_enb19: default + dc_offs_enb2: default + dc_offs_enb20: default + dc_offs_enb21: default + dc_offs_enb22: default + dc_offs_enb23: default + dc_offs_enb24: default + dc_offs_enb25: default + dc_offs_enb26: default + dc_offs_enb27: default + dc_offs_enb28: default + dc_offs_enb29: default + dc_offs_enb3: default + dc_offs_enb30: default + dc_offs_enb31: default + dc_offs_enb4: default + dc_offs_enb5: default + dc_offs_enb6: default + dc_offs_enb7: default + dc_offs_enb8: default + dc_offs_enb9: default + dev_addr: '""' + dev_args: '""' + gain0: '85' + gain1: '0' + gain10: '0' + gain11: '0' + gain12: '0' + gain13: '0' + gain14: '0' + gain15: '0' + gain16: '0' + gain17: '0' + gain18: '0' + gain19: '0' + gain2: '0' + gain20: '0' + gain21: '0' + gain22: '0' + gain23: '0' + gain24: '0' + gain25: '0' + gain26: '0' + gain27: '0' + gain28: '0' + gain29: '0' + gain3: '0' + gain30: '0' + gain31: '0' + gain4: '0' + gain5: '0' + gain6: '0' + gain7: '0' + gain8: '0' + gain9: '0' + gain_type0: default + gain_type1: default + gain_type10: default + gain_type11: default + gain_type12: default + gain_type13: default + gain_type14: default + gain_type15: default + gain_type16: default + gain_type17: default + gain_type18: default + gain_type19: default + gain_type2: default + gain_type20: default + gain_type21: default + gain_type22: default + gain_type23: default + gain_type24: default + gain_type25: default + gain_type26: default + gain_type27: default + gain_type28: default + gain_type29: default + gain_type3: default + gain_type30: default + gain_type31: default + gain_type4: default + gain_type5: default + gain_type6: default + gain_type7: default + gain_type8: default + gain_type9: default + iq_imbal0: 0+0j + iq_imbal1: 0+0j + iq_imbal10: 0+0j + iq_imbal11: 0+0j + iq_imbal12: 0+0j + iq_imbal13: 0+0j + iq_imbal14: 0+0j + iq_imbal15: 0+0j + iq_imbal16: 0+0j + iq_imbal17: 0+0j + iq_imbal18: 0+0j + iq_imbal19: 0+0j + iq_imbal2: 0+0j + iq_imbal20: 0+0j + iq_imbal21: 0+0j + iq_imbal22: 0+0j + iq_imbal23: 0+0j + iq_imbal24: 0+0j + iq_imbal25: 0+0j + iq_imbal26: 0+0j + iq_imbal27: 0+0j + iq_imbal28: 0+0j + iq_imbal29: 0+0j + iq_imbal3: 0+0j + iq_imbal30: 0+0j + iq_imbal31: 0+0j + iq_imbal4: 0+0j + iq_imbal5: 0+0j + iq_imbal6: 0+0j + iq_imbal7: 0+0j + iq_imbal8: 0+0j + iq_imbal9: 0+0j + iq_imbal_enb0: default + iq_imbal_enb1: default + iq_imbal_enb10: default + iq_imbal_enb11: default + iq_imbal_enb12: default + iq_imbal_enb13: default + iq_imbal_enb14: default + iq_imbal_enb15: default + iq_imbal_enb16: default + iq_imbal_enb17: default + iq_imbal_enb18: default + iq_imbal_enb19: default + iq_imbal_enb2: default + iq_imbal_enb20: default + iq_imbal_enb21: default + iq_imbal_enb22: default + iq_imbal_enb23: default + iq_imbal_enb24: default + iq_imbal_enb25: default + iq_imbal_enb26: default + iq_imbal_enb27: default + iq_imbal_enb28: default + iq_imbal_enb29: default + iq_imbal_enb3: default + iq_imbal_enb30: default + iq_imbal_enb31: default + iq_imbal_enb4: default + iq_imbal_enb5: default + iq_imbal_enb6: default + iq_imbal_enb7: default + iq_imbal_enb8: default + iq_imbal_enb9: default + lo_export0: 'False' + lo_export1: 'False' + lo_export10: 'False' + lo_export11: 'False' + lo_export12: 'False' + lo_export13: 'False' + lo_export14: 'False' + lo_export15: 'False' + lo_export16: 'False' + lo_export17: 'False' + lo_export18: 'False' + lo_export19: 'False' + lo_export2: 'False' + lo_export20: 'False' + lo_export21: 'False' + lo_export22: 'False' + lo_export23: 'False' + lo_export24: 'False' + lo_export25: 'False' + lo_export26: 'False' + lo_export27: 'False' + lo_export28: 'False' + lo_export29: 'False' + lo_export3: 'False' + lo_export30: 'False' + lo_export31: 'False' + lo_export4: 'False' + lo_export5: 'False' + lo_export6: 'False' + lo_export7: 'False' + lo_export8: 'False' + lo_export9: 'False' + lo_source0: internal + lo_source1: internal + lo_source10: internal + lo_source11: internal + lo_source12: internal + lo_source13: internal + lo_source14: internal + lo_source15: internal + lo_source16: internal + lo_source17: internal + lo_source18: internal + lo_source19: internal + lo_source2: internal + lo_source20: internal + lo_source21: internal + lo_source22: internal + lo_source23: internal + lo_source24: internal + lo_source25: internal + lo_source26: internal + lo_source27: internal + lo_source28: internal + lo_source29: internal + lo_source3: internal + lo_source30: internal + lo_source31: internal + lo_source4: internal + lo_source5: internal + lo_source6: internal + lo_source7: internal + lo_source8: internal + lo_source9: internal + maxoutbuf: '0' + minoutbuf: '0' + nchan: '1' + num_mboards: '1' + otw: '' + rx_agc0: Default + rx_agc1: Default + rx_agc10: Default + rx_agc11: Default + rx_agc12: Default + rx_agc13: Default + rx_agc14: Default + rx_agc15: Default + rx_agc16: Default + rx_agc17: Default + rx_agc18: Default + rx_agc19: Default + rx_agc2: Default + rx_agc20: Default + rx_agc21: Default + rx_agc22: Default + rx_agc23: Default + rx_agc24: Default + rx_agc25: Default + rx_agc26: Default + rx_agc27: Default + rx_agc28: Default + rx_agc29: Default + rx_agc3: Default + rx_agc30: Default + rx_agc31: Default + rx_agc4: Default + rx_agc5: Default + rx_agc6: Default + rx_agc7: Default + rx_agc8: Default + rx_agc9: Default + samp_rate: samp_rate + sd_spec0: '' + sd_spec1: '' + sd_spec2: '' + sd_spec3: '' + sd_spec4: '' + sd_spec5: '' + sd_spec6: '' + sd_spec7: '' + show_lo_controls: 'False' + start_time: '-1.0' + stream_args: '' + stream_chans: '[]' + sync: sync + time_source0: '' + time_source1: '' + time_source2: '' + time_source3: '' + time_source4: '' + time_source5: '' + time_source6: '' + time_source7: '' + type: fc32 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [19, 520] + rotation: 0 + state: enabled + +connections: +- [analog_pwr_squelch_xx_1, '0', low_pass_filter_0, '0'] +- [analog_pwr_squelch_xx_1, '0', qtgui_time_sink_x_1, '0'] +- [analog_quadrature_demod_cf_0, '0', digital_clock_recovery_mm_xx_0, '0'] +- [blocks_char_to_float_0, '0', qtgui_time_sink_x_0, '0'] +- [blocks_char_to_float_0_2, '0', qtgui_time_sink_x_0_2, '0'] +- [blocks_file_source_0, '0', blocks_throttle_0, '0'] +- [blocks_throttle_0, '0', analog_pwr_squelch_xx_1, '0'] +- [digital_binary_slicer_fb_0, '0', blocks_char_to_float_0, '0'] +- [digital_binary_slicer_fb_0, '0', digital_correlate_access_code_xx_ts_0, '0'] +- [digital_binary_slicer_fb_0, '0', nordic_nordic_rx_0, '0'] +- [digital_clock_recovery_mm_xx_0, '0', digital_binary_slicer_fb_0, '0'] +- [digital_correlate_access_code_xx_ts_0, '0', blocks_char_to_float_0_2, '0'] +- [digital_gfsk_demod_0, '0', digital_correlate_access_code_xx_ts_0, '0'] +- [digital_gfsk_demod_0, '0', nordic_nordic_rx_0, '0'] +- [low_pass_filter_0, '0', analog_quadrature_demod_cf_0, '0'] +- [low_pass_filter_0, '0', digital_gfsk_demod_0, '0'] +- [nordic_nordic_rx_0, nordictap_out, blocks_message_debug_0_0, print_pdu] +- [nordic_nordic_rx_0, nordictap_out, nordic_nordictap_printer_0, nordictap_in] +- [uhd_usrp_source_0, '0', analog_pwr_squelch_xx_1, '0'] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/nrf24_tx.grc b/examples/nrf24_tx.grc new file mode 100644 index 0000000..e20ef96 --- /dev/null +++ b/examples/nrf24_tx.grc @@ -0,0 +1,228 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: top_block + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: address + id: variable + parameters: + comment: '' + value: '[0, 85, 2, 5, 8, 0, 0, 2, 85, 85, 85, 85, 85]' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 332] + rotation: 0 + state: enabled +- name: payload + id: variable + parameters: + comment: '' + value: '" 20.0"' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 252] + rotation: 0 + state: enabled +- name: pkt_vec + id: variable + parameters: + comment: '' + value: address + [ ord(x) for x in payload ] + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 412] + rotation: 0 + state: enabled +- name: probe_var + id: variable_function_probe + parameters: + block_id: probe_signal + comment: '' + function_args: '' + function_name: level + poll_rate: '10' + value: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [17, 486] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: '32000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: variable_qtgui_entry_0 + id: variable_qtgui_entry + parameters: + comment: '' + gui_hint: '' + label: '' + type: int + value: probe_var + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [18, 81] + rotation: 0 + state: enabled +- name: blocks_message_strobe_0 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.init_u8vector( len(pkt_vec), pkt_vec) + period: '500' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [294, 199] + rotation: 0 + state: disabled +- name: blocks_message_strobe_1 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.intern("trig") + period: '2000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [161, 599] + rotation: 0 + state: true +- name: blocks_throttle_0 + id: blocks_throttle + parameters: + affinity: '' + alias: '' + comment: '' + ignoretag: 'True' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_second: samp_rate + type: byte + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [794, 207] + rotation: 0 + state: true +- name: nordic_nordic_tx_0 + id: nordic_nordic_tx + parameters: + affinity: '' + alias: '' + channel_count: '1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [618, 207] + rotation: 0 + state: enabled +- name: nordic_nordictap_transmitter_0 + id: nordic_nordictap_transmitter + parameters: + address: '''\x55\x55\x55\x55\x55''' + affinity: '' + alias: '' + big_packet: '0' + channel_count: '1' + channel_index: '0' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + payload: '''\x20\x20\x20\x20\x32\x30\x2E\x30''' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [348, 398] + rotation: 0 + state: true +- name: probe_signal + id: blocks_probe_signal_x + parameters: + affinity: '' + alias: '' + comment: '' + type: byte + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [981, 207] + rotation: 0 + state: enabled + +connections: +- [blocks_message_strobe_0, strobe, nordic_nordic_tx_0, nordictap_in] +- [blocks_message_strobe_1, strobe, nordic_nordictap_transmitter_0, trig] +- [blocks_throttle_0, '0', probe_signal, '0'] +- [nordic_nordic_tx_0, '0', blocks_throttle_0, '0'] +- [nordic_nordictap_transmitter_0, nordictap_out, nordic_nordic_tx_0, nordictap_in] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/nrf_data.bin b/examples/nrf_data.bin new file mode 100644 index 0000000..684fb2d Binary files /dev/null and b/examples/nrf_data.bin differ diff --git a/examples/nrf_scan.grc b/examples/nrf_scan.grc new file mode 100644 index 0000000..a55d672 --- /dev/null +++ b/examples/nrf_scan.grc @@ -0,0 +1,948 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: nrf_scan + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: fsk_deviation_hz + id: variable + parameters: + comment: '' + value: 320e3 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [120, 164] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: 4e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: analog_pwr_squelch_xx_0 + id: analog_pwr_squelch_xx + parameters: + affinity: '' + alias: '' + alpha: 5e-4 + comment: '' + gate: 'False' + maxoutbuf: '0' + minoutbuf: '0' + ramp: '0' + threshold: '-35' + type: complex + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [296, 216] + rotation: 0 + state: enabled +- name: analog_quadrature_demod_cf_0 + id: analog_quadrature_demod_cf + parameters: + affinity: '' + alias: '' + comment: '' + gain: samp_rate/(2*math.pi*fsk_deviation_hz/8.0) + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [712, 52] + rotation: 0 + state: disabled +- name: analog_simple_squelch_cc_0 + id: analog_simple_squelch_cc + parameters: + affinity: '' + alias: '' + alpha: '0.1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + threshold: '-35' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [312, 316] + rotation: 0 + state: disabled +- name: blocks_file_sink_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /home/herve/nrf24_2500m_250k_2.bin + type: float + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1104, 276] + rotation: 0 + state: disabled +- name: blocks_uchar_to_float_0 + id: blocks_uchar_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [928, 176] + rotation: 0 + state: enabled +- name: blocks_uchar_to_float_0_0 + id: blocks_uchar_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1064, 56] + rotation: 0 + state: disabled +- name: digital_binary_slicer_fb_0 + id: digital_binary_slicer_fb + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [904, 56] + rotation: 0 + state: disabled +- name: digital_gfsk_demod_0 + id: digital_gfsk_demod + parameters: + affinity: '' + alias: '' + comment: '' + freq_error: '0.0' + gain_mu: '0.175' + log: 'False' + maxoutbuf: '0' + minoutbuf: '0' + mu: '0.5' + omega_relative_limit: '0.005' + samples_per_symbol: '2' + sensitivity: '1.0' + verbose: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [712, 136] + rotation: 0 + state: enabled +- name: iio_pluto_source_0 + id: iio_pluto_source + parameters: + affinity: '' + alias: '' + bandwidth: '20000000' + bbdc: 'True' + buffer_size: 0x8000*16 + comment: '' + filter: '' + filter_source: '''Auto''' + fpass: '0' + frequency: int(2485e6) + fstop: '0' + gain1: '''manual''' + len_tag_key: packet_len + manual_gain1: '64' + maxoutbuf: '0' + minoutbuf: '0' + quadrature: 'True' + rfdc: 'True' + samplerate: int(samp_rate) + type: fc32 + uri: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [400, 548.0] + rotation: 180 + state: true +- name: low_pass_filter_0 + id: low_pass_filter + parameters: + affinity: '' + alias: '' + beta: '6.76' + comment: '' + cutoff_freq: fsk_deviation_hz + decim: '2' + gain: '1' + interp: '1' + maxoutbuf: '0' + minoutbuf: '0' + samp_rate: samp_rate + type: fir_filter_ccf + width: 100e3 + win: window.WIN_HAMMING + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [504, 280] + rotation: 0 + state: enabled +- name: qtgui_freq_sink_x_0 + id: qtgui_freq_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + average: '1.0' + axislabels: 'True' + bw: samp_rate/2 + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + ctrlpanel: 'False' + fc: '0' + fftsize: 1024*8 + freqhalf: 'True' + grid: 'False' + gui_hint: '' + label: Relative Gain + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + norm_window: 'False' + showports: 'True' + tr_chan: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_tag: '""' + type: complex + units: dB + update_time: '0.01' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + wintype: window.WIN_BLACKMAN_hARRIS + ymax: '10' + ymin: '-140' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [832, 308] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: 1024*256 + srate: samp_rate/2 + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '""' + type: float + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '2' + ymin: '0' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1096, 156] + rotation: 0 + state: enabled +- name: qtgui_waterfall_sink_x_0 + id: qtgui_waterfall_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + axislabels: 'True' + bw: samp_rate/2 + color1: '0' + color10: '0' + color2: '0' + color3: '0' + color4: '0' + color5: '0' + color6: '0' + color7: '0' + color8: '0' + color9: '0' + comment: '' + fc: '0' + fftsize: 1024*8 + freqhalf: 'True' + grid: 'False' + gui_hint: '' + int_max: '10' + int_min: '-100' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + showports: 'True' + type: complex + update_time: '0.10' + wintype: window.WIN_BLACKMAN_hARRIS + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [840, 444] + rotation: 0 + state: disabled +- name: uhd_usrp_source_0 + id: uhd_usrp_source + parameters: + affinity: '' + alias: '' + ant0: TX/RX + ant1: '' + ant10: '' + ant11: '' + ant12: '' + ant13: '' + ant14: '' + ant15: '' + ant16: '' + ant17: '' + ant18: '' + ant19: '' + ant2: '' + ant20: '' + ant21: '' + ant22: '' + ant23: '' + ant24: '' + ant25: '' + ant26: '' + ant27: '' + ant28: '' + ant29: '' + ant3: '' + ant30: '' + ant31: '' + ant4: '' + ant5: '' + ant6: '' + ant7: '' + ant8: '' + ant9: '' + bw0: '0' + bw1: '0' + bw10: '0' + bw11: '0' + bw12: '0' + bw13: '0' + bw14: '0' + bw15: '0' + bw16: '0' + bw17: '0' + bw18: '0' + bw19: '0' + bw2: '0' + bw20: '0' + bw21: '0' + bw22: '0' + bw23: '0' + bw24: '0' + bw25: '0' + bw26: '0' + bw27: '0' + bw28: '0' + bw29: '0' + bw3: '0' + bw30: '0' + bw31: '0' + bw4: '0' + bw5: '0' + bw6: '0' + bw7: '0' + bw8: '0' + bw9: '0' + center_freq0: 2500e6 + center_freq1: '0' + center_freq10: '0' + center_freq11: '0' + center_freq12: '0' + center_freq13: '0' + center_freq14: '0' + center_freq15: '0' + center_freq16: '0' + center_freq17: '0' + center_freq18: '0' + center_freq19: '0' + center_freq2: '0' + center_freq20: '0' + center_freq21: '0' + center_freq22: '0' + center_freq23: '0' + center_freq24: '0' + center_freq25: '0' + center_freq26: '0' + center_freq27: '0' + center_freq28: '0' + center_freq29: '0' + center_freq3: '0' + center_freq30: '0' + center_freq31: '0' + center_freq4: '0' + center_freq5: '0' + center_freq6: '0' + center_freq7: '0' + center_freq8: '0' + center_freq9: '0' + clock_rate: '0.0' + clock_source0: '' + clock_source1: '' + clock_source2: '' + clock_source3: '' + clock_source4: '' + clock_source5: '' + clock_source6: '' + clock_source7: '' + comment: '' + dc_offs0: 0+0j + dc_offs1: 0+0j + dc_offs10: 0+0j + dc_offs11: 0+0j + dc_offs12: 0+0j + dc_offs13: 0+0j + dc_offs14: 0+0j + dc_offs15: 0+0j + dc_offs16: 0+0j + dc_offs17: 0+0j + dc_offs18: 0+0j + dc_offs19: 0+0j + dc_offs2: 0+0j + dc_offs20: 0+0j + dc_offs21: 0+0j + dc_offs22: 0+0j + dc_offs23: 0+0j + dc_offs24: 0+0j + dc_offs25: 0+0j + dc_offs26: 0+0j + dc_offs27: 0+0j + dc_offs28: 0+0j + dc_offs29: 0+0j + dc_offs3: 0+0j + dc_offs30: 0+0j + dc_offs31: 0+0j + dc_offs4: 0+0j + dc_offs5: 0+0j + dc_offs6: 0+0j + dc_offs7: 0+0j + dc_offs8: 0+0j + dc_offs9: 0+0j + dc_offs_enb0: default + dc_offs_enb1: default + dc_offs_enb10: default + dc_offs_enb11: default + dc_offs_enb12: default + dc_offs_enb13: default + dc_offs_enb14: default + dc_offs_enb15: default + dc_offs_enb16: default + dc_offs_enb17: default + dc_offs_enb18: default + dc_offs_enb19: default + dc_offs_enb2: default + dc_offs_enb20: default + dc_offs_enb21: default + dc_offs_enb22: default + dc_offs_enb23: default + dc_offs_enb24: default + dc_offs_enb25: default + dc_offs_enb26: default + dc_offs_enb27: default + dc_offs_enb28: default + dc_offs_enb29: default + dc_offs_enb3: default + dc_offs_enb30: default + dc_offs_enb31: default + dc_offs_enb4: default + dc_offs_enb5: default + dc_offs_enb6: default + dc_offs_enb7: default + dc_offs_enb8: default + dc_offs_enb9: default + dev_addr: '"type=b200"' + dev_args: '""' + gain0: '50' + gain1: '0' + gain10: '0' + gain11: '0' + gain12: '0' + gain13: '0' + gain14: '0' + gain15: '0' + gain16: '0' + gain17: '0' + gain18: '0' + gain19: '0' + gain2: '0' + gain20: '0' + gain21: '0' + gain22: '0' + gain23: '0' + gain24: '0' + gain25: '0' + gain26: '0' + gain27: '0' + gain28: '0' + gain29: '0' + gain3: '0' + gain30: '0' + gain31: '0' + gain4: '0' + gain5: '0' + gain6: '0' + gain7: '0' + gain8: '0' + gain9: '0' + gain_type0: default + gain_type1: default + gain_type10: default + gain_type11: default + gain_type12: default + gain_type13: default + gain_type14: default + gain_type15: default + gain_type16: default + gain_type17: default + gain_type18: default + gain_type19: default + gain_type2: default + gain_type20: default + gain_type21: default + gain_type22: default + gain_type23: default + gain_type24: default + gain_type25: default + gain_type26: default + gain_type27: default + gain_type28: default + gain_type29: default + gain_type3: default + gain_type30: default + gain_type31: default + gain_type4: default + gain_type5: default + gain_type6: default + gain_type7: default + gain_type8: default + gain_type9: default + iq_imbal0: 0+0j + iq_imbal1: 0+0j + iq_imbal10: 0+0j + iq_imbal11: 0+0j + iq_imbal12: 0+0j + iq_imbal13: 0+0j + iq_imbal14: 0+0j + iq_imbal15: 0+0j + iq_imbal16: 0+0j + iq_imbal17: 0+0j + iq_imbal18: 0+0j + iq_imbal19: 0+0j + iq_imbal2: 0+0j + iq_imbal20: 0+0j + iq_imbal21: 0+0j + iq_imbal22: 0+0j + iq_imbal23: 0+0j + iq_imbal24: 0+0j + iq_imbal25: 0+0j + iq_imbal26: 0+0j + iq_imbal27: 0+0j + iq_imbal28: 0+0j + iq_imbal29: 0+0j + iq_imbal3: 0+0j + iq_imbal30: 0+0j + iq_imbal31: 0+0j + iq_imbal4: 0+0j + iq_imbal5: 0+0j + iq_imbal6: 0+0j + iq_imbal7: 0+0j + iq_imbal8: 0+0j + iq_imbal9: 0+0j + iq_imbal_enb0: default + iq_imbal_enb1: default + iq_imbal_enb10: default + iq_imbal_enb11: default + iq_imbal_enb12: default + iq_imbal_enb13: default + iq_imbal_enb14: default + iq_imbal_enb15: default + iq_imbal_enb16: default + iq_imbal_enb17: default + iq_imbal_enb18: default + iq_imbal_enb19: default + iq_imbal_enb2: default + iq_imbal_enb20: default + iq_imbal_enb21: default + iq_imbal_enb22: default + iq_imbal_enb23: default + iq_imbal_enb24: default + iq_imbal_enb25: default + iq_imbal_enb26: default + iq_imbal_enb27: default + iq_imbal_enb28: default + iq_imbal_enb29: default + iq_imbal_enb3: default + iq_imbal_enb30: default + iq_imbal_enb31: default + iq_imbal_enb4: default + iq_imbal_enb5: default + iq_imbal_enb6: default + iq_imbal_enb7: default + iq_imbal_enb8: default + iq_imbal_enb9: default + lo_export0: 'False' + lo_export1: 'False' + lo_export10: 'False' + lo_export11: 'False' + lo_export12: 'False' + lo_export13: 'False' + lo_export14: 'False' + lo_export15: 'False' + lo_export16: 'False' + lo_export17: 'False' + lo_export18: 'False' + lo_export19: 'False' + lo_export2: 'False' + lo_export20: 'False' + lo_export21: 'False' + lo_export22: 'False' + lo_export23: 'False' + lo_export24: 'False' + lo_export25: 'False' + lo_export26: 'False' + lo_export27: 'False' + lo_export28: 'False' + lo_export29: 'False' + lo_export3: 'False' + lo_export30: 'False' + lo_export31: 'False' + lo_export4: 'False' + lo_export5: 'False' + lo_export6: 'False' + lo_export7: 'False' + lo_export8: 'False' + lo_export9: 'False' + lo_source0: internal + lo_source1: internal + lo_source10: internal + lo_source11: internal + lo_source12: internal + lo_source13: internal + lo_source14: internal + lo_source15: internal + lo_source16: internal + lo_source17: internal + lo_source18: internal + lo_source19: internal + lo_source2: internal + lo_source20: internal + lo_source21: internal + lo_source22: internal + lo_source23: internal + lo_source24: internal + lo_source25: internal + lo_source26: internal + lo_source27: internal + lo_source28: internal + lo_source29: internal + lo_source3: internal + lo_source30: internal + lo_source31: internal + lo_source4: internal + lo_source5: internal + lo_source6: internal + lo_source7: internal + lo_source8: internal + lo_source9: internal + maxoutbuf: '0' + minoutbuf: '0' + nchan: '1' + num_mboards: '1' + otw: '' + rx_agc0: Default + rx_agc1: Default + rx_agc10: Default + rx_agc11: Default + rx_agc12: Default + rx_agc13: Default + rx_agc14: Default + rx_agc15: Default + rx_agc16: Default + rx_agc17: Default + rx_agc18: Default + rx_agc19: Default + rx_agc2: Default + rx_agc20: Default + rx_agc21: Default + rx_agc22: Default + rx_agc23: Default + rx_agc24: Default + rx_agc25: Default + rx_agc26: Default + rx_agc27: Default + rx_agc28: Default + rx_agc29: Default + rx_agc3: Default + rx_agc30: Default + rx_agc31: Default + rx_agc4: Default + rx_agc5: Default + rx_agc6: Default + rx_agc7: Default + rx_agc8: Default + rx_agc9: Default + samp_rate: samp_rate + sd_spec0: '' + sd_spec1: '' + sd_spec2: '' + sd_spec3: '' + sd_spec4: '' + sd_spec5: '' + sd_spec6: '' + sd_spec7: '' + show_lo_controls: 'False' + start_time: '-1.0' + stream_args: '' + stream_chans: '[]' + sync: sync + time_source0: '' + time_source1: '' + time_source2: '' + time_source3: '' + time_source4: '' + time_source5: '' + time_source6: '' + time_source7: '' + type: fc32 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [80, 296] + rotation: 0 + state: disabled + +connections: +- [analog_pwr_squelch_xx_0, '0', low_pass_filter_0, '0'] +- [analog_quadrature_demod_cf_0, '0', digital_binary_slicer_fb_0, '0'] +- [analog_simple_squelch_cc_0, '0', low_pass_filter_0, '0'] +- [blocks_uchar_to_float_0, '0', blocks_file_sink_0, '0'] +- [blocks_uchar_to_float_0, '0', qtgui_time_sink_x_0, '0'] +- [blocks_uchar_to_float_0_0, '0', qtgui_time_sink_x_0, '0'] +- [digital_binary_slicer_fb_0, '0', blocks_uchar_to_float_0_0, '0'] +- [digital_gfsk_demod_0, '0', blocks_uchar_to_float_0, '0'] +- [iio_pluto_source_0, '0', analog_pwr_squelch_xx_0, '0'] +- [low_pass_filter_0, '0', analog_quadrature_demod_cf_0, '0'] +- [low_pass_filter_0, '0', digital_gfsk_demod_0, '0'] +- [low_pass_filter_0, '0', qtgui_freq_sink_x_0, '0'] +- [low_pass_filter_0, '0', qtgui_waterfall_sink_x_0, '0'] +- [uhd_usrp_source_0, '0', analog_simple_squelch_cc_0, '0'] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/pluto_rx.grc b/examples/pluto_rx.grc new file mode 100644 index 0000000..5f19d0a --- /dev/null +++ b/examples/pluto_rx.grc @@ -0,0 +1,233 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: pluto_rx + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: samp_rate + id: variable + parameters: + comment: '' + value: 4e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: analog_pwr_squelch_xx_0 + id: analog_pwr_squelch_xx + parameters: + affinity: '' + alias: '' + alpha: 5e-4 + comment: '' + gate: 'False' + maxoutbuf: '0' + minoutbuf: '0' + ramp: '0' + threshold: '-35' + type: complex + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [616, 304] + rotation: 0 + state: enabled +- name: iio_pluto_source_0 + id: iio_pluto_source + parameters: + affinity: '' + alias: '' + bandwidth: '20000000' + bbdc: 'True' + buffer_size: 0x8000*32 + comment: '' + filter: '' + filter_source: '''Auto''' + fpass: '0' + frequency: int(2485e6+8e3) + fstop: '0' + gain1: '''manual''' + len_tag_key: packet_len + manual_gain1: '64' + maxoutbuf: '0' + minoutbuf: '0' + quadrature: 'True' + rfdc: 'True' + samplerate: int(samp_rate) + type: fc32 + uri: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [288, 204.0] + rotation: 0 + state: true +- name: qtgui_sink_x_0 + id: qtgui_sink_x + parameters: + affinity: '' + alias: '' + bw: samp_rate + comment: '' + fc: '0' + fftsize: '1024' + gui_hint: '' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + plotconst: 'True' + plotfreq: 'True' + plottime: 'True' + plotwaterfall: 'True' + rate: '100' + showports: 'True' + showrf: 'False' + type: complex + wintype: window.WIN_BLACKMAN_hARRIS + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [816, 184] + rotation: 0 + state: disabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: 8192*128 + srate: samp_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '""' + type: complex + update_time: '0.25' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1.5' + ymin: '-1.5' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [816, 308] + rotation: 0 + state: enabled + +connections: +- [analog_pwr_squelch_xx_0, '0', qtgui_time_sink_x_0, '0'] +- [iio_pluto_source_0, '0', analog_pwr_squelch_xx_0, '0'] +- [iio_pluto_source_0, '0', qtgui_sink_x_0, '0'] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/test_gfsk_mod.grc b/examples/test_gfsk_mod.grc new file mode 100644 index 0000000..2eece00 --- /dev/null +++ b/examples/test_gfsk_mod.grc @@ -0,0 +1,127 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: test_gfsk_mod + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: samp_rate + id: variable + parameters: + comment: '' + value: 500e3 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: blocks_file_source_0 + id: blocks_file_source + parameters: + affinity: '' + alias: '' + begin_tag: pmt.PMT_NIL + comment: '' + file: /home/herve/gr-nordic/examples/nordic_transmitter.py + length: '0' + maxoutbuf: '0' + minoutbuf: '0' + offset: '0' + repeat: 'True' + type: byte + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [192, 148] + rotation: 0 + state: enabled +- name: digital_gfsk_mod_0 + id: digital_gfsk_mod + parameters: + affinity: '' + alias: '' + bt: '0.35' + comment: '' + do_unpack: 'True' + log: 'True' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_symbol: '2' + sensitivity: '1.0' + verbose: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [520, 148] + rotation: 0 + state: enabled +- name: qtgui_sink_x_0 + id: qtgui_sink_x + parameters: + affinity: '' + alias: '' + bw: samp_rate + comment: '' + fc: '0' + fftsize: '1024' + gui_hint: '' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + plotconst: 'True' + plotfreq: 'True' + plottime: 'True' + plotwaterfall: 'True' + rate: '10' + showports: 'True' + showrf: 'False' + type: complex + wintype: window.WIN_BLACKMAN_hARRIS + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [736, 144] + rotation: 0 + state: enabled + +connections: +- [blocks_file_source_0, '0', digital_gfsk_mod_0, '0'] +- [digital_gfsk_mod_0, '0', qtgui_sink_x_0, '0'] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/tx_nrf.grc b/examples/tx_nrf.grc new file mode 100644 index 0000000..47103cd --- /dev/null +++ b/examples/tx_nrf.grc @@ -0,0 +1,729 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: tx_nrf + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '1' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: address + id: variable + parameters: + comment: '' + value: '[0, 120, 2, 5, 8, 0, 0, 2, 231, 231, 231, 231, 231]' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 324] + rotation: 0 + state: enabled +- name: freq + id: variable + parameters: + comment: '' + value: 2520e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [128, 244] + rotation: 0 + state: enabled +- name: payload + id: variable + parameters: + comment: '' + value: '"22.75"' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [9, 244] + rotation: 0 + state: enabled +- name: pkt_vec + id: variable + parameters: + comment: '' + value: address + [ ord(x) for x in payload ] + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 404] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: 4e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: symbol_rate + id: variable + parameters: + comment: '' + value: 2e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 484] + rotation: 0 + state: enabled +- name: taps + id: variable_low_pass_filter_taps + parameters: + beta: '6.76' + comment: '' + cutoff_freq: (symbol_rate/2)*1.5 + gain: '1.0' + samp_rate: samp_rate + value: '' + width: 250e3 + win: window.WIN_HAMMING + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [184, 8] + rotation: 0 + state: enabled +- name: blocks_file_sink_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /home/herve/gr-nordic/examples/data_tr.bin + type: complex + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1112, 636.0] + rotation: 0 + state: disabled +- name: blocks_message_debug_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: '' + en_uvec: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [428, 24] + rotation: 0 + state: disabled +- name: blocks_message_strobe_0 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.init_u8vector( len(pkt_vec), pkt_vec) + period: '1000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [145, 165] + rotation: 0 + state: enabled +- name: digital_gfsk_mod_0 + id: digital_gfsk_mod + parameters: + affinity: '' + alias: '' + bt: '0.5' + comment: '' + do_unpack: 'True' + log: 'False' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_symbol: '2' + sensitivity: 1.5707/2 + verbose: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [592, 212.0] + rotation: 0 + state: enabled +- name: iio_pluto_sink_0 + id: iio_pluto_sink + parameters: + affinity: '' + alias: '' + attenuation1: '10.0' + bandwidth: '3000000' + buffer_size: '0x200' + comment: '' + cyclic: 'False' + filter: '' + filter_source: '''Auto''' + fpass: '0' + frequency: int(freq) + fstop: '0' + len_tag_key: '' + samplerate: int(samp_rate) + type: fc32 + uri: ip:192.168.2.1 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1096, 148.0] + rotation: 0 + state: enabled +- name: nordic_nordic_tx_0 + id: nordic_nordic_tx + parameters: + affinity: '' + alias: '' + channel_count: '1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [391, 257] + rotation: 0 + state: enabled +- name: pfb_synthesizer_ccf_0 + id: pfb_synthesizer_ccf + parameters: + affinity: '' + alias: '' + bus_structure_sink: '[[0,],]' + ch_map: '[]' + comment: '' + connections: '1' + maxoutbuf: '0' + minoutbuf: '0' + numchans: '1' + samp_delay: '0' + taps: taps + twox: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [808, 212.0] + rotation: 0 + state: enabled +- name: qtgui_freq_sink_x_0 + id: qtgui_freq_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + average: '1.0' + axislabels: 'True' + bw: samp_rate + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + ctrlpanel: 'False' + fc: '0' + fftsize: '1024' + freqhalf: 'True' + grid: 'False' + gui_hint: '' + label: Relative Gain + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + norm_window: 'False' + showports: 'True' + tr_chan: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_tag: '""' + type: complex + units: dB + update_time: '0.01' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + wintype: window.WIN_BLACKMAN_hARRIS + ymax: '10' + ymin: '-140' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1096, 32.0] + rotation: 0 + state: disabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: '512' + srate: samp_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"packet_len"' + type: complex + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1111, 532] + rotation: 0 + state: enabled +- name: uhd_usrp_sink_0 + id: uhd_usrp_sink + parameters: + affinity: '' + alias: '' + ant0: TX/RX + ant1: '' + ant10: '' + ant11: '' + ant12: '' + ant13: '' + ant14: '' + ant15: '' + ant16: '' + ant17: '' + ant18: '' + ant19: '' + ant2: '' + ant20: '' + ant21: '' + ant22: '' + ant23: '' + ant24: '' + ant25: '' + ant26: '' + ant27: '' + ant28: '' + ant29: '' + ant3: '' + ant30: '' + ant31: '' + ant4: '' + ant5: '' + ant6: '' + ant7: '' + ant8: '' + ant9: '' + bw0: 3e6 + bw1: '0' + bw10: '0' + bw11: '0' + bw12: '0' + bw13: '0' + bw14: '0' + bw15: '0' + bw16: '0' + bw17: '0' + bw18: '0' + bw19: '0' + bw2: '0' + bw20: '0' + bw21: '0' + bw22: '0' + bw23: '0' + bw24: '0' + bw25: '0' + bw26: '0' + bw27: '0' + bw28: '0' + bw29: '0' + bw3: '0' + bw30: '0' + bw31: '0' + bw4: '0' + bw5: '0' + bw6: '0' + bw7: '0' + bw8: '0' + bw9: '0' + center_freq0: freq + center_freq1: '0' + center_freq10: '0' + center_freq11: '0' + center_freq12: '0' + center_freq13: '0' + center_freq14: '0' + center_freq15: '0' + center_freq16: '0' + center_freq17: '0' + center_freq18: '0' + center_freq19: '0' + center_freq2: '0' + center_freq20: '0' + center_freq21: '0' + center_freq22: '0' + center_freq23: '0' + center_freq24: '0' + center_freq25: '0' + center_freq26: '0' + center_freq27: '0' + center_freq28: '0' + center_freq29: '0' + center_freq3: '0' + center_freq30: '0' + center_freq31: '0' + center_freq4: '0' + center_freq5: '0' + center_freq6: '0' + center_freq7: '0' + center_freq8: '0' + center_freq9: '0' + clock_rate: '0.0' + clock_source0: '' + clock_source1: '' + clock_source2: '' + clock_source3: '' + clock_source4: '' + clock_source5: '' + clock_source6: '' + clock_source7: '' + comment: '' + dev_addr: '""' + dev_args: '""' + gain0: '75' + gain1: '0' + gain10: '0' + gain11: '0' + gain12: '0' + gain13: '0' + gain14: '0' + gain15: '0' + gain16: '0' + gain17: '0' + gain18: '0' + gain19: '0' + gain2: '0' + gain20: '0' + gain21: '0' + gain22: '0' + gain23: '0' + gain24: '0' + gain25: '0' + gain26: '0' + gain27: '0' + gain28: '0' + gain29: '0' + gain3: '0' + gain30: '0' + gain31: '0' + gain4: '0' + gain5: '0' + gain6: '0' + gain7: '0' + gain8: '0' + gain9: '0' + gain_type0: default + gain_type1: default + gain_type10: default + gain_type11: default + gain_type12: default + gain_type13: default + gain_type14: default + gain_type15: default + gain_type16: default + gain_type17: default + gain_type18: default + gain_type19: default + gain_type2: default + gain_type20: default + gain_type21: default + gain_type22: default + gain_type23: default + gain_type24: default + gain_type25: default + gain_type26: default + gain_type27: default + gain_type28: default + gain_type29: default + gain_type3: default + gain_type30: default + gain_type31: default + gain_type4: default + gain_type5: default + gain_type6: default + gain_type7: default + gain_type8: default + gain_type9: default + len_tag_name: '' + lo_export0: 'False' + lo_export1: 'False' + lo_export10: 'False' + lo_export11: 'False' + lo_export12: 'False' + lo_export13: 'False' + lo_export14: 'False' + lo_export15: 'False' + lo_export16: 'False' + lo_export17: 'False' + lo_export18: 'False' + lo_export19: 'False' + lo_export2: 'False' + lo_export20: 'False' + lo_export21: 'False' + lo_export22: 'False' + lo_export23: 'False' + lo_export24: 'False' + lo_export25: 'False' + lo_export26: 'False' + lo_export27: 'False' + lo_export28: 'False' + lo_export29: 'False' + lo_export3: 'False' + lo_export30: 'False' + lo_export31: 'False' + lo_export4: 'False' + lo_export5: 'False' + lo_export6: 'False' + lo_export7: 'False' + lo_export8: 'False' + lo_export9: 'False' + lo_source0: internal + lo_source1: internal + lo_source10: internal + lo_source11: internal + lo_source12: internal + lo_source13: internal + lo_source14: internal + lo_source15: internal + lo_source16: internal + lo_source17: internal + lo_source18: internal + lo_source19: internal + lo_source2: internal + lo_source20: internal + lo_source21: internal + lo_source22: internal + lo_source23: internal + lo_source24: internal + lo_source25: internal + lo_source26: internal + lo_source27: internal + lo_source28: internal + lo_source29: internal + lo_source3: internal + lo_source30: internal + lo_source31: internal + lo_source4: internal + lo_source5: internal + lo_source6: internal + lo_source7: internal + lo_source8: internal + lo_source9: internal + maxoutbuf: '0' + minoutbuf: '0' + nchan: '1' + num_mboards: '1' + otw: '' + samp_rate: samp_rate + sd_spec0: '' + sd_spec1: '' + sd_spec2: '' + sd_spec3: '' + sd_spec4: '' + sd_spec5: '' + sd_spec6: '' + sd_spec7: '' + show_lo_controls: 'False' + start_time: '-1.0' + stream_args: '' + stream_chans: '[]' + sync: sync + time_source0: '' + time_source1: '' + time_source2: '' + time_source3: '' + time_source4: '' + time_source5: '' + time_source6: '' + time_source7: '' + type: fc32 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1096, 340.0] + rotation: 0 + state: disabled + +connections: +- [blocks_message_strobe_0, strobe, blocks_message_debug_0, print_pdu] +- [blocks_message_strobe_0, strobe, nordic_nordic_tx_0, nordictap_in] +- [digital_gfsk_mod_0, '0', pfb_synthesizer_ccf_0, '0'] +- [nordic_nordic_tx_0, '0', digital_gfsk_mod_0, '0'] +- [pfb_synthesizer_ccf_0, '0', blocks_file_sink_0, '0'] +- [pfb_synthesizer_ccf_0, '0', iio_pluto_sink_0, '0'] +- [pfb_synthesizer_ccf_0, '0', qtgui_freq_sink_x_0, '0'] +- [pfb_synthesizer_ccf_0, '0', qtgui_time_sink_x_0, '0'] +- [pfb_synthesizer_ccf_0, '0', uhd_usrp_sink_0, '0'] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/tx_nrf_foo.grc b/examples/tx_nrf_foo.grc new file mode 100644 index 0000000..0240db3 --- /dev/null +++ b/examples/tx_nrf_foo.grc @@ -0,0 +1,747 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: tx_nrf_foo + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '1' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: address + id: variable + parameters: + comment: '' + value: '[0, 120, 2, 5, 8, 2, 0, 2, 231, 231, 231, 231, 231]' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 324] + rotation: 0 + state: enabled +- name: freq + id: variable + parameters: + comment: '' + value: 2520e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [128, 244] + rotation: 0 + state: enabled +- name: payload + id: variable + parameters: + comment: '' + value: '"22.75"' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [9, 244] + rotation: 0 + state: enabled +- name: pkt_vec + id: variable + parameters: + comment: '' + value: address + [ ord(x) for x in payload ] + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 404] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: 4e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: symbol_rate + id: variable + parameters: + comment: '' + value: 2e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 484] + rotation: 0 + state: enabled +- name: taps + id: variable_low_pass_filter_taps + parameters: + beta: '6.76' + comment: '' + cutoff_freq: (symbol_rate/2)*1.5 + gain: '1.0' + samp_rate: samp_rate + value: '' + width: 250e3 + win: window.WIN_HAMMING + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [184, 8] + rotation: 0 + state: enabled +- name: blocks_file_sink_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /home/herve/gr-nordic/examples/data_tr.bin + type: complex + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1168, 588.0] + rotation: 0 + state: disabled +- name: blocks_message_debug_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: '' + en_uvec: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [428, 24] + rotation: 0 + state: disabled +- name: blocks_message_strobe_0 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.init_u8vector( len(pkt_vec), pkt_vec) + period: '1000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [145, 165] + rotation: 0 + state: enabled +- name: digital_gfsk_mod_0 + id: digital_gfsk_mod + parameters: + affinity: '' + alias: '' + bt: '0.5' + comment: '' + do_unpack: 'True' + log: 'False' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_symbol: '2' + sensitivity: 1.5707/2 + verbose: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [504, 220.0] + rotation: 0 + state: enabled +- name: foo_burst_tagger_0 + id: foo_burst_tagger + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + mult: int(8*samp_rate/symbol_rate) + tag_name: pmt.intern("packet_len") + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [688, 228.0] + rotation: 0 + state: enabled +- name: iio_pluto_sink_0 + id: iio_pluto_sink + parameters: + affinity: '' + alias: '' + attenuation1: '10.0' + bandwidth: '2000000' + buffer_size: '0x200' + comment: '' + cyclic: 'False' + filter: '' + filter_source: '''Auto''' + fpass: '0' + frequency: int(freq) + fstop: '0' + len_tag_key: '' + samplerate: int(samp_rate) + type: fc32 + uri: ip:192.168.2.1 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1168, 148.0] + rotation: 0 + state: enabled +- name: nordic_nordic_tx_0 + id: nordic_nordic_tx + parameters: + affinity: '' + alias: '' + channel_count: '1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [328, 260.0] + rotation: 0 + state: enabled +- name: pfb_synthesizer_ccf_0 + id: pfb_synthesizer_ccf + parameters: + affinity: '' + alias: '' + bus_structure_sink: '[[0,],]' + ch_map: '[]' + comment: '' + connections: '1' + maxoutbuf: '0' + minoutbuf: '0' + numchans: '1' + samp_delay: '0' + taps: taps + twox: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [872, 212.0] + rotation: 0 + state: enabled +- name: qtgui_freq_sink_x_0 + id: qtgui_freq_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + average: '1.0' + axislabels: 'True' + bw: samp_rate + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + ctrlpanel: 'False' + fc: '0' + fftsize: '1024' + freqhalf: 'True' + grid: 'False' + gui_hint: '' + label: Relative Gain + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + norm_window: 'False' + showports: 'True' + tr_chan: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_tag: '""' + type: complex + units: dB + update_time: '0.01' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + wintype: window.WIN_BLACKMAN_hARRIS + ymax: '10' + ymin: '-140' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1168, 32.0] + rotation: 0 + state: disabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: '1024' + srate: samp_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"packet_len"' + type: complex + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1168, 492.0] + rotation: 0 + state: enabled +- name: uhd_usrp_sink_0 + id: uhd_usrp_sink + parameters: + affinity: '' + alias: '' + ant0: TX/RX + ant1: '' + ant10: '' + ant11: '' + ant12: '' + ant13: '' + ant14: '' + ant15: '' + ant16: '' + ant17: '' + ant18: '' + ant19: '' + ant2: '' + ant20: '' + ant21: '' + ant22: '' + ant23: '' + ant24: '' + ant25: '' + ant26: '' + ant27: '' + ant28: '' + ant29: '' + ant3: '' + ant30: '' + ant31: '' + ant4: '' + ant5: '' + ant6: '' + ant7: '' + ant8: '' + ant9: '' + bw0: 3e6 + bw1: '0' + bw10: '0' + bw11: '0' + bw12: '0' + bw13: '0' + bw14: '0' + bw15: '0' + bw16: '0' + bw17: '0' + bw18: '0' + bw19: '0' + bw2: '0' + bw20: '0' + bw21: '0' + bw22: '0' + bw23: '0' + bw24: '0' + bw25: '0' + bw26: '0' + bw27: '0' + bw28: '0' + bw29: '0' + bw3: '0' + bw30: '0' + bw31: '0' + bw4: '0' + bw5: '0' + bw6: '0' + bw7: '0' + bw8: '0' + bw9: '0' + center_freq0: freq + center_freq1: '0' + center_freq10: '0' + center_freq11: '0' + center_freq12: '0' + center_freq13: '0' + center_freq14: '0' + center_freq15: '0' + center_freq16: '0' + center_freq17: '0' + center_freq18: '0' + center_freq19: '0' + center_freq2: '0' + center_freq20: '0' + center_freq21: '0' + center_freq22: '0' + center_freq23: '0' + center_freq24: '0' + center_freq25: '0' + center_freq26: '0' + center_freq27: '0' + center_freq28: '0' + center_freq29: '0' + center_freq3: '0' + center_freq30: '0' + center_freq31: '0' + center_freq4: '0' + center_freq5: '0' + center_freq6: '0' + center_freq7: '0' + center_freq8: '0' + center_freq9: '0' + clock_rate: '0.0' + clock_source0: '' + clock_source1: '' + clock_source2: '' + clock_source3: '' + clock_source4: '' + clock_source5: '' + clock_source6: '' + clock_source7: '' + comment: '' + dev_addr: '""' + dev_args: '""' + gain0: '75' + gain1: '0' + gain10: '0' + gain11: '0' + gain12: '0' + gain13: '0' + gain14: '0' + gain15: '0' + gain16: '0' + gain17: '0' + gain18: '0' + gain19: '0' + gain2: '0' + gain20: '0' + gain21: '0' + gain22: '0' + gain23: '0' + gain24: '0' + gain25: '0' + gain26: '0' + gain27: '0' + gain28: '0' + gain29: '0' + gain3: '0' + gain30: '0' + gain31: '0' + gain4: '0' + gain5: '0' + gain6: '0' + gain7: '0' + gain8: '0' + gain9: '0' + gain_type0: default + gain_type1: default + gain_type10: default + gain_type11: default + gain_type12: default + gain_type13: default + gain_type14: default + gain_type15: default + gain_type16: default + gain_type17: default + gain_type18: default + gain_type19: default + gain_type2: default + gain_type20: default + gain_type21: default + gain_type22: default + gain_type23: default + gain_type24: default + gain_type25: default + gain_type26: default + gain_type27: default + gain_type28: default + gain_type29: default + gain_type3: default + gain_type30: default + gain_type31: default + gain_type4: default + gain_type5: default + gain_type6: default + gain_type7: default + gain_type8: default + gain_type9: default + len_tag_name: '' + lo_export0: 'False' + lo_export1: 'False' + lo_export10: 'False' + lo_export11: 'False' + lo_export12: 'False' + lo_export13: 'False' + lo_export14: 'False' + lo_export15: 'False' + lo_export16: 'False' + lo_export17: 'False' + lo_export18: 'False' + lo_export19: 'False' + lo_export2: 'False' + lo_export20: 'False' + lo_export21: 'False' + lo_export22: 'False' + lo_export23: 'False' + lo_export24: 'False' + lo_export25: 'False' + lo_export26: 'False' + lo_export27: 'False' + lo_export28: 'False' + lo_export29: 'False' + lo_export3: 'False' + lo_export30: 'False' + lo_export31: 'False' + lo_export4: 'False' + lo_export5: 'False' + lo_export6: 'False' + lo_export7: 'False' + lo_export8: 'False' + lo_export9: 'False' + lo_source0: internal + lo_source1: internal + lo_source10: internal + lo_source11: internal + lo_source12: internal + lo_source13: internal + lo_source14: internal + lo_source15: internal + lo_source16: internal + lo_source17: internal + lo_source18: internal + lo_source19: internal + lo_source2: internal + lo_source20: internal + lo_source21: internal + lo_source22: internal + lo_source23: internal + lo_source24: internal + lo_source25: internal + lo_source26: internal + lo_source27: internal + lo_source28: internal + lo_source29: internal + lo_source3: internal + lo_source30: internal + lo_source31: internal + lo_source4: internal + lo_source5: internal + lo_source6: internal + lo_source7: internal + lo_source8: internal + lo_source9: internal + maxoutbuf: '0' + minoutbuf: '0' + nchan: '1' + num_mboards: '1' + otw: '' + samp_rate: samp_rate + sd_spec0: '' + sd_spec1: '' + sd_spec2: '' + sd_spec3: '' + sd_spec4: '' + sd_spec5: '' + sd_spec6: '' + sd_spec7: '' + show_lo_controls: 'False' + start_time: '-1.0' + stream_args: '' + stream_chans: '[]' + sync: sync + time_source0: '' + time_source1: '' + time_source2: '' + time_source3: '' + time_source4: '' + time_source5: '' + time_source6: '' + time_source7: '' + type: fc32 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1168, 340.0] + rotation: 0 + state: disabled + +connections: +- [blocks_message_strobe_0, strobe, blocks_message_debug_0, print_pdu] +- [blocks_message_strobe_0, strobe, nordic_nordic_tx_0, nordictap_in] +- [digital_gfsk_mod_0, '0', foo_burst_tagger_0, '0'] +- [foo_burst_tagger_0, '0', pfb_synthesizer_ccf_0, '0'] +- [nordic_nordic_tx_0, '0', digital_gfsk_mod_0, '0'] +- [pfb_synthesizer_ccf_0, '0', blocks_file_sink_0, '0'] +- [pfb_synthesizer_ccf_0, '0', iio_pluto_sink_0, '0'] +- [pfb_synthesizer_ccf_0, '0', qtgui_freq_sink_x_0, '0'] +- [pfb_synthesizer_ccf_0, '0', qtgui_time_sink_x_0, '0'] +- [pfb_synthesizer_ccf_0, '0', uhd_usrp_sink_0, '0'] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/tx_nrf_python_block.grc b/examples/tx_nrf_python_block.grc new file mode 100644 index 0000000..5bd763a --- /dev/null +++ b/examples/tx_nrf_python_block.grc @@ -0,0 +1,799 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: tx_nrf_python_block + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: freq + id: variable + parameters: + comment: '' + value: 2520e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [16, 380.0] + rotation: 0 + state: enabled +- name: payload + id: variable + parameters: + comment: '' + value: '"24.25"' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 92.0] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: 4e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: symbol_rate + id: variable + parameters: + comment: '' + value: 2e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [0, 236] + rotation: 0 + state: enabled +- name: taps + id: variable_low_pass_filter_taps + parameters: + beta: '6.76' + comment: '' + cutoff_freq: (symbol_rate/2) + gain: '1.0' + samp_rate: samp_rate + value: '' + width: 250e3 + win: window.WIN_HAMMING + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [280, 8] + rotation: 0 + state: enabled +- name: blocks_char_to_float_0 + id: blocks_char_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + scale: '1' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [768, 500.0] + rotation: 0 + state: enabled +- name: blocks_file_sink_0 + id: blocks_file_sink + parameters: + affinity: '' + alias: '' + append: 'False' + comment: '' + file: /home/herve/nrf_gfsk.dat + type: complex + unbuffered: 'False' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [984, 60.0] + rotation: 0 + state: disabled +- name: blocks_message_debug_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: '' + en_uvec: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [336, 496.0] + rotation: 0 + state: disabled +- name: blocks_message_strobe_0 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.intern("trig") + period: '1000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [176, 172] + rotation: 0 + state: enabled +- name: blocks_repack_bits_bb_0 + id: blocks_repack_bits_bb + parameters: + affinity: '' + alias: '' + align_output: 'False' + comment: '' + endianness: gr.GR_MSB_FIRST + k: '8' + l: '1' + len_tag_key: '""' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [560, 492.0] + rotation: 0 + state: enabled +- name: digital_gfsk_mod_0 + id: digital_gfsk_mod + parameters: + affinity: '' + alias: '' + bt: '0.5' + comment: '' + do_unpack: 'True' + log: 'False' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_symbol: int(samp_rate/symbol_rate) + sensitivity: 1.5707/(samp_rate/symbol_rate) + verbose: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [576, 300.0] + rotation: 0 + state: enabled +- name: foo_burst_tagger_0 + id: foo_burst_tagger + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + mult: int(8*samp_rate/symbol_rate) + tag_name: pmt.intern("packet_len") + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [728, 196.0] + rotation: 0 + state: enabled +- name: iio_pluto_sink_0 + id: iio_pluto_sink + parameters: + affinity: '' + alias: '' + attenuation1: '10.0' + bandwidth: '2000000' + buffer_size: '0x200' + comment: '' + cyclic: 'False' + filter: '' + filter_source: '''Auto''' + fpass: '0' + frequency: int(freq) + fstop: '0' + len_tag_key: '' + samplerate: int(samp_rate) + type: fc32 + uri: ip:192.168.2.1 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1184, 388.0] + rotation: 0 + state: enabled +- name: nordic_nordic_tx_0 + id: nordic_nordic_tx + parameters: + affinity: '' + alias: '' + channel_count: '1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [384, 268.0] + rotation: 0 + state: enabled +- name: nordic_nordictap_transmitter_0 + id: nordic_nordictap_transmitter + parameters: + address: '''\xE7\xE7\xE7\xE7\xE7''' + affinity: '' + alias: '' + big_packet: '0' + channel_count: '120' + channel_index: '0' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + payload: payload + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [168, 332.0] + rotation: 0 + state: enabled +- name: pfb_synthesizer_ccf_0 + id: pfb_synthesizer_ccf + parameters: + affinity: '' + alias: '' + bus_structure_sink: '[[0,],]' + ch_map: '[]' + comment: '' + connections: '1' + maxoutbuf: '0' + minoutbuf: '0' + numchans: '1' + samp_delay: '0' + taps: taps + twox: 'False' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [904, 284.0] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: 1024*2 + srate: samp_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_TAG + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"packet_len"' + type: complex + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [984, 156] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: '1024' + srate: samp_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '"tx_sob"' + type: float + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [952, 484.0] + rotation: 0 + state: enabled +- name: uhd_usrp_sink_0 + id: uhd_usrp_sink + parameters: + affinity: '' + alias: '' + ant0: TX/RX + ant1: '' + ant10: '' + ant11: '' + ant12: '' + ant13: '' + ant14: '' + ant15: '' + ant16: '' + ant17: '' + ant18: '' + ant19: '' + ant2: '' + ant20: '' + ant21: '' + ant22: '' + ant23: '' + ant24: '' + ant25: '' + ant26: '' + ant27: '' + ant28: '' + ant29: '' + ant3: '' + ant30: '' + ant31: '' + ant4: '' + ant5: '' + ant6: '' + ant7: '' + ant8: '' + ant9: '' + bw0: '0' + bw1: '0' + bw10: '0' + bw11: '0' + bw12: '0' + bw13: '0' + bw14: '0' + bw15: '0' + bw16: '0' + bw17: '0' + bw18: '0' + bw19: '0' + bw2: '0' + bw20: '0' + bw21: '0' + bw22: '0' + bw23: '0' + bw24: '0' + bw25: '0' + bw26: '0' + bw27: '0' + bw28: '0' + bw29: '0' + bw3: '0' + bw30: '0' + bw31: '0' + bw4: '0' + bw5: '0' + bw6: '0' + bw7: '0' + bw8: '0' + bw9: '0' + center_freq0: 2485e6 + center_freq1: '0' + center_freq10: '0' + center_freq11: '0' + center_freq12: '0' + center_freq13: '0' + center_freq14: '0' + center_freq15: '0' + center_freq16: '0' + center_freq17: '0' + center_freq18: '0' + center_freq19: '0' + center_freq2: '0' + center_freq20: '0' + center_freq21: '0' + center_freq22: '0' + center_freq23: '0' + center_freq24: '0' + center_freq25: '0' + center_freq26: '0' + center_freq27: '0' + center_freq28: '0' + center_freq29: '0' + center_freq3: '0' + center_freq30: '0' + center_freq31: '0' + center_freq4: '0' + center_freq5: '0' + center_freq6: '0' + center_freq7: '0' + center_freq8: '0' + center_freq9: '0' + clock_rate: '0.0' + clock_source0: '' + clock_source1: '' + clock_source2: '' + clock_source3: '' + clock_source4: '' + clock_source5: '' + clock_source6: '' + clock_source7: '' + comment: '' + dev_addr: '""' + dev_args: '""' + gain0: '40' + gain1: '0' + gain10: '0' + gain11: '0' + gain12: '0' + gain13: '0' + gain14: '0' + gain15: '0' + gain16: '0' + gain17: '0' + gain18: '0' + gain19: '0' + gain2: '0' + gain20: '0' + gain21: '0' + gain22: '0' + gain23: '0' + gain24: '0' + gain25: '0' + gain26: '0' + gain27: '0' + gain28: '0' + gain29: '0' + gain3: '0' + gain30: '0' + gain31: '0' + gain4: '0' + gain5: '0' + gain6: '0' + gain7: '0' + gain8: '0' + gain9: '0' + gain_type0: default + gain_type1: default + gain_type10: default + gain_type11: default + gain_type12: default + gain_type13: default + gain_type14: default + gain_type15: default + gain_type16: default + gain_type17: default + gain_type18: default + gain_type19: default + gain_type2: default + gain_type20: default + gain_type21: default + gain_type22: default + gain_type23: default + gain_type24: default + gain_type25: default + gain_type26: default + gain_type27: default + gain_type28: default + gain_type29: default + gain_type3: default + gain_type30: default + gain_type31: default + gain_type4: default + gain_type5: default + gain_type6: default + gain_type7: default + gain_type8: default + gain_type9: default + len_tag_name: '' + lo_export0: 'False' + lo_export1: 'False' + lo_export10: 'False' + lo_export11: 'False' + lo_export12: 'False' + lo_export13: 'False' + lo_export14: 'False' + lo_export15: 'False' + lo_export16: 'False' + lo_export17: 'False' + lo_export18: 'False' + lo_export19: 'False' + lo_export2: 'False' + lo_export20: 'False' + lo_export21: 'False' + lo_export22: 'False' + lo_export23: 'False' + lo_export24: 'False' + lo_export25: 'False' + lo_export26: 'False' + lo_export27: 'False' + lo_export28: 'False' + lo_export29: 'False' + lo_export3: 'False' + lo_export30: 'False' + lo_export31: 'False' + lo_export4: 'False' + lo_export5: 'False' + lo_export6: 'False' + lo_export7: 'False' + lo_export8: 'False' + lo_export9: 'False' + lo_source0: internal + lo_source1: internal + lo_source10: internal + lo_source11: internal + lo_source12: internal + lo_source13: internal + lo_source14: internal + lo_source15: internal + lo_source16: internal + lo_source17: internal + lo_source18: internal + lo_source19: internal + lo_source2: internal + lo_source20: internal + lo_source21: internal + lo_source22: internal + lo_source23: internal + lo_source24: internal + lo_source25: internal + lo_source26: internal + lo_source27: internal + lo_source28: internal + lo_source29: internal + lo_source3: internal + lo_source30: internal + lo_source31: internal + lo_source4: internal + lo_source5: internal + lo_source6: internal + lo_source7: internal + lo_source8: internal + lo_source9: internal + maxoutbuf: '0' + minoutbuf: '0' + nchan: '1' + num_mboards: '1' + otw: '' + samp_rate: samp_rate + sd_spec0: '' + sd_spec1: '' + sd_spec2: '' + sd_spec3: '' + sd_spec4: '' + sd_spec5: '' + sd_spec6: '' + sd_spec7: '' + show_lo_controls: 'False' + start_time: '-1.0' + stream_args: '' + stream_chans: '[]' + sync: sync + time_source0: '' + time_source1: '' + time_source2: '' + time_source3: '' + time_source4: '' + time_source5: '' + time_source6: '' + time_source7: '' + type: fc32 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1184, 252.0] + rotation: 0 + state: disabled + +connections: +- [blocks_char_to_float_0, '0', qtgui_time_sink_x_0_0, '0'] +- [blocks_message_strobe_0, strobe, nordic_nordictap_transmitter_0, trig] +- [blocks_repack_bits_bb_0, '0', blocks_char_to_float_0, '0'] +- [digital_gfsk_mod_0, '0', foo_burst_tagger_0, '0'] +- [foo_burst_tagger_0, '0', blocks_file_sink_0, '0'] +- [foo_burst_tagger_0, '0', pfb_synthesizer_ccf_0, '0'] +- [foo_burst_tagger_0, '0', qtgui_time_sink_x_0, '0'] +- [nordic_nordic_tx_0, '0', blocks_repack_bits_bb_0, '0'] +- [nordic_nordic_tx_0, '0', digital_gfsk_mod_0, '0'] +- [nordic_nordictap_transmitter_0, nordictap_out, blocks_message_debug_0, print_pdu] +- [nordic_nordictap_transmitter_0, nordictap_out, nordic_nordic_tx_0, nordictap_in] +- [pfb_synthesizer_ccf_0, '0', iio_pluto_sink_0, '0'] +- [pfb_synthesizer_ccf_0, '0', uhd_usrp_sink_0, '0'] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/examples/tx_rx_loop.grc b/examples/tx_rx_loop.grc new file mode 100644 index 0000000..fd9cf52 --- /dev/null +++ b/examples/tx_rx_loop.grc @@ -0,0 +1,367 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: tx_rx_loop + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: '' + window_size: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 8] + rotation: 0 + state: enabled + +blocks: +- name: address + id: variable + parameters: + comment: '' + value: '[0, 120, 2, 5, 8, 0, 0, 2, 231, 231, 231, 231, 231]' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 316] + rotation: 0 + state: enabled +- name: payload + id: variable + parameters: + comment: '' + value: '"22.75"' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [12, 236] + rotation: 0 + state: enabled +- name: pkt_vec + id: variable + parameters: + comment: '' + value: address + [ ord(x) for x in payload ] + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 396] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: 2e6 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 160] + rotation: 0 + state: enabled +- name: blocks_char_to_float_0 + id: blocks_char_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + scale: '1' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [768, 316] + rotation: 0 + state: enabled +- name: blocks_ctrlport_monitor_performance_0 + id: blocks_ctrlport_monitor_performance + parameters: + alias: '' + comment: '' + en: 'True' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [488, 68.0] + rotation: 0 + state: disabled +- name: blocks_message_strobe_0 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.init_u8vector( len(pkt_vec), pkt_vec) + period: '2000' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [111, 88] + rotation: 0 + state: disabled +- name: blocks_message_strobe_1 + id: blocks_message_strobe + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + msg: pmt.intern("trig") + period: '500' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [73, 502] + rotation: 0 + state: true +- name: blocks_repack_bits_bb_0 + id: blocks_repack_bits_bb + parameters: + affinity: '' + alias: '' + align_output: 'False' + comment: '' + endianness: gr.GR_MSB_FIRST + k: '8' + l: '1' + len_tag_key: '""' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [504, 220.0] + rotation: 0 + state: enabled +- name: blocks_throttle_0 + id: blocks_throttle + parameters: + affinity: '' + alias: '' + comment: '' + ignoretag: 'True' + maxoutbuf: '0' + minoutbuf: '0' + samples_per_second: samp_rate + type: byte + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [737, 191] + rotation: 0 + state: enabled +- name: nordic_nordic_rx_0 + id: nordic_nordic_rx + parameters: + address_length: '5' + address_match: '' + affinity: '' + alias: '' + channel: '120' + comment: '' + crc_length: '2' + data_rate: '2' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [932, 168] + rotation: 0 + state: enabled +- name: nordic_nordic_tx_0 + id: nordic_nordic_tx + parameters: + affinity: '' + alias: '' + channel_count: '1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [288, 228.0] + rotation: 0 + state: enabled +- name: nordic_nordictap_printer_0 + id: nordic_nordictap_printer + parameters: + affinity: '' + alias: '' + comment: '' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1289, 195] + rotation: 0 + state: enabled +- name: nordic_nordictap_transmitter_0 + id: nordic_nordictap_transmitter + parameters: + address: '''\xE7\xE7\xE7\xE7\xE7''' + affinity: '' + alias: '' + big_packet: '0' + channel_count: '120' + channel_index: '0' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + payload: payload + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [280, 476] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'True' + grid: 'False' + gui_hint: '' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: '1024' + srate: samp_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '""' + type: float + update_time: '0.10' + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [920, 300] + rotation: 0 + state: enabled + +connections: +- [blocks_char_to_float_0, '0', qtgui_time_sink_x_0, '0'] +- [blocks_message_strobe_0, strobe, nordic_nordic_tx_0, nordictap_in] +- [blocks_message_strobe_1, strobe, nordic_nordictap_transmitter_0, trig] +- [blocks_repack_bits_bb_0, '0', blocks_char_to_float_0, '0'] +- [blocks_repack_bits_bb_0, '0', blocks_throttle_0, '0'] +- [blocks_throttle_0, '0', nordic_nordic_rx_0, '0'] +- [nordic_nordic_rx_0, nordictap_out, nordic_nordictap_printer_0, nordictap_in] +- [nordic_nordic_tx_0, '0', blocks_repack_bits_bb_0, '0'] +- [nordic_nordictap_transmitter_0, nordictap_out, nordic_nordic_tx_0, nordictap_in] + +metadata: + file_format: 1 + grc_version: v3.11.0.0git-215-g9a698313 diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index b456b1a..404c544 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -1,18 +1,15 @@ -# Copyright (C) 2016 Bastille Networks +# Copyright 2011 Free Software Foundation, Inc. # -# 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 3 of the License, or -# (at your option) any later version. +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . + install(FILES - nordic_nordic_rx.xml - nordic_nordic_tx.xml DESTINATION share/gnuradio/grc/blocks + nordic_nordictap_printer.block.yml + nordic_nordictap_transmitter.block.yml + nordic_nordic_tx.block.yml + nordic_nordic_rx.block.yml + DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/nordic_nordic_rx.block.yml b/grc/nordic_nordic_rx.block.yml new file mode 100644 index 0000000..76e141e --- /dev/null +++ b/grc/nordic_nordic_rx.block.yml @@ -0,0 +1,75 @@ +id: nordic_nordic_rx +label: nordic rx +category: '[Nordic]' +templates: + imports: import nordic + make: nordic.nordic_rx(${channel}, ${address_length}, ${crc_length}, ${data_rate}, ${address_match}) +parameters: +- id: channel + label: Channel + default: '0' + dtype: int +- id: address_length + label: Address Length + default: '5' + dtype: int +- id: crc_length + label: CRC Length + default: '2' + dtype: int +- id: data_rate + label: Data Rate + default: '0' + dtype: enum + options: ['0', '1', '2'] + option_labels: ['250kbps', '1mbps', '2mbps'] + option_attributes: + dtype: [int, int, int] +- id: address_match + label: Address Match List + default: '' + dtype: string +inputs: +- label: in + domain: stream + dtype: byte +outputs: +- label: nordictap_out + domain: message +documentation: |- + Nordic receiver: + Channel: + The channel argument is mainly informational and tags data packets with + this value for downstream usage (e.g. Wireshark). + + Address_length: + Specifies how many bytes within the packet header are for the address. The + Nordic protocol specifies this can be 3, 4, or 5 bytes long. The most + common (and default value) is 5. + + Crc_length: + Specifies how many CRC bytes are used within the packet. This implementation + only properly supports 16-bit CRC for now. Most (all?) NRF implementations + use 16-bit CRC. The most common (and default value) is 2. + + Data_rate: + The data rate argument is mainly for informational purposes and tags data + packets for downstream usage (e.g. Wireshark). + + Address_match: + An optional argument which indicates a list of addresses to search for + instead of solely relying on CRC and preamble to identify packets. This is + useful if the addresses are known and you would like to know if packets are + being dropped due to CRC errors. The input format for this argument is a + comma separated list of addresses in hex form. Addresses need not be fully + specified, the match will identify packets based on the length of address + provided. Use caution, a very short match (1-2 bytes) will likely match + noise and cause very verbose output. + + Usage example: + Address_match: E4A0F1EE,E4A0F1EF,BA87FE + Will match addresses starting with any of the following: + 0xE4 0xA0 0xF1 0xEE + 0xE4 0xA0 0xF1 0xEF + 0xBA 0x87 0xFE +file_format: 1 diff --git a/grc/nordic_nordic_rx.xml b/grc/nordic_nordic_rx.xml deleted file mode 100644 index d7f3b3e..0000000 --- a/grc/nordic_nordic_rx.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - nordic_rx - nordic_nordic_rx - nordic - import nordic - nordic.nordic_rx() - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/nordic_nordic_tx.block.yml b/grc/nordic_nordic_tx.block.yml new file mode 100644 index 0000000..7fae939 --- /dev/null +++ b/grc/nordic_nordic_tx.block.yml @@ -0,0 +1,20 @@ +id: nordic_nordic_tx +label: nordic tx +category: '[Nordic]' +templates: + imports: import nordic + make: nordic.nordic_tx(${channel_count}) +parameters: +- id: channel_count + label: Channel_count + default: '1' + dtype: int +inputs: +- label: nordictap_in + domain: message +outputs: +- label: out + domain: stream + dtype: byte + multiplicity: ${channel_count} +file_format: 1 diff --git a/grc/nordic_nordic_tx.xml b/grc/nordic_nordic_tx.xml deleted file mode 100644 index ef783c0..0000000 --- a/grc/nordic_nordic_tx.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - nordic_tx - nordic_nordic_tx - nordic - import nordic - nordic.nordic_tx() - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/nordic_nordictap_printer.block.yml b/grc/nordic_nordictap_printer.block.yml new file mode 100644 index 0000000..c944218 --- /dev/null +++ b/grc/nordic_nordictap_printer.block.yml @@ -0,0 +1,10 @@ +id: nordic_nordictap_printer +label: nordictap_printer +category: '[Nordic]' +templates: + imports: import nordic + make: nordic.nordictap_printer() +inputs: +- label: nordictap_in + domain: message +file_format: 1 diff --git a/grc/nordic_nordictap_transmitter.block.yml b/grc/nordic_nordictap_transmitter.block.yml new file mode 100644 index 0000000..58ecb21 --- /dev/null +++ b/grc/nordic_nordictap_transmitter.block.yml @@ -0,0 +1,38 @@ +id: nordic_nordictap_transmitter +label: nordictap_transmitter +category: '[Nordic]' +templates: + imports: import nordic + make: nordic.nordictap_transmitter(${channel_count}, ${address}, ${payload}, ${channel_index}, ${sequence_number}, ${big_packet}) +parameters: +- id: channel_count + label: Channel Count + default: '4' + dtype: int +- id: address + label: Address + default: '\x55\x55\x55\x55\x55' + dtype: string +- id: payload + label: Payload + default: '\xAA\xAA\xAA\xAA\xAA' + dtype: string +- id: channel_index + label: Channel Index + default: '0' + dtype: int +- id: sequence_number + label: Sequence Number + default: '0' + dtype: int + id: big_packet + label: Big Packet + default: '0' + dtype: int +inputs: +- label: trig + domain: message +outputs: +- label: nordictap_out + domain: message +file_format: 1 diff --git a/include/nordic/CMakeLists.txt b/include/nordic/CMakeLists.txt index 46f73f9..909ffc5 100644 --- a/include/nordic/CMakeLists.txt +++ b/include/nordic/CMakeLists.txt @@ -1,24 +1,17 @@ -# Copyright (C) 2016 Bastille Networks +# Copyright 2011,2012 Free Software Foundation, Inc. # -# 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 3 of the License, or -# (at your option) any later version. +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . ######################################################################## # Install public header files ######################################################################## install(FILES api.h + nordic_tx.h nordic_rx.h - nordic_tx.h DESTINATION include/nordic + DESTINATION include/nordic ) - diff --git a/include/nordic/api.h b/include/nordic/api.h index a3d963e..51b21e4 100644 --- a/include/nordic/api.h +++ b/include/nordic/api.h @@ -1,19 +1,12 @@ /* - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -*/ + * Copyright 2011 Free Software Foundation, Inc. + * + * This file was generated by gr_modtool, a tool from the GNU Radio framework + * This file is a part of gr-nordic + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ #ifndef INCLUDED_NORDIC_API_H #define INCLUDED_NORDIC_API_H @@ -21,9 +14,9 @@ #include #ifdef gnuradio_nordic_EXPORTS -# define NORDIC_API __GR_ATTR_EXPORT +#define NORDIC_API __GR_ATTR_EXPORT #else -# define NORDIC_API __GR_ATTR_IMPORT +#define NORDIC_API __GR_ATTR_IMPORT #endif #endif /* INCLUDED_NORDIC_API_H */ diff --git a/include/nordic/nordic_rx.h b/include/nordic/nordic_rx.h index a105a38..c2b23f1 100644 --- a/include/nordic/nordic_rx.h +++ b/include/nordic/nordic_rx.h @@ -36,7 +36,7 @@ namespace gr { class NORDIC_API nordic_rx : virtual public gr::sync_block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * \brief Return a shared_ptr to a new instance of nordic::nordic_rx. @@ -46,10 +46,11 @@ namespace gr { * class. nordic::nordic_rx::make is the public interface for * creating new instances. */ - static sptr make(uint8_t channel=0, - uint8_t address_length=5, - uint8_t crc_length=2, - uint8_t data_rate=0); + static sptr make(const uint8_t channel=0, + const uint8_t address_length=5, + const uint8_t crc_length=2, + const uint8_t data_rate=0, + const std::string &address_match=""); // Channel getter/setter virtual uint8_t get_channel()=0; diff --git a/include/nordic/nordic_tx.h b/include/nordic/nordic_tx.h index c35291c..ece642e 100644 --- a/include/nordic/nordic_tx.h +++ b/include/nordic/nordic_tx.h @@ -36,7 +36,7 @@ namespace gr { class NORDIC_API nordic_tx : virtual public gr::sync_block { public: - typedef boost::shared_ptr sptr; + typedef std::shared_ptr sptr; /*! * \brief Return a shared_ptr to a new instance of nordic::nordic_tx. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d3a800a..b06d43a 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,39 +1,35 @@ -# Copyright (C) 2016 Bastille Networks +# Copyright 2011,2012,2016,2018,2019 Free Software Foundation, Inc. # -# 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 3 of the License, or -# (at your option) any later version. +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . ######################################################################## # Setup library ######################################################################## include(GrPlatform) #define LIB_SUFFIX -include_directories(${Boost_INCLUDE_DIR}) -link_directories(${Boost_LIBRARY_DIRS}) list(APPEND nordic_sources - nordic_rx_impl.cc - bit_shifting_byte_vector.cc nordic_tx_impl.cc - enhanced_shockburst_packet.cc ) + bit_shifting_byte_vector.cc + nordic_rx_impl.cc + enhanced_shockburst_packet.cc +) set(nordic_sources "${nordic_sources}" PARENT_SCOPE) if(NOT nordic_sources) - MESSAGE(STATUS "No C++ sources... skipping lib/") - return() + MESSAGE(STATUS "No C++ sources... skipping lib/") + return() endif(NOT nordic_sources) add_library(gnuradio-nordic SHARED ${nordic_sources}) -target_link_libraries(gnuradio-nordic ${Boost_LIBRARIES} ${GNURADIO_ALL_LIBRARIES}) +target_link_libraries(gnuradio-nordic gnuradio::gnuradio-runtime) +target_include_directories(gnuradio-nordic + PUBLIC $ + PUBLIC $ + ) set_target_properties(gnuradio-nordic PROPERTIES DEFINE_SYMBOL "gnuradio_nordic_EXPORTS") if(APPLE) @@ -45,32 +41,35 @@ endif(APPLE) ######################################################################## # Install built library files ######################################################################## -install(TARGETS gnuradio-nordic - LIBRARY DESTINATION lib${LIB_SUFFIX} # .so/.dylib file - ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file - RUNTIME DESTINATION bin # .dll file -) +include(GrMiscUtils) +GR_LIBRARY_FOO(gnuradio-nordic) + +######################################################################## +# Print summary +######################################################################## +message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") +message(STATUS "Building for version: ${VERSION} / ${LIBVER}") ######################################################################## # Build and register unit test ######################################################################## include(GrTest) -include_directories(${CPPUNIT_INCLUDE_DIRS}) - +# If your unit tests require special include paths, add them here +#include_directories() +# List all files that contain Boost.UTF unit tests here list(APPEND test_nordic_sources - ${CMAKE_CURRENT_SOURCE_DIR}/test_nordic.cc - ${CMAKE_CURRENT_SOURCE_DIR}/qa_nordic.cc ) +# Anything we need to link to for the unit tests go here +list(APPEND GR_TEST_TARGET_DEPS gnuradio-nordic) -add_executable(test-nordic ${test_nordic_sources}) +if(NOT test_nordic_sources) + MESSAGE(STATUS "No C++ unit tests... skipping") + return() +endif(NOT test_nordic_sources) -target_link_libraries( - test-nordic - ${GNURADIO_RUNTIME_LIBRARIES} - ${Boost_LIBRARIES} - ${CPPUNIT_LIBRARIES} - gnuradio-nordic -) - -GR_ADD_TEST(test_nordic test-nordic) +foreach(qa_file ${test_nordic_sources}) + GR_ADD_CPP_TEST("nordic_${qa_file}" + ${CMAKE_CURRENT_SOURCE_DIR}/${qa_file} + ) +endforeach(qa_file) diff --git a/lib/enhanced_shockburst_packet.cc b/lib/enhanced_shockburst_packet.cc index 1f3efe7..7af5c95 100644 --- a/lib/enhanced_shockburst_packet.cc +++ b/lib/enhanced_shockburst_packet.cc @@ -26,6 +26,7 @@ #include "enhanced_shockburst_packet.h" enhanced_shockburst_packet::enhanced_shockburst_packet(uint8_t address_length, + uint8_t big_packet, uint8_t payload_length, uint8_t sequence_number, uint8_t no_ack, @@ -34,6 +35,7 @@ enhanced_shockburst_packet::enhanced_shockburst_packet(uint8_t address_length, uint8_t * payload ) : m_address_length(address_length), + m_big_packet(big_packet), m_payload_length(payload_length), m_sequence_number(sequence_number), m_no_ack(no_ack), @@ -57,6 +59,8 @@ enhanced_shockburst_packet::enhanced_shockburst_packet(uint8_t address_length, m_packet_length_bits = blen*8; m_packet_bytes = new uint8_t[blen]; + memset(m_packet_bytes, 0, blen); + // Preamble if((address[0] & 0x80) == 0x80) m_packet_bytes[0] = 0xAA; else m_packet_bytes[0] = 0x55; @@ -64,26 +68,41 @@ enhanced_shockburst_packet::enhanced_shockburst_packet(uint8_t address_length, // Address memcpy(&m_packet_bytes[1], address, m_address_length); + uint8_t alignment_offset; // PCF - m_packet_bytes[1 + m_address_length] = (m_payload_length & 0x3F) << 2; - m_packet_bytes[1 + m_address_length] |= (m_sequence_number & 0x3); - m_packet_bytes[2 + m_address_length] = m_no_ack << 7; + if (!big_packet) + { + m_packet_bytes[1 + m_address_length] = (m_payload_length & 0x3F) << 2; + m_packet_bytes[1 + m_address_length] |= (m_sequence_number & 0x3); + m_packet_bytes[2 + m_address_length] = m_no_ack << 7; + alignment_offset = 1; + } + else { // 8-bits for payload length when NRF_ESB_MAX_PAYLOAD_LENGTH > 32 + m_packet_bytes[1 + m_address_length] = m_payload_length; + m_packet_bytes[2 + m_address_length] = (m_sequence_number & 0x3) << 6; + m_packet_bytes[2 + m_address_length] |= m_no_ack << 5; + alignment_offset = 3; + } // Payload for(int b = 0; b < m_payload_length; b++) { - m_packet_bytes[2 + m_address_length + b] |= (payload[b] >> 1); - m_packet_bytes[3 + m_address_length + b] |= (payload[b] << 7); + m_packet_bytes[2 + m_address_length + b] |= (payload[b] >> alignment_offset); + m_packet_bytes[3 + m_address_length + b] |= (payload[b] << (8 - alignment_offset)); } // Calculate the CRC uint16_t crc = 0xFFFF; - for(int b = 1; b < 7 + m_payload_length; b++) crc = crc_update(crc, m_packet_bytes[b]); - crc = crc_update(crc, m_packet_bytes[7 + m_payload_length] & 0x80, 1); + for(int b = 1; b < 7 + m_payload_length; b++) + crc = crc_update(crc, m_packet_bytes[b]); + + crc = crc_update(crc, m_packet_bytes[7 + m_payload_length] & (0xFF << (8 - alignment_offset)), alignment_offset); + memcpy(m_crc, &crc, m_crc_length); - m_packet_bytes[2 + m_address_length + m_payload_length] |= ((crc >> 9) & 0xFF); - m_packet_bytes[3 + m_address_length + m_payload_length] |= ((crc >> 1) & 0xFF); - m_packet_bytes[4 + m_address_length + m_payload_length] |= ((crc << 7) & 0x80); + + m_packet_bytes[2 + m_address_length + m_payload_length] |= ((crc >> (8 + alignment_offset)) & 0xFF); + m_packet_bytes[3 + m_address_length + m_payload_length] |= ((crc >> alignment_offset) & 0xFF); + m_packet_bytes[4 + m_address_length + m_payload_length] |= ((crc << (8 - alignment_offset)) & (0xFF << (8 - alignment_offset))); } // Destructur @@ -94,16 +113,59 @@ enhanced_shockburst_packet::~enhanced_shockburst_packet() delete[] m_crc; } -// Attempt to parse a packet from some incoming bytes +// Attempt to parse a packet from some incoming bytes using small packet protocol first, then large packet protocol bool enhanced_shockburst_packet::try_parse(const uint8_t * bytes, - const uint8_t * bytes_shifted, + const uint8_t ** addresses, + const uint8_t *address_match_len, uint8_t address_length, uint8_t crc_length, enhanced_shockburst_packet *& packet) +{ + if (!enhanced_shockburst_packet::_try_parse(bytes, + addresses, + address_match_len, + address_length, + crc_length, + packet, + false)) + { + return enhanced_shockburst_packet::_try_parse(bytes, + addresses, + address_match_len, + address_length, + crc_length, + packet, + true); + } + + return true; +} +bool enhanced_shockburst_packet::_try_parse(const uint8_t * bytes, + const uint8_t ** addresses, + const uint8_t * address_match_len, + uint8_t address_length, + uint8_t crc_length, + enhanced_shockburst_packet * &packet, + bool big_packet) { // Read the payload length - uint8_t payload_length = bytes[6] >> 2; - if(payload_length > 32) return false; + uint8_t payload_length; + uint8_t alignment_offset; + + if (big_packet) { + payload_length = bytes[6]; + alignment_offset = 3; + + if (payload_length > 252) + return false; + } + else { + payload_length = bytes[6] >> 2; + alignment_offset = 1; + + if (payload_length > 32) + return false; + } // Read the address uint8_t * address = new uint8_t[address_length]; @@ -111,32 +173,84 @@ bool enhanced_shockburst_packet::try_parse(const uint8_t * bytes, // Read the given CRC uint16_t crc_given; - memcpy(&crc_given, &bytes_shifted[8 + payload_length], 2); + crc_given = bytes[2 + address_length + payload_length] & (0xFF >> alignment_offset); + crc_given <<= 8; + crc_given |= bytes[3 + address_length + payload_length]; + crc_given <<= alignment_offset; + crc_given |= bytes[4 + address_length + payload_length] >> (8 - alignment_offset) ; + crc_given = htons(crc_given); + // Calculate the CRC uint16_t crc = 0xFFFF; for(int b = 1; b < 7 + payload_length; b++) crc = crc_update(crc, bytes[b]); - crc = crc_update(crc, bytes[7 + payload_length] & 0x80, 1); + crc = crc_update(crc, bytes[7 + payload_length] & (0xFF << (8 - alignment_offset)), alignment_offset); crc = htons(crc); // Validate the CRC if(memcmp(&crc, &crc_given, 2) != 0) { - delete[] address; - return false; + // If we've been provided a list of possible addresses, look for those so we can report CRC errors + // Only check this if we're in the big_packet round of parsing, otherwise will report valid BP + // packets during the non-BP parsing round. + if (address_match_len && big_packet) + { + const uint8_t* cur_match_len = address_match_len; + const uint8_t** cur_addr_match = addresses; + + while (*cur_match_len) + { + if (memcmp(address, *cur_addr_match, *cur_match_len) == 0) + { + printf("Possible NRF packet with CRC error (given: %04X, calculated: %04X, length: %d, address: ", + crc_given, crc, payload_length); + for (int i = 0; i < address_length; i++) printf("%02X",address[i]); + printf(")\n"); + break; + } + cur_match_len++; + cur_addr_match++; + } + } + + delete[] address; + return false; } // Read the sequence number and no-ACK bit - uint8_t seq = bytes[6] & 0x3; - uint8_t no_ack = bytes[7] >> 7; + uint8_t seq; + uint8_t no_ack; + + if (big_packet) + { + seq = bytes[7] >> 6; + no_ack = (bytes[7] >> 5) & 0x01; + } + else { + seq = bytes[6] & 0x3; + no_ack = bytes[7] >> 7; + } // Read the payload - uint8_t payload[32]; - memcpy(payload, &bytes_shifted[8], payload_length); + uint8_t payload[252]; - // Update the fields - packet = new enhanced_shockburst_packet(address_length, payload_length, seq, no_ack, crc_length, address, payload); + // Payload + for (int b = 0; b < payload_length; b++) + { + payload[b] = bytes[7 + b] << alignment_offset; + payload[b] |= bytes[8 + b] >> (8 - alignment_offset); + } + // Update the fields + packet = new enhanced_shockburst_packet(address_length, + big_packet, + payload_length, + seq, + no_ack, + crc_length, + address, + payload); + // Cleanup delete[] address; @@ -160,7 +274,10 @@ void enhanced_shockburst_packet::print() printf("Bytes: "); for(int x = 0; x < m_packet_length_bytes; x++) printf("%02X ", m_packet_bytes[x]); - printf("\n"); + printf("BP: %d\n", m_big_packet); + printf("ACK: %d\n", m_no_ack); + + printf("\n"); printf("\n"); } @@ -175,4 +292,4 @@ uint16_t enhanced_shockburst_packet::crc_update (uint16_t crc, uint8_t data, uin else crc <<= 1; } return crc; -} \ No newline at end of file +} diff --git a/lib/enhanced_shockburst_packet.h b/lib/enhanced_shockburst_packet.h index 3db60fc..4018785 100644 --- a/lib/enhanced_shockburst_packet.h +++ b/lib/enhanced_shockburst_packet.h @@ -30,6 +30,7 @@ class enhanced_shockburst_packet // Constructor enhanced_shockburst_packet(uint8_t address_length, + uint8_t big_packet, uint8_t payload_length, uint8_t sequence_number, uint8_t no_ack, @@ -43,11 +44,20 @@ class enhanced_shockburst_packet // Attempt to parse a packet from some incoming bytes static bool try_parse(const uint8_t * bytes, - const uint8_t * bytes_shifted, + const uint8_t ** addresses, + const uint8_t * address_match_len, uint8_t address_length, uint8_t crc_length, enhanced_shockburst_packet *& packet); + static bool _try_parse(const uint8_t* bytes, + const uint8_t** addresses, + const uint8_t* address_match_len, + uint8_t address_length, + uint8_t crc_length, + enhanced_shockburst_packet*& packet, + bool big_packet); + // Process a crc byte (or partial byte) static uint16_t crc_update (uint16_t crc, uint8_t data, uint8_t bits=8); @@ -56,6 +66,7 @@ class enhanced_shockburst_packet // Getters const uint8_t payload_length() { return m_payload_length; } + //const uint8_t address_length() { return m_address_length; } const uint8_t bytes_length() { return m_packet_length_bytes; } const uint8_t sequence_number() { return m_sequence_number; } const uint8_t no_ack() { return m_no_ack; } @@ -63,12 +74,16 @@ class enhanced_shockburst_packet const uint8_t * payload() { return m_payload; } const uint8_t * crc() { return m_crc; } const uint8_t * bytes() { return m_packet_bytes; } + const uint8_t big_packet() { return m_big_packet; } private: // Address length uint8_t m_address_length; + // Big packet protocol + bool m_big_packet; + // Payload length uint8_t m_payload_length; @@ -99,4 +114,4 @@ class enhanced_shockburst_packet } __attribute__((packed)); -#endif // ENHANCED_SHOCKBURST_PACKET_H \ No newline at end of file +#endif // ENHANCED_SHOCKBURST_PACKET_H diff --git a/lib/nordic_rx_impl.cc b/lib/nordic_rx_impl.cc index 2cb45c5..56706e6 100644 --- a/lib/nordic_rx_impl.cc +++ b/lib/nordic_rx_impl.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include "nordic_rx_impl.h" #include "nordictap.h" @@ -32,31 +33,74 @@ namespace gr { namespace nordic { nordic_rx::sptr - nordic_rx::make(uint8_t channel, - uint8_t address_length, - uint8_t crc_length, - uint8_t data_rate) + nordic_rx::make(const uint8_t channel, + const uint8_t address_length, + const uint8_t crc_length, + const uint8_t data_rate, + const std::string &address_match) { return gnuradio::get_initial_sptr - (new nordic_rx_impl(channel, address_length, crc_length, data_rate)); + (new nordic_rx_impl(channel, address_length, crc_length, data_rate, address_match)); } /* * The private constructor */ - nordic_rx_impl::nordic_rx_impl(uint8_t channel, - uint8_t address_length, - uint8_t crc_length, - uint8_t data_rate) + nordic_rx_impl::nordic_rx_impl(const uint8_t channel, + const uint8_t address_length, + const uint8_t crc_length, + const uint8_t data_rate, + const std::string &address_match) : gr::sync_block("nordic_rx", gr::io_signature::make(1, 1, sizeof(uint8_t)), gr::io_signature::make(0, 0, 0)), - m_decoded_bits_bytes(42*8 /* buffer sufficient for max ESB frame length */), + m_decoded_bits_bytes(262*8 /* buffer sufficient for max ESB frame length */), // ESB payload can be up to 252 bytes plus header+crc m_crc_length(crc_length), m_address_length(address_length), m_channel(channel), - m_data_rate(data_rate) + m_data_rate(data_rate), + m_addresses(NULL), + m_address_match_len(NULL) { + // Parse list of addresses + if (!address_match.empty()) + { + std::string match_buffer = address_match; + int n_addresses = std::count(match_buffer.begin(), match_buffer.end(), ',') + 1; + + m_addresses = new uint8_t *[n_addresses]; + for (int i = 0; i < n_addresses; i++) + m_addresses[i] = new uint8_t[address_length]; + + m_address_match_len = new uint8_t[n_addresses + 1]; + m_address_match_len[n_addresses] = 0; + + int cur_address = 0; + size_t e = 0; + + std::string::iterator s = match_buffer.begin(); + do + { + e = match_buffer.find(',', s - match_buffer.begin()); + + if (e == std::string::npos) + e = match_buffer.end() - match_buffer.begin(); + + m_address_match_len[cur_address] = std::min((e - (s - match_buffer.begin())) / 2, (size_t) address_length); + + try { + std::string hex_address = boost::algorithm::unhex(match_buffer.substr(s - match_buffer.begin(), m_address_match_len[cur_address] * 2)); + memcpy(m_addresses[cur_address], hex_address.c_str(), m_address_match_len[cur_address]); + cur_address++; + } + catch (boost::algorithm::hex_decode_error hde) { + printf("Warning, invalid hex data provided as address match list to nordic_rx\n"); + } + + s += (e - (s - match_buffer.begin())) + 1; + } while (s < match_buffer.end()); + } + message_port_register_out(pmt::mp("nordictap_out")); } @@ -65,7 +109,15 @@ namespace gr { */ nordic_rx_impl::~nordic_rx_impl() { - + if (m_addresses) + { + for (int i = 0; i < 1; i++) + delete[] m_addresses[i]; + delete[] m_addresses; + } + + if (m_address_match_len) + delete[] m_address_match_len; } int @@ -87,19 +139,23 @@ namespace gr { { // Check for a valid first address bit if((bytes[0] & 0x80) == (bytes[1] & 0x80)) - { + { // Attempt to decode a payload if(enhanced_shockburst_packet::try_parse(bytes, - m_decoded_bits_bytes.bytes(0), + (const uint8_t **) m_addresses, + (const uint8_t *) m_address_match_len, m_address_length, m_crc_length, m_enhanced_shockburst)) { + // m_enhanced_shockburst->print(); + // Build the wireshark header nordictap_header header; header.channel = m_channel; header.data_rate = m_data_rate; header.address_length = m_address_length; + header.big_packet = m_enhanced_shockburst->big_packet(); header.payload_length = m_enhanced_shockburst->payload_length(); header.sequence_number = m_enhanced_shockburst->sequence_number(); header.no_ack = m_enhanced_shockburst->no_ack(); @@ -112,6 +168,9 @@ namespace gr { memcpy(&buffer[sizeof(nordictap_header)], m_enhanced_shockburst->address(), m_address_length); memcpy(&buffer[sizeof(nordictap_header) + m_address_length], m_enhanced_shockburst->payload(), header.payload_length); memcpy(&buffer[sizeof(nordictap_header) + m_address_length + header.payload_length], m_enhanced_shockburst->crc(), m_crc_length); + + //printf("Buffer=%s", buffer); + //printf("\n"); // Send the packet to wireshark boost::asio::io_service io_service; diff --git a/lib/nordic_rx_impl.h b/lib/nordic_rx_impl.h index adcf668..e33f7e3 100644 --- a/lib/nordic_rx_impl.h +++ b/lib/nordic_rx_impl.h @@ -41,6 +41,8 @@ namespace gr { uint8_t m_crc_length; uint8_t m_channel; uint8_t m_data_rate; + uint8_t** m_addresses; + uint8_t* m_address_match_len; // Incoming bit/byte vector bit_shifting_byte_vector m_decoded_bits_bytes; @@ -51,10 +53,11 @@ namespace gr { public: // Constructor/destructor - nordic_rx_impl(uint8_t channel, - uint8_t address_length, - uint8_t crc_length, - uint8_t data_rate); + nordic_rx_impl(const uint8_t channel, + const uint8_t address_length, + const uint8_t crc_length, + const uint8_t data_rate, + const std::string &address_match); ~nordic_rx_impl(); // Main work method diff --git a/lib/nordic_tx_impl.cc b/lib/nordic_tx_impl.cc index 019f39e..1dfe011 100644 --- a/lib/nordic_tx_impl.cc +++ b/lib/nordic_tx_impl.cc @@ -24,6 +24,7 @@ #include #include +#include #include "nordic_tx_impl.h" #include "nordictap.h" #include "enhanced_shockburst_packet.h" @@ -49,7 +50,7 @@ namespace gr { { // Register nordictap input, which accepts packets to transmit message_port_register_in(pmt::intern("nordictap_in")); - set_msg_handler(pmt::intern("nordictap_in"), boost::bind(&nordic_tx_impl::nordictap_message_handler, this, _1)); + set_msg_handler(pmt::intern("nordictap_in"), boost::bind(&nordic_tx_impl::nordictap_message_handler, this, boost::placeholders::_1)); } /* @@ -63,6 +64,7 @@ namespace gr { void nordic_tx_impl::nordictap_message_handler(pmt::pmt_t msg) { m_tx_queue.push(msg); + //printf("Got new message\n"); } int @@ -78,7 +80,7 @@ namespace gr { // Get the blob std::vector vec = pmt::u8vector_elements(m_tx_queue.front()); uint8_t * blob = vec.data(); - + // Read the channel index uint8_t channel = blob[0]; @@ -97,6 +99,7 @@ namespace gr { // Build the packet enhanced_shockburst_packet * packet = new enhanced_shockburst_packet(header.address_length, + header.big_packet, header.payload_length, header.sequence_number, header.no_ack, @@ -107,14 +110,26 @@ namespace gr { // Remove the blob from the queue m_tx_queue.pop(); + memset(output_items[channel], 0, packet->bytes_length()*2); // Write the output bytes uint8_t * out = (uint8_t *)output_items[channel]; + for(int b = 0; b < packet->bytes_length(); b++) + //for(int b = 0; b < noutput_items; b++) { out[b] = packet->bytes()[b]; - out[packet->bytes_length()*2+b] = packet->bytes()[b]; + //printf(" ByteOut = %02X\n", out[b]); + //printf(" ByteIn = %02X\n", packet->bytes()[b]); + //out[packet->bytes_length()*2+b] = packet->bytes()[b]; + //out[packet->bytes_length()*2+b] = 0x0; + //printf(" Bytes = %02X\n", out[packet->bytes_length()*2+b]); + //out[packet->bytes_length()*3+b] = packet->bytes()[b]; } - + /*for(int b = 0; b < 5; b++) + { + out[packet->bytes_length()*2+b] = 0x0; + }*/ + //memcpy(output_items[0],out, packet->bytes_length()*2); // Write zeros to the other channels' buffers for(int c = 0; c < m_channel_count; c++) { @@ -123,14 +138,34 @@ namespace gr { memset(output_items[c], 0, packet->bytes_length()*2); } } - + //printf("Number of output items %d\n", noutput_items); + //printf("Channel = %d\n",blob[0]); + //printf("Packet length = %d\n",packet->bytes_length()*2); + //packet->print(); // Cleanup delete[] address; delete[] payload; - delete packet; + //printf("Number of items written sob %ld\n", nitems_written(0)); + add_item_tag(0, nitems_written(0), + pmt::string_to_symbol("tx_sob"), + pmt::PMT_T, + pmt::string_to_symbol(name())); + //printf("Number of items written eob %ld\n", nitems_written(0) + packet->bytes_length()); + add_item_tag(0, nitems_written(0) + packet->bytes_length(), + pmt::string_to_symbol("tx_eob"), + pmt::PMT_T, + pmt::string_to_symbol(name())); + int packet_length = packet->bytes_length()*2; + //printf("Number of items written %ld\n", nitems_written(0)); + add_item_tag(0, // Port number + nitems_written(0), // Offset + pmt::mp("packet_len"), // Key + pmt::from_uint64(packet_length) // Value + ); + delete packet; //This is really stupid! // Return the number of bytes produced - return packet->bytes_length()*2; + return packet_length; } else { diff --git a/lib/nordictap.h b/lib/nordictap.h index d9e4e52..4affc37 100644 --- a/lib/nordictap.h +++ b/lib/nordictap.h @@ -31,6 +31,9 @@ struct nordictap_header // CRC length, in bytes uint8_t crc_length; + // Big packet protocol + bool big_packet; + } __attribute__((packed)); #endif // NORDICTAP_H \ No newline at end of file diff --git a/lib/qa_nordic.cc b/lib/qa_nordic.cc deleted file mode 100644 index 14c4244..0000000 --- a/lib/qa_nordic.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -*/ - -/* - * This class gathers together all the test cases for the gr-filter - * directory into a single test suite. As you create new test cases, - * add them here. - */ - -#include "qa_nordic.h" - -CppUnit::TestSuite * -qa_nordic::suite() -{ - CppUnit::TestSuite *s = new CppUnit::TestSuite("nordic"); - - return s; -} diff --git a/lib/qa_nordic.h b/lib/qa_nordic.h deleted file mode 100644 index 9f57ecd..0000000 --- a/lib/qa_nordic.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- c++ -*- */ -/* - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -*/ - -#ifndef _QA_NORDIC_H_ -#define _QA_NORDIC_H_ - -#include -#include - -//! collect all the tests for the gr-filter directory - -class __GR_ATTR_EXPORT qa_nordic -{ - public: - //! return suite of tests for all of gr-filter directory - static CppUnit::TestSuite *suite(); -}; - -#endif /* _QA_NORDIC_H_ */ diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 5e26f62..257477f 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,17 +1,10 @@ -# Copyright (C) 2016 Bastille Networks +# Copyright 2011 Free Software Foundation, Inc. # -# 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 3 of the License, or -# (at your option) any later version. +# This file was generated by gr_modtool, a tool from the GNU Radio framework +# This file is a part of gr-nordic # -# 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. +# SPDX-License-Identifier: GPL-3.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . ######################################################################## # Include python install macros @@ -21,12 +14,15 @@ if(NOT PYTHONINTERP_FOUND) return() endif() +add_subdirectory(bindings) + ######################################################################## # Install python sources ######################################################################## GR_PYTHON_INSTALL( FILES __init__.py + nordic_blocks.py DESTINATION ${GR_PYTHON_DIR}/nordic ) @@ -36,4 +32,3 @@ GR_PYTHON_INSTALL( include(GrTest) set(GR_TEST_TARGET_DEPS gnuradio-nordic) -set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) diff --git a/python/__init__.py b/python/__init__.py index ec593b2..2d16fe5 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -1,19 +1,8 @@ -''' - Copyright (C) 2016 Bastille Networks - - 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 3 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, see . -''' +# +# Copyright 2008,2009 Free Software Foundation, Inc. +# +# SPDX-License-Identifier: GPL-3.0-or-later +# # The presence of this file turns this directory into a Python package @@ -21,15 +10,15 @@ This is the GNU Radio NORDIC module. Place your Python package description here (python/__init__.py). ''' +import os -# import swig generated symbols into the nordic namespace +# import pybind11 generated symbols into the nordic namespace try: - # this might fail if the module is python-only - from nordic_swig import * -except ImportError: - pass + # this might fail if the module is python-only + from .nordic_python import * +except ModuleNotFoundError: + pass # import any pure python here - - # +from .nordic_blocks import nordictap_printer, nordictap_transmitter \ No newline at end of file diff --git a/python/bindings/CMakeLists.txt b/python/bindings/CMakeLists.txt new file mode 100644 index 0000000..6e4ee8a --- /dev/null +++ b/python/bindings/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright 2020 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# SPDX-License-Identifier: GPL-3.0-or-later +# + +######################################################################## +# Check if there is C++ code at all +######################################################################## +if(NOT nordic_sources) + MESSAGE(STATUS "No C++ sources... skipping python bindings") + return() +endif(NOT nordic_sources) + +######################################################################## +# Check for pygccxml +######################################################################## +GR_PYTHON_CHECK_MODULE_RAW( + "pygccxml" + "import pygccxml" + PYGCCXML_FOUND + ) + +include(GrPybind) + +######################################################################## +# Python Bindings +######################################################################## + +list(APPEND nordic_python_files + nordic_rx_python.cc + nordic_tx_python.cc + python_bindings.cc) + +GR_PYBIND_MAKE_OOT(nordic + ../.. + gr::nordic + "${nordic_python_files}") + +install(TARGETS nordic_python DESTINATION ${GR_PYTHON_DIR}/nordic COMPONENT pythonapi) diff --git a/python/bindings/README.md b/python/bindings/README.md new file mode 100644 index 0000000..e69de29 diff --git a/python/bindings/bind_oot_file.py b/python/bindings/bind_oot_file.py new file mode 100644 index 0000000..91719f7 --- /dev/null +++ b/python/bindings/bind_oot_file.py @@ -0,0 +1,57 @@ +import warnings +import argparse +import os +from gnuradio.bindtool import BindingGenerator +import pathlib +import sys + +parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block') +parser.add_argument('--module', type=str, + help='Name of gr module containing file to bind (e.g. fft digital analog)') + +parser.add_argument('--output_dir', default='/tmp', + help='Output directory of generated bindings') +parser.add_argument('--prefix', help='Prefix of Installed GNU Radio') +parser.add_argument('--src', help='Directory of gnuradio source tree', + default=os.path.dirname(os.path.abspath(__file__))+'/../../..') + +parser.add_argument( + '--filename', help="File to be parsed") + +parser.add_argument( + '--defines', help='Set additional defines for precompiler',default=(), nargs='*') +parser.add_argument( + '--include', help='Additional Include Dirs, separated', default=(), nargs='*') + +parser.add_argument( + '--status', help='Location of output file for general status (used during cmake)', default=None +) +parser.add_argument( + '--flag_automatic', default='0' +) +parser.add_argument( + '--flag_pygccxml', default='0' +) + +args = parser.parse_args() + +prefix = args.prefix +output_dir = args.output_dir +defines = tuple(','.join(args.defines).split(',')) +includes = ','.join(args.include) +name = args.module + +namespace = ['gr', name] +prefix_include_root = name + + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + + bg = BindingGenerator(prefix, namespace, + prefix_include_root, output_dir, define_symbols=defines, addl_includes=includes, + catch_exceptions=False, write_json_output=False, status_output=args.status, + flag_automatic=True if args.flag_automatic.lower() in [ + '1', 'true'] else False, + flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False) + bg.gen_file_binding(args.filename) diff --git a/python/bindings/docstrings/README.md b/python/bindings/docstrings/README.md new file mode 100644 index 0000000..295455a --- /dev/null +++ b/python/bindings/docstrings/README.md @@ -0,0 +1 @@ +This directory stores templates for docstrings that are scraped from the include header files for each block \ No newline at end of file diff --git a/python/bindings/docstrings/nordic_rx_pydoc_template.h b/python/bindings/docstrings/nordic_rx_pydoc_template.h new file mode 100644 index 0000000..89f27ad --- /dev/null +++ b/python/bindings/docstrings/nordic_rx_pydoc_template.h @@ -0,0 +1,36 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,nordic, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_nordic_nordic_rx = R"doc()doc"; + + + static const char *__doc_gr_nordic_nordic_rx_nordic_rx_0 = R"doc()doc"; + + + static const char *__doc_gr_nordic_nordic_rx_nordic_rx_1 = R"doc()doc"; + + + static const char *__doc_gr_nordic_nordic_rx_make = R"doc()doc"; + + + static const char *__doc_gr_nordic_nordic_rx_get_channel = R"doc()doc"; + + + static const char *__doc_gr_nordic_nordic_rx_set_channel = R"doc()doc"; + + diff --git a/python/bindings/docstrings/nordic_tx_pydoc_template.h b/python/bindings/docstrings/nordic_tx_pydoc_template.h new file mode 100644 index 0000000..910cb4d --- /dev/null +++ b/python/bindings/docstrings/nordic_tx_pydoc_template.h @@ -0,0 +1,27 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "pydoc_macros.h" +#define D(...) DOC(gr,nordic, __VA_ARGS__ ) +/* + This file contains placeholders for docstrings for the Python bindings. + Do not edit! These were automatically extracted during the binding process + and will be overwritten during the build process + */ + + + + static const char *__doc_gr_nordic_nordic_tx = R"doc()doc"; + + + static const char *__doc_gr_nordic_nordic_tx_nordic_tx = R"doc()doc"; + + + static const char *__doc_gr_nordic_nordic_tx_make = R"doc()doc"; + + diff --git a/python/bindings/header_utils.py b/python/bindings/header_utils.py new file mode 100644 index 0000000..165124e --- /dev/null +++ b/python/bindings/header_utils.py @@ -0,0 +1,78 @@ +# Utilities for reading values in header files + +from argparse import ArgumentParser +import re + + +class PybindHeaderParser: + def __init__(self, pathname): + with open(pathname,'r') as f: + self.file_txt = f.read() + + def get_flag_automatic(self): + # p = re.compile(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)', self.file_txt) + if (m and m.group(1) == '1'): + return True + else: + return False + + def get_flag_pygccxml(self): + # p = re.compile(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)', self.file_txt) + if (m and m.group(1) == '1'): + return True + else: + return False + + def get_header_filename(self): + # p = re.compile(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)', self.file_txt) + if (m): + return m.group(1) + else: + return None + + def get_header_file_hash(self): + # p = re.compile(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)') + # m = p.search(self.file_txt) + m = re.search(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)', self.file_txt) + if (m): + return m.group(1) + else: + return None + + def get_flags(self): + return f'{self.get_flag_automatic()};{self.get_flag_pygccxml()};{self.get_header_filename()};{self.get_header_file_hash()};' + + + +def argParse(): + """Parses commandline args.""" + desc='Reads the parameters from the comment block in the pybind files' + parser = ArgumentParser(description=desc) + + parser.add_argument("function", help="Operation to perform on comment block of pybind file", choices=["flag_auto","flag_pygccxml","header_filename","header_file_hash","all"]) + parser.add_argument("pathname", help="Pathname of pybind c++ file to read, e.g. blockname_python.cc") + + return parser.parse_args() + +if __name__ == "__main__": + # Parse command line options and set up doxyxml. + args = argParse() + + pbhp = PybindHeaderParser(args.pathname) + + if args.function == "flag_auto": + print(pbhp.get_flag_automatic()) + elif args.function == "flag_pygccxml": + print(pbhp.get_flag_pygccxml()) + elif args.function == "header_filename": + print(pbhp.get_header_filename()) + elif args.function == "header_file_hash": + print(pbhp.get_header_file_hash()) + elif args.function == "all": + print(pbhp.get_flags()) \ No newline at end of file diff --git a/python/bindings/nordic_rx_python.cc b/python/bindings/nordic_rx_python.cc new file mode 100644 index 0000000..ac2918e --- /dev/null +++ b/python/bindings/nordic_rx_python.cc @@ -0,0 +1,77 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(nordic_rx.h) */ +/* BINDTOOL_HEADER_FILE_HASH(4f65600078a25f6e89110772295838c5) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_nordic_rx(py::module& m) +{ + + using nordic_rx = ::gr::nordic::nordic_rx; + + + py::class_>(m, "nordic_rx", D(nordic_rx)) + + .def(py::init(&nordic_rx::make), + py::arg("channel") = 0, + py::arg("address_length") = 5, + py::arg("crc_length") = 2, + py::arg("data_rate") = 0, + py::arg("address_match") = "", + D(nordic_rx,make) + ) + + + + + + + .def("get_channel",&nordic_rx::get_channel, + D(nordic_rx,get_channel) + ) + + + + .def("set_channel",&nordic_rx::set_channel, + py::arg("channel"), + D(nordic_rx,set_channel) + ) + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/nordic_tx_python.cc b/python/bindings/nordic_tx_python.cc new file mode 100644 index 0000000..fc8d198 --- /dev/null +++ b/python/bindings/nordic_tx_python.cc @@ -0,0 +1,60 @@ +/* + * Copyright 2021 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +/***********************************************************************************/ +/* This file is automatically generated using bindtool and can be manually edited */ +/* The following lines can be configured to regenerate this file during cmake */ +/* If manual edits are made, the following tags should be modified accordingly. */ +/* BINDTOOL_GEN_AUTOMATIC(0) */ +/* BINDTOOL_USE_PYGCCXML(0) */ +/* BINDTOOL_HEADER_FILE(nordic_tx.h) */ +/* BINDTOOL_HEADER_FILE_HASH(1d227aa9169123335554c7962533ad4d) */ +/***********************************************************************************/ + +#include +#include +#include + +namespace py = pybind11; + +#include +// pydoc.h is automatically generated in the build directory +#include + +void bind_nordic_tx(py::module& m) +{ + + using nordic_tx = ::gr::nordic::nordic_tx; + + + py::class_>(m, "nordic_tx", D(nordic_tx)) + + .def(py::init(&nordic_tx::make), + py::arg("channel_count") = 1, + D(nordic_tx,make) + ) + + + + + ; + + + + +} + + + + + + + + diff --git a/python/bindings/python_bindings.cc b/python/bindings/python_bindings.cc new file mode 100644 index 0000000..2ce0039 --- /dev/null +++ b/python/bindings/python_bindings.cc @@ -0,0 +1,57 @@ +/* + * Copyright 2020 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include + +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include + +namespace py = pybind11; + +// Headers for binding functions +/**************************************/ +// The following comment block is used for +// gr_modtool to insert function prototypes +// Please do not delete +/**************************************/ +// BINDING_FUNCTION_PROTOTYPES( + void bind_nordic_rx(py::module& m); + void bind_nordic_tx(py::module& m); +// ) END BINDING_FUNCTION_PROTOTYPES + + +// We need this hack because import_array() returns NULL +// for newer Python versions. +// This function is also necessary because it ensures access to the C API +// and removes a warning. +void* init_numpy() +{ + import_array(); + return NULL; +} + +PYBIND11_MODULE(nordic_python, m) +{ + // Initialize the numpy C API + // (otherwise we will see segmentation faults) + init_numpy(); + + // Allow access to base block methods + py::module::import("gnuradio.gr"); + + /**************************************/ + // The following comment block is used for + // gr_modtool to insert binding function calls + // Please do not delete + /**************************************/ + // BINDING_FUNCTION_CALLS( + bind_nordic_rx(m); + bind_nordic_tx(m); + // ) END BINDING_FUNCTION_CALLS +} diff --git a/python/nordic_blocks.py b/python/nordic_blocks.py new file mode 100644 index 0000000..07f3fba --- /dev/null +++ b/python/nordic_blocks.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python + +from gnuradio import gr, blocks, digital +import _thread +import nordic +import pmt +import struct +import time +import numpy +import array +import random +import argparse +from bitstring import BitArray +from gnuradio import uhd +from queue import Queue + +# Nordic transmitter strobe +class nordictap_transmitter(gr.sync_block): + + # Constructor + + def __init__(self, channel_map, address, payload, channel_index, sequence_number, big_packet): + gr.sync_block.__init__( + self, name="Nordictap Transmitter", in_sig=None, out_sig=None) + + self.channel_map = [channel_map] + self.address = address + self.payload = payload + self.channel_index = channel_index + self.sequence_number = sequence_number + self.big_packet = big_packet + + # Packet output port + self.message_port_register_in(pmt.intern("trig")) + self.message_port_register_out(pmt.intern("nordictap_out")) + + self.set_msg_handler(pmt.intern("trig"), self.transmit) + + # Transmit a packet + def transmit(self, msg): + + channel = self.channel_map[self.channel_index] + + if self.sequence_number == 4: + self.sequence_number = 0 + + #print address + #print('SEQ=' + str(self.sequence_number)) + # Build a payload + nordictap = [self.channel_index] + [ + channel, 2, len(self.address), len(self.payload), self.sequence_number, 0, 2, self.big_packet] + for c in self.address: + nordictap.append(ord(c)) + for c in self.payload: + nordictap.append(ord(c)) + #print nordictap + self.sequence_number += 1 + # Transmit packet + #vec = pmt.make_u8vector(len(nordictap), 0) + vec = pmt.init_u8vector(len(nordictap), nordictap) + #for x in range(len(nordictap)): + # pmt.u8vector_set(vec, x, nordictap[x]) + self.message_port_pub(pmt.intern("nordictap_out"), vec) + #time.sleep(0.2) + + # Nordic Printer +class nordictap_printer(gr.sync_block): + + # Constructor + + def __init__(self): + gr.sync_block.__init__( + self, name="Nordictap Printer", in_sig=None, out_sig=None) + + # Received packet input port + self.message_port_register_in(pmt.intern("nordictap_in")) + self.set_msg_handler( + pmt.intern("nordictap_in"), self.nordictap_handler) + + # Handle incoming packets, and print payloads + def nordictap_handler(self, msg): + + # PMT to byte string + data = pmt.to_python(msg).tostring() + + # Unpack the header + values = struct.unpack('BBBBBBBB', data[0:8]) + channel = values[0] + data_rate = values[1] + address_length = values[2] + payload_length = values[3] + sequence_number = values[4] + no_ack = values[5] + crc_length = values[6] + big_packet = values[7] + + # Parse the address, payload, and crc + address = data[8:8 + address_length] + payload = data[8 + address_length:8 + address_length + payload_length] + crc = data[8 + address_length + payload_length: + 8 + address_length + payload_length + crc_length] + + # Print the channel, sequence number, address and payload + print('CH=' + str(2400 + channel)), + print('SEQ=' + str(sequence_number)), + print('ADDR=' + ':'.join('%02X' % b for b in address)), + print('PLD=' + ':'.join('%02X' % b for b in payload)), + print('CRC=' + ':'.join('%02X' % b for b in crc)) + print('BP=' + str(big_packet)) diff --git a/python/qa_nordic_rx.py b/python/qa_nordic_rx.py new file mode 100644 index 0000000..f6b6c64 --- /dev/null +++ b/python/qa_nordic_rx.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-nordic author. +# +# This is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This software 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 software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +from gnuradio import blocks +import nordic_swig as nordic + +class qa_nordic_rx(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_t(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_nordic_rx) diff --git a/python/qa_nordic_tx.py b/python/qa_nordic_tx.py new file mode 100644 index 0000000..ce2b56a --- /dev/null +++ b/python/qa_nordic_tx.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2021 gr-nordic author. +# +# This is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This software 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 software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, gr_unittest +from gnuradio import blocks +import nordic_swig as nordic + +class qa_nordic_tx(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_t(self): + # set up fg + self.tb.run() + # check data + + +if __name__ == '__main__': + gr_unittest.run(qa_nordic_tx) diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt deleted file mode 100644 index 277a0d3..0000000 --- a/swig/CMakeLists.txt +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright (C) 2016 Bastille Networks -# -# 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 3 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, see . - -######################################################################## -# Check if there is C++ code at all -######################################################################## -if(NOT nordic_sources) - MESSAGE(STATUS "No C++ sources... skipping swig/") - return() -endif(NOT nordic_sources) - -######################################################################## -# Include swig generation macros -######################################################################## -find_package(SWIG) -find_package(PythonLibs 2) -if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND) - return() -endif() -include(GrSwig) -include(GrPython) - -######################################################################## -# Setup swig generation -######################################################################## -foreach(incdir ${GNURADIO_RUNTIME_INCLUDE_DIRS}) - list(APPEND GR_SWIG_INCLUDE_DIRS ${incdir}/gnuradio/swig) -endforeach(incdir) - -set(GR_SWIG_LIBRARIES gnuradio-nordic) -set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/nordic_swig_doc.i) -set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include) - -GR_SWIG_MAKE(nordic_swig nordic_swig.i) - -######################################################################## -# Install the build swig module -######################################################################## -GR_SWIG_INSTALL(TARGETS nordic_swig DESTINATION ${GR_PYTHON_DIR}/nordic) - -######################################################################## -# Install swig .i files for development -######################################################################## -install( - FILES - nordic_swig.i - ${CMAKE_CURRENT_BINARY_DIR}/nordic_swig_doc.i - DESTINATION ${GR_INCLUDE_DIR}/nordic/swig -) diff --git a/swig/nordic_swig.i b/swig/nordic_swig.i deleted file mode 100644 index e4ea82a..0000000 --- a/swig/nordic_swig.i +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- c++ -*- */ - -#define NORDIC_API - -%include "gnuradio.i" // the common stuff - -//load generated python docstrings -%include "nordic_swig_doc.i" - -%{ -#include "nordic/nordic_rx.h" -#include "nordic/nordic_tx.h" -%} - - -%include "nordic/nordic_rx.h" -GR_SWIG_BLOCK_MAGIC2(nordic, nordic_rx); -%include "nordic/nordic_tx.h" -GR_SWIG_BLOCK_MAGIC2(nordic, nordic_tx); diff --git a/wireshark/nordic_dissector.lua b/wireshark/nordic_dissector.lua index 822cd99..40e3f36 100644 --- a/wireshark/nordic_dissector.lua +++ b/wireshark/nordic_dissector.lua @@ -32,16 +32,19 @@ function nordic_proto.dissector(buffer,pinfo,tree) -- crc length local crc_length = buffer(6,1):uint() + -- dynamic payloads bit + local dynamic_payload = buffer(7,1):uint() + -- address - local address = buffer(7,address_length) + local address = buffer(8,address_length) local address_bytes = address:bytes() -- payload - local payload = buffer(7+address_length,payload_length) + local payload = buffer(8+address_length,payload_length) local payload_bytes = payload:bytes() -- crc - local crc = buffer(7+address_length+payload_length, crc_length) + local crc = buffer(8+address_length+payload_length, crc_length) subtree:add(buffer(0,1), "Channel: " .. (2400+channel) .. "MHz") subtree:add(buffer(1,1), "Data Rate: " .. data_rate_string) @@ -49,10 +52,11 @@ function nordic_proto.dissector(buffer,pinfo,tree) subtree:add(buffer(3,1), "Payload Length: " .. payload_length) subtree:add(buffer(4,1), "Sequence Number: " .. sequence_number) subtree:add(buffer(5,1), "No ACK: " .. no_ack) - subtree:add(buffer(6,1), "CRC Length: " .. crc_length) - subtree:add(buffer(7,address_length), "Address: " .. address) - subtree:add(buffer(7+address_length,payload_length), "Payload: " .. payload) - subtree:add(buffer(7+address_length+payload_length, crc_length), "CRC: " .. crc) + subtree:add(buffer(6,1), "Dynamic Payload: " .. dynamic_payload) + subtree:add(buffer(7,1), "CRC Length: " .. crc_length) + subtree:add(buffer(8,address_length), "Address: " .. address) + subtree:add(buffer(8+address_length,payload_length), "Payload: " .. payload) + subtree:add(buffer(8+address_length+payload_length, crc_length), "CRC: " .. crc) -- Keepalive (vendor agnostic) if payload_bytes:len() == 0 then