├── .gitignore ├── .gitlab-ci.yml ├── .gitmodules ├── ABOUT ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── cmake ├── BuildFlatBuffers.cmake ├── FindFlatBuffers.cmake ├── SigmfConfig.cmake.in └── config.cmake.in ├── docs ├── index.md └── license.md ├── examples ├── CMakeLists.txt ├── example.sigmf-meta ├── example2.sigmf-meta ├── example_reading_sigmf_file.cpp ├── example_record_with_multiple_namespaces.cpp ├── example_record_with_variadic_dataclass.cpp ├── example_sigmf_json_roundtrip.cpp └── flatbuffer_patterns.cpp ├── mkdocs.yml ├── performance.json ├── sigmf_protocols ├── sigmf_adsb.fbs ├── sigmf_adsb_generated.h ├── sigmf_antenna.fbs ├── sigmf_antenna_generated.h ├── sigmf_capture_details.fbs ├── sigmf_capture_details_generated.h ├── sigmf_core.fbs ├── sigmf_core_generated.h ├── sigmf_signal.fbs ├── sigmf_signal_generated.h ├── sigmf_spatial.fbs ├── sigmf_spatial_generated.h ├── sigmf_wifi.fbs ├── sigmf_wifi_generated.h ├── testing_protocols.fbs └── testing_protocols_generated.h └── src ├── annotation.h ├── capture.h ├── collection.h ├── flatbuffers_json_visitor.h ├── flatbuffers_type_to_json.h ├── global.h ├── sigmf.h ├── sigmf_helpers.h └── variadic_data_class.h /.gitignore: -------------------------------------------------------------------------------- 1 | *build* 2 | .idea/ 3 | .vscode/ 4 | site/ 5 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | 2 | stages: 3 | - build 4 | - check 5 | - deploy 6 | 7 | build-16.04: 8 | stage: build 9 | image: ubuntu:16.04 10 | before_script: 11 | - apt update && apt install -y cmake build-essential git 12 | - git submodule update --init --recursive 13 | 14 | script: 15 | - mkdir build && cd build 16 | - cmake .. 17 | - make 18 | - ./example 19 | artifacts: 20 | paths: 21 | - build 22 | reports: 23 | performance: 24 | - performance.json 25 | expire_in: 26 | 1 week 27 | 28 | 29 | build-18.04: 30 | stage: build 31 | image: ubuntu:18.04 32 | before_script: 33 | - apt update && apt install -y cmake build-essential git 34 | - git submodule update --init --recursive 35 | script: 36 | - mkdir build && cd build 37 | - cmake .. 38 | - make 39 | - ./example 40 | artifacts: 41 | paths: 42 | - build 43 | expire_in: 44 | 1 week 45 | 46 | test-16.04: 47 | stage: check 48 | dependencies: 49 | - build-16.04 50 | image: ubuntu:16.04 51 | before_script: 52 | - apt update && apt install -y valgrind 53 | script: 54 | - valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all build/example 55 | 56 | test-18.04: 57 | stage: check 58 | dependencies: 59 | - build-18.04 60 | image: ubuntu:18.04 61 | before_script: 62 | - apt update && apt install -y valgrind 63 | script: 64 | - valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all build/example 65 | 66 | 67 | pages: 68 | stage: deploy 69 | image: python:alpine 70 | before_script: 71 | - pip install mkdocs 72 | script: 73 | - mkdocs build 74 | - mv site public 75 | artifacts: 76 | paths: 77 | - public 78 | only: 79 | - master 80 | 81 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/json"] 2 | path = external/json 3 | url = https://github.com/nlohmann/json.git 4 | [submodule "external/flatbuffers"] 5 | path = external/flatbuffers 6 | url = https://github.com/google/flatbuffers.git 7 | -------------------------------------------------------------------------------- /ABOUT: -------------------------------------------------------------------------------- 1 | libsigmf: https://www.deepsig.io/libsigmf 2 | 3 | libsigmf is a free & opensource library for working with SigMF recordings. 4 | (https://sigmf.org) 5 | 6 | It was designed to enable the use of SigMF through static types in C++, thus 7 | enabling things like compile-time errors and code inspection. 8 | 9 | It was created and first authored by DeepSig Inc., and then released to 10 | the community as an Apache 2.0-licensed FOSS project at FOSDEM 2019. 11 | 12 | Contributors: 13 | 14 | Nathan West 15 | Tim O'Shea 16 | Ben Hilburn 17 | 18 | 19 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | ######################################################################## 3 | # Setup project 4 | ######################################################################## 5 | cmake_minimum_required(VERSION 3.0) 6 | project(libsigmf VERSION 1.0.2 LANGUAGES CXX) 7 | 8 | # c++17 used for supporting flatbuffers optional scalar fields via std::optional 9 | set(CMAKE_CXX_STANDARD 17) 10 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 11 | 12 | list(APPEND CMAKE_MODULE_PATH cmake) 13 | option(ENABLE_EXAMPLES "Enable building of examples" ON) 14 | option(USE_SYSTEM_JSON "Attempt to use the system installed nlohmann JSON library" OFF) 15 | option(USE_SYSTEM_FLATBUFFERS "Attempt to use the system installed flatbuffers library and flatc" OFF) 16 | 17 | include(GNUInstallDirs) 18 | 19 | set(LIBSIGMF_TARGET_NAME ${PROJECT_NAME}) 20 | set(LIBSIGMF_CONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE INTERNAL "") 21 | set(LIBSIGMF_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") 22 | set(LIBSIGMF_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets") 23 | set(LIBSIGMF_CMAKE_CONFIG_TEMPLATE "cmake/config.cmake.in") 24 | set(LIBSIGMF_CMAKE_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}") 25 | set(LIBSIGMF_CMAKE_PROJECT_CONFIG_FILE "${LIBSIGMF_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Config.cmake") 26 | set(LIBSIGMF_CMAKE_VERSION_CONFIG_FILE "${LIBSIGMF_CMAKE_CONFIG_DIR}/${PROJECT_NAME}ConfigVersion.cmake") 27 | set(LIBSIGMF_CMAKE_PROJECT_TARGETS_FILE "${LIBSIGMF_CMAKE_CONFIG_DIR}/${PROJECT_NAME}Targets.cmake") 28 | 29 | ######################################################################## 30 | # Dependency management 31 | # 32 | # Prefer system-installed versions, but revert to using submodules 33 | ######################################################################## 34 | set(libsigmf_deps "") 35 | 36 | # flatbuffers 37 | if (${USE_SYSTEM_FLATBUFFERS}) 38 | find_package(Flatbuffers REQUIRED) 39 | endif (${USE_SYSTEM_FLATBUFFERS}) 40 | 41 | if (NOT ${USE_SYSTEM_FLATBUFFERS}) 42 | message(STATUS "Flatbuffers was not found. Submodule will be used. This will require building flatc") 43 | set(FLATBUFFERS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/flatbuffers/include") 44 | # Initialize Flatbuffers submodule if unititialized 45 | set(FLATBUFFERS_INCLUDE_DIR 46 | ${CMAKE_CURRENT_SOURCE_DIR}/external/flatbuffers/include 47 | CACHE PATH "flatbuffers include directory") 48 | 49 | if (NOT IS_DIRECTORY ${FLATBUFFERS_INCLUDE_DIR}) 50 | message("Flatbuffers submodule not found! Downloading...") 51 | execute_process(COMMAND git submodule update --init -- external/flatbuffers 52 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 53 | endif(NOT IS_DIRECTORY ${FLATBUFFERS_INCLUDE_DIR}) 54 | 55 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/flatbuffers 56 | ${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build 57 | EXCLUDE_FROM_ALL) 58 | endif (NOT ${USE_SYSTEM_FLATBUFFERS}) 59 | 60 | # nlohmann_json 61 | if (${USE_SYSTEM_JSON}) 62 | find_package(nlohmann_json REQUIRED) 63 | endif (${USE_SYSTEM_JSON}) 64 | 65 | if (NOT ${USE_SYSTEM_JSON}) 66 | message(STATUS "Nlohmann JSON was not found. Submodule will be used.") 67 | # Initialize Json submodule if unititialized 68 | set(JSON_INCLUDE_DIR 69 | ${CMAKE_CURRENT_SOURCE_DIR}/external/json/include 70 | CACHE PATH "json include directory") 71 | 72 | if (NOT IS_DIRECTORY ${JSON_INCLUDE_DIR}) 73 | message("Json submodule not found! Downloading...") 74 | execute_process(COMMAND git submodule update --init -- external/json 75 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 76 | endif(NOT IS_DIRECTORY ${JSON_INCLUDE_DIR}) 77 | endif(NOT ${USE_SYSTEM_JSON}) 78 | 79 | ######################################################################## 80 | # Use flatbuffers to generate SigMF headers 81 | ######################################################################## 82 | function(generate_sigmf_header generate_sigmf_target FBS_FILE OUTPUT_LOCATION) 83 | get_filename_component(generated_output_name ${FBS_FILE} NAME_WE) 84 | message(STATUS "Flatbuffers generated ${generated_output_name}") 85 | if( ${ARGC} GREATER 3) 86 | set(FLATC_EXTRA_ARGS ${ARGN}) 87 | string(REPLACE " " ";" FLATC_EXTRA_ARGS ${FLATC_EXTRA_ARGS}) 88 | else() 89 | set(FLATC_EXTRA_ARGS "") 90 | endif() 91 | add_custom_command(OUTPUT ${OUTPUT_LOCATION}/${generated_output_name}_generated.h 92 | COMMAND flatc ${FLATC_EXTRA_ARGS} -c --cpp-ptr-type std::shared_ptr --reflect-types --reflect-names --gen-object-api -o "${OUTPUT_LOCATION}/" "${FBS_FILE}" 93 | COMMENT "Building C++ header for flatbuffers definition ${FBS_FILE} ${ARGC} ${ARGN}" 94 | WORKING_DIRECTORY . 95 | DEPENDS "${FBS_FILE}" 96 | ) 97 | add_custom_target(generate_sigmf_target_${generate_sigmf_target} 98 | DEPENDS ${OUTPUT_LOCATION}/${generated_output_name}_generated.h 99 | ) 100 | add_library(${generate_sigmf_target} INTERFACE) 101 | add_dependencies(${generate_sigmf_target} generate_sigmf_target_${generate_sigmf_target} flatc) 102 | target_include_directories(${generate_sigmf_target} INTERFACE "${OUTPUT_LOCATION}/") 103 | endfunction(generate_sigmf_header) 104 | 105 | ######################################################################## 106 | # Create targets for generating default namespace definitions 107 | ######################################################################## 108 | generate_sigmf_header(generated_core_ns 109 | "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols/sigmf_core.fbs" 110 | "${CMAKE_CURRENT_BINARY_DIR}/include" 111 | ) 112 | generate_sigmf_header(generated_adsb_ns 113 | "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols/sigmf_adsb.fbs" 114 | "${CMAKE_CURRENT_BINARY_DIR}/include" 115 | ) 116 | generate_sigmf_header(generated_antenna_ns 117 | "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols/sigmf_antenna.fbs" 118 | "${CMAKE_CURRENT_BINARY_DIR}/include" 119 | ) 120 | generate_sigmf_header(generated_capture_details_ns 121 | "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols/sigmf_capture_details.fbs" 122 | "${CMAKE_CURRENT_BINARY_DIR}/include" 123 | ) 124 | generate_sigmf_header(generated_signal_ns 125 | "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols/sigmf_signal.fbs" 126 | "${CMAKE_CURRENT_BINARY_DIR}/include" 127 | ) 128 | generate_sigmf_header(generated_spatial_ns 129 | "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols/sigmf_spatial.fbs" 130 | "${CMAKE_CURRENT_BINARY_DIR}/include" 131 | ) 132 | generate_sigmf_header(generated_wifi_ns 133 | "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols/sigmf_wifi.fbs" 134 | "${CMAKE_CURRENT_BINARY_DIR}/include" 135 | ) 136 | generate_sigmf_header(generated_testing_ns 137 | "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols/testing_protocols.fbs" 138 | "${CMAKE_CURRENT_BINARY_DIR}/include" 139 | ) 140 | 141 | # We also carry around pre-generated headers so downstream doesn't need to build flatc 142 | set(LIBSIGMF_PREGEN_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols") 143 | 144 | ######################################################################## 145 | # Our interface target that downstream have to use 146 | ######################################################################## 147 | add_library(libsigmf INTERFACE) 148 | target_include_directories(libsigmf INTERFACE 149 | $ 150 | $ 151 | $ 152 | $ 153 | ) 154 | 155 | if (${Flatbuffers_FOUND}) 156 | # System flatbuffers can import this target 157 | else() 158 | target_include_directories(libsigmf INTERFACE 159 | $ 160 | ) 161 | endif(${Flatbuffers_FOUND}) 162 | 163 | if (${nlohmann_json_FOUND}) 164 | # TODO: add target_link_libraries interface to nlohmann json 165 | # when we use the system version 166 | else() 167 | target_include_directories(libsigmf INTERFACE 168 | $ 169 | ) 170 | endif(${nlohmann_json_FOUND}) 171 | 172 | 173 | ######################################################################## 174 | # Ensure that our protocol headers are generated before libsigmf dep 175 | ######################################################################## 176 | add_dependencies(libsigmf libsigmf_genheaders) 177 | add_custom_target(libsigmf_genheaders DEPENDS 178 | generate_sigmf_target_generated_core_ns 179 | # extension namespaces: 180 | generate_sigmf_target_generated_adsb_ns 181 | generate_sigmf_target_generated_antenna_ns 182 | generate_sigmf_target_generated_capture_details_ns 183 | generate_sigmf_target_generated_spatial_ns 184 | generate_sigmf_target_generated_signal_ns 185 | generate_sigmf_target_generated_wifi_ns 186 | generate_sigmf_target_generated_testing_ns 187 | ) 188 | 189 | if (ENABLE_EXAMPLES) 190 | add_subdirectory(examples) 191 | endif (ENABLE_EXAMPLES) 192 | 193 | add_custom_target(makedocs 194 | COMMAND mkdocs build 195 | COMMENT "Building documentation website" 196 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 197 | 198 | include(CMakePackageConfigHelpers) 199 | write_basic_package_version_file( 200 | ${LIBSIGMF_CMAKE_VERSION_CONFIG_FILE} COMPATIBILITY SameMajorVersion 201 | ) 202 | 203 | configure_file( 204 | ${CMAKE_CURRENT_SOURCE_DIR}/${LIBSIGMF_CMAKE_CONFIG_TEMPLATE} 205 | ${LIBSIGMF_CMAKE_PROJECT_CONFIG_FILE} 206 | @ONLY 207 | ) 208 | 209 | ######################################################################## 210 | # Install SigMF headers 211 | ######################################################################## 212 | install( # install flatbuf proto defs 213 | DIRECTORY ${LIBSIGMF_PREGEN_HEADERS}/ 214 | DESTINATION include/sigmf/fbs 215 | FILES_MATCHING PATTERN "*.fbs") 216 | install( # install pregenerated headers 217 | DIRECTORY ${LIBSIGMF_PREGEN_HEADERS}/ 218 | DESTINATION include/sigmf 219 | FILES_MATCHING PATTERN "*.h") 220 | install( # if headers were built, replace pregenerated headers with those 221 | DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/ 222 | DESTINATION include/sigmf 223 | FILES_MATCHING PATTERN "*.h") 224 | install( # install original headers 225 | DIRECTORY ${CMAKE_SOURCE_DIR}/src/ 226 | DESTINATION include/sigmf 227 | FILES_MATCHING PATTERN "*.h") 228 | 229 | ######################################################################## 230 | # Install cmake configuration foo 231 | ######################################################################## 232 | install( 233 | FILES ${LIBSIGMF_CMAKE_PROJECT_CONFIG_FILE} 234 | ${LIBSIGMF_CMAKE_VERSION_CONFIG_FILE} 235 | DESTINATION ${LIBSIGMF_CONFIG_INSTALL_DIR} 236 | ) 237 | install(TARGETS libsigmf 238 | EXPORT ${LIBSIGMF_TARGETS_EXPORT_NAME} 239 | ) 240 | install(EXPORT ${LIBSIGMF_TARGETS_EXPORT_NAME} 241 | FILE ${LIBSIGMF_TARGETS_EXPORT_NAME}.cmake 242 | NAMESPACE ${PROJECT_NAME}:: 243 | DESTINATION ${LIBSIGMF_CONFIG_INSTALL_DIR} 244 | ) 245 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | All contributions following the `inbound=outbound` licensing model, as 2 | described 3 | [here](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license), 4 | and are copyright of their respective author(s). 5 | 6 | When contributing code, please mimic the code style of the project. 7 | Contributions should be made in the form of Pull Requests on [libsigmf's GitHub 8 | project](https://github.com/deepsig/libsigmf). 9 | 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | libsigmf: https://www.deepsig.io/libsigmf 2 | 3 | Copyright 2019 DeepSig Inc. and libsigmf contributors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # libsigmf 3 | 4 | `libsigmf` is a header-only C++ library for working with [SigMF](https://github.com/gnuradio/sigmf) metadata. It is 5 | provided under the Apache License 2.0 and the copyright notice can be found in NOTICE. 6 | 7 | ## Updates in libsigmf v1.0 8 | 9 | Version 1.0 has several changes from earlier versions, most notably is the requirement to use optional (nullable) 10 | scalar fields which became supported in flatbuffers since the library was originally published (v0.0.2). This means 11 | scalar values are ALL implemented as `std::optional`, which is a change for applications using `libsigmf`. This 12 | change was made to avoid the situation where default values are either not populated or always populated. Now all 13 | fields will be included in the output if and only if they are set. 14 | 15 | Other v1.0 changes include: updating to the latest SigMF metadata fields in the included schemas (including 16 | redefining all scalar fields as optional via `=null;`), updating to flatbuffers v2.0.0 syntax, using `shared_ptr` 17 | for generated headers instead of `unique_ptr`, cmake updates, updates to examples to ensure optional fields are 18 | working correctly, update to require c++17 for `std::optional`, and namespacing the entire library and associated 19 | schema files within the `sigmf::` c++ namespace. 20 | 21 | To update existing code from libsigmf v0.x to v1.x, some changes are required. Accessing a field like this: 22 | 23 | ```c++ 24 | annotation_sample_start = annotation.sample_start; 25 | ``` 26 | 27 | is no longer valid as the `annotation.sample_start` field is not a `uint64_t`, its a `std::optional` and must now 28 | be checked to see if it has been set, then accessed in a legal way, such as: 29 | 30 | ```c++ 31 | if (annotation.sample_start.has_value()) { 32 | annotation_sample_start = annotation.sample_start.value(); 33 | } else { 34 | // what to do if the "sample_start" field is missing 35 | } 36 | ``` 37 | 38 | Users can also preserve existing behavior (where all scalar fields had a default value of zero) with: 39 | 40 | ```c++ 41 | annotation_sample_start = annotation.sample_start.value_or(0); 42 | ``` 43 | 44 | or any other default value of choice. 45 | 46 | Generation of JSON is unaffected other than it is no longer required to choose between "all fields" or "no fields 47 | with default values". 48 | 49 | ## Limitations of libsigmf v1.0 50 | 51 | - SigMF collections do not have any formal support yet. 52 | - Formal test code is still a WIP, examples provide some code coverage. 53 | 54 | ## Building 55 | 56 | libsigmf depends on the following packages: 57 | 58 | - nlohmann-json3-dev (3.7.3 preferred, other versions may work) 59 | - libflatbuffers-dev (2.0.0 required as of SigMF v1.0) 60 | 61 | These dependencies are included as submodules that can be built alongside libsigmf (default), or system installed 62 | libraries can be used by passing `-DUSE_SYSTEM_JSON=ON -DUSE_SYSTEM_FLATBUFFERS=ON` to cmake. It is recommended 63 | that users install flatbuffers v2.0 system wide as most applications using libsigmf will also need this. 64 | 65 | Build with the standard cmake process: 66 | 67 | ``` 68 | mkdir build 69 | cd build 70 | cmake ../ # OR: cmake -DUSE_SYSTEM_JSON=ON -DUSE_SYSTEM_FLATBUFFERS=ON ../ 71 | make -j 72 | sudo make install 73 | ``` 74 | 75 | ## Usage 76 | 77 | It is important to keep in mind that libsigmf does not strictly enforce all aspects of the SigMF 78 | specification. While types are strictly enforced, fields that are noted as REQUIRED by SigMF will 79 | not necessarily cause errors if they are missing during schema parsing. 80 | 81 | ### Including in your application 82 | 83 | To use libsigmf, your application needs to `#include ` and link to `libflatbuffers.so`. 84 | 85 | One option is to include libsigmf (this git repo) as a submodule inside your project sources. A typical cmake 86 | usage would look like the following (see the CMakeLists.txt in this examples directory for what this looks like 87 | in real usage). 88 | 89 | ```cmake 90 | add_executable(example_record_with_multiple_namespaces example_record_with_multiple_namespaces.cpp) 91 | target_link_libraries(example_record_with_multiple_namespaces libsigmf::libsigmf) 92 | target_include_directories(example_record_with_multiple_namespaces PRIVATE ${CMAKE_BINARY_DIR}/include) 93 | ``` 94 | 95 | Ideally you install `libsigmf` either system-wide or in a prefix. Provided CMake configuration 96 | then enables you to include `libsigmf` in your project by including this 97 | 98 | ```cmake 99 | find_package(libsigmf REQUIRED) 100 | add_executable(my_awesome_record my_awesome_record.cpp) 101 | target_link_libraries(my_awesome_record libsigmf::libsigmf) 102 | ``` 103 | 104 | ### Code usage 105 | 106 | libsigmf internally has a class `sigmf::VariadicDataClass` that does the heavy lifting of keeping objects of collected 107 | metadata using different SigMF namespaces. As a convenience, there are 4 classes that directly deal with SigMF 108 | objects that are all you need to use: 109 | 110 | 1) `sigmf::SigMF` 111 | 2) `sigmf::Global` 112 | 3) `sigmf::Capture` 113 | 4) `sigmf::Annotation` 114 | 115 | ## Extensions 116 | 117 | By default, the `antenna`, `capture_details`, and `signal` extensions are included in libsigmf. Users are 118 | able to add additional extensions by defining *.fbs schema, building with flatc and including these schema 119 | in their applications. The canonical signal-specific extensions (`adsb`, `wifi`) are included and imported 120 | into sigmf.h but are not built into the sigmf helpers by default. 121 | 122 | ## Contributing 123 | 124 | Please see `CONTRIBUTING.md` for more information! 125 | -------------------------------------------------------------------------------- /cmake/BuildFlatBuffers.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Google Inc. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # General function to create FlatBuffer build rules for the given list of 16 | # schemas. 17 | # 18 | # flatbuffers_schemas: A list of flatbuffer schema files to process. 19 | # 20 | # schema_include_dirs: A list of schema file include directories, which will be 21 | # passed to flatc via the -I parameter. 22 | # 23 | # custom_target_name: The generated files will be added as dependencies for a 24 | # new custom target with this name. You should add that target as a dependency 25 | # for your main target to ensure these files are built. You can also retrieve 26 | # various properties from this target, such as GENERATED_INCLUDES_DIR, 27 | # BINARY_SCHEMAS_DIR, and COPY_TEXT_SCHEMAS_DIR. 28 | # 29 | # additional_dependencies: A list of additional dependencies that you'd like 30 | # all generated files to depend on. Pass in a blank string if you have none. 31 | # 32 | # generated_includes_dir: Where to generate the C++ header files for these 33 | # schemas. The generated includes directory will automatically be added to 34 | # CMake's include directories, and will be where generated header files are 35 | # placed. This parameter is optional; pass in empty string if you don't want to 36 | # generate include files for these schemas. 37 | # 38 | # binary_schemas_dir: If you specify an optional binary schema directory, binary 39 | # schemas will be generated for these schemas as well, and placed into the given 40 | # directory. 41 | # 42 | # copy_text_schemas_dir: If you want all text schemas (including schemas from 43 | # all schema include directories) copied into a directory (for example, if you 44 | # need them within your project to build JSON files), you can specify that 45 | # folder here. All text schemas will be copied to that folder. 46 | # 47 | # IMPORTANT: Make sure you quote all list arguments you pass to this function! 48 | # Otherwise CMake will only pass in the first element. 49 | # Example: build_flatbuffers("${fb_files}" "${include_dirs}" target_name ...) 50 | function(build_flatbuffers flatbuffers_schemas 51 | schema_include_dirs 52 | custom_target_name 53 | additional_dependencies 54 | generated_includes_dir 55 | binary_schemas_dir 56 | copy_text_schemas_dir) 57 | 58 | # Test if including from FindFlatBuffers 59 | if(FLATBUFFERS_FLATC_EXECUTABLE) 60 | set(FLATC_TARGET "") 61 | set(FLATC ${FLATBUFFERS_FLATC_EXECUTABLE}) 62 | else() 63 | set(FLATC_TARGET flatc) 64 | set(FLATC flatc) 65 | endif() 66 | set(FLATC_SCHEMA_ARGS --gen-mutable) 67 | if(FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS) 68 | set(FLATC_SCHEMA_ARGS 69 | ${FLATBUFFERS_FLATC_SCHEMA_EXTRA_ARGS} 70 | ${FLATC_SCHEMA_ARGS} 71 | ) 72 | endif() 73 | 74 | set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}") 75 | 76 | set(schema_glob "*.fbs") 77 | # Generate the include files parameters. 78 | set(include_params "") 79 | set(all_generated_files "") 80 | foreach (include_dir ${schema_include_dirs}) 81 | set(include_params -I ${include_dir} ${include_params}) 82 | if (NOT ${copy_text_schemas_dir} STREQUAL "") 83 | # Copy text schemas from dependent folders. 84 | file(GLOB_RECURSE dependent_schemas ${include_dir}/${schema_glob}) 85 | foreach (dependent_schema ${dependent_schemas}) 86 | file(COPY ${dependent_schema} DESTINATION ${copy_text_schemas_dir}) 87 | endforeach() 88 | endif() 89 | endforeach() 90 | 91 | foreach(schema ${flatbuffers_schemas}) 92 | get_filename_component(filename ${schema} NAME_WE) 93 | # For each schema, do the things we requested. 94 | if (NOT ${generated_includes_dir} STREQUAL "") 95 | set(generated_include ${generated_includes_dir}/${filename}_generated.h) 96 | add_custom_command( 97 | OUTPUT ${generated_include} 98 | COMMAND ${FLATC} ${FLATC_SCHEMA_ARGS} 99 | -o ${generated_includes_dir} 100 | ${include_params} 101 | -c ${schema} 102 | DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies} 103 | WORKING_DIRECTORY "${working_dir}") 104 | list(APPEND all_generated_files ${generated_include}) 105 | endif() 106 | 107 | if (NOT ${binary_schemas_dir} STREQUAL "") 108 | set(binary_schema ${binary_schemas_dir}/${filename}.bfbs) 109 | add_custom_command( 110 | OUTPUT ${binary_schema} 111 | COMMAND ${FLATC} -b --schema 112 | -o ${binary_schemas_dir} 113 | ${include_params} 114 | ${schema} 115 | DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies} 116 | WORKING_DIRECTORY "${working_dir}") 117 | list(APPEND all_generated_files ${binary_schema}) 118 | endif() 119 | 120 | if (NOT ${copy_text_schemas_dir} STREQUAL "") 121 | file(COPY ${schema} DESTINATION ${copy_text_schemas_dir}) 122 | endif() 123 | endforeach() 124 | 125 | # Create a custom target that depends on all the generated files. 126 | # This is the target that you can depend on to trigger all these 127 | # to be built. 128 | add_custom_target(${custom_target_name} 129 | DEPENDS ${all_generated_files} ${additional_dependencies}) 130 | 131 | # Register the include directory we are using. 132 | if (NOT ${generated_includes_dir} STREQUAL "") 133 | include_directories(${generated_includes_dir}) 134 | set_property(TARGET ${custom_target_name} 135 | PROPERTY GENERATED_INCLUDES_DIR 136 | ${generated_includes_dir}) 137 | endif() 138 | 139 | # Register the binary schemas dir we are using. 140 | if (NOT ${binary_schemas_dir} STREQUAL "") 141 | set_property(TARGET ${custom_target_name} 142 | PROPERTY BINARY_SCHEMAS_DIR 143 | ${binary_schemas_dir}) 144 | endif() 145 | 146 | # Register the text schema copy dir we are using. 147 | if (NOT ${copy_text_schemas_dir} STREQUAL "") 148 | set_property(TARGET ${custom_target_name} 149 | PROPERTY COPY_TEXT_SCHEMAS_DIR 150 | ${copy_text_schemas_dir}) 151 | endif() 152 | endfunction() 153 | -------------------------------------------------------------------------------- /cmake/FindFlatBuffers.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Stefan.Eilemann@epfl.ch 2 | # Copyright 2014 Google Inc. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Find the flatbuffers schema compiler 17 | # 18 | # Output Variables: 19 | # * FLATBUFFERS_FLATC_EXECUTABLE the flatc compiler executable 20 | # * FLATBUFFERS_FOUND 21 | # 22 | # Provides: 23 | # * FLATBUFFERS_GENERATE_C_HEADERS(Name ) creates the C++ headers 24 | # for the given flatbuffer schema files. 25 | # Returns the header files in ${Name}_OUTPUTS 26 | 27 | set(FLATBUFFERS_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR}) 28 | 29 | find_program(FLATBUFFERS_FLATC_EXECUTABLE NAMES flatc) 30 | find_path(FLATBUFFERS_INCLUDE_DIR NAMES flatbuffers/flatbuffers.h) 31 | 32 | include(FindPackageHandleStandardArgs) 33 | find_package_handle_standard_args(flatbuffers 34 | DEFAULT_MSG FLATBUFFERS_FLATC_EXECUTABLE FLATBUFFERS_INCLUDE_DIR) 35 | 36 | if(FLATBUFFERS_FOUND) 37 | function(FLATBUFFERS_GENERATE_C_HEADERS Name) 38 | set(FLATC_OUTPUTS) 39 | foreach(FILE ${ARGN}) 40 | get_filename_component(FLATC_OUTPUT ${FILE} NAME_WE) 41 | set(FLATC_OUTPUT 42 | "${CMAKE_CURRENT_BINARY_DIR}/${FLATC_OUTPUT}_generated.h") 43 | list(APPEND FLATC_OUTPUTS ${FLATC_OUTPUT}) 44 | 45 | add_custom_command(OUTPUT ${FLATC_OUTPUT} 46 | COMMAND ${FLATBUFFERS_FLATC_EXECUTABLE} 47 | ARGS -c -o "${CMAKE_CURRENT_BINARY_DIR}/" ${FILE} 48 | DEPENDS ${FILE} 49 | COMMENT "Building C++ header for ${FILE}" 50 | WORKING_DIRECTORY ..) 51 | endforeach() 52 | set(${Name}_OUTPUTS ${FLATC_OUTPUTS} PARENT_SCOPE) 53 | endfunction() 54 | 55 | set(FLATBUFFERS_INCLUDE_DIRS ${FLATBUFFERS_INCLUDE_DIR}) 56 | include_directories(${CMAKE_BINARY_DIR}) 57 | else() 58 | set(FLATBUFFERS_INCLUDE_DIR) 59 | endif() 60 | 61 | include("${FLATBUFFERS_CMAKE_DIR}/BuildFlatBuffers.cmake") 62 | -------------------------------------------------------------------------------- /cmake/SigmfConfig.cmake.in: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # 3 | # Copyright 2019 DeepSig Inc. 4 | # 5 | # SPDX-License-Identifier: Apache 2.0 6 | # 7 | ######################################################################## 8 | 9 | set(SIGMF_FOUND TRUE) 10 | set(SIGMF_ROOT @CMAKE_INSTALL_PREFIX@) 11 | find_path( 12 | SIGMF_ROOT 13 | NAMES include/sigmf/sigmf.h 14 | PATHS /usr/local/include 15 | /usr/include 16 | /usr/local/opt/sigmf/ 17 | $ENV{SIGMF_ROOT} 18 | ${SIGMF_ROOT} 19 | ) 20 | set(SIGMF_INCLUDE_DIR ${SIGMF_ROOT}/include) 21 | set(SIGMF_INCLUDE_GEN_DIR ${SIGMF_ROOT}/include/sigmf/) 22 | set(SIGMF_FLATBUFFERS_INCLUDE_DIR ${SIGMF_ROOT}/include/sigmf/external/) 23 | set(SIGMF_JSON_INCLUDE_DIR ${SIGMF_ROOT}/include/sigmf/external/) 24 | set(SIGMF_INCLUDE_DIRS ${SIGMF_INCLUDE_DIR} ${SIGMF_FLATBUFFERS_INCLUDE_DIR} ${SIGMF_JSON_INCLUDE_DIR} ${SIGMF_INCLUDE_GEN_DIR}) 25 | message(STATUS "Found Sigmf root: " ${SIGMF_ROOT}) 26 | -------------------------------------------------------------------------------- /cmake/config.cmake.in: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # 3 | # Copyright 2019 DeepSig Inc. 4 | # 5 | # SPDX-License-Identifier: Apache 2.0 6 | # 7 | ######################################################################## 8 | include(FindPackageHandleStandardArgs) 9 | set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG ${CMAKE_CURRENT_LIST_FILE}) 10 | find_package_handle_standard_args(@PROJECT_NAME@ CONFIG_MODE) 11 | 12 | if(NOT TARGET @PROJECT_NAME@::@LIBSIGMF_TARGET_NAME@) 13 | include(CMakeFindDependencyMacro) 14 | 15 | find_dependency(nlohmann_json REQUIRED) 16 | find_dependency(Flatbuffers REQUIRED) 17 | include("${CMAKE_CURRENT_LIST_DIR}/@LIBSIGMF_TARGETS_EXPORT_NAME@.cmake") 18 | endif() 19 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | 2 | # libsigmf 3 | 4 | libsigmf is a C++ library for working with [SigMF](https://github.com/gnuradio/sigmf) records. The primary 5 | design goals are to be flexible with mixing SigMF namesapces using static types so that errors in namespace 6 | usage can be caught at compile time, memory usage is low while working with objects, and accessing fields 7 | has low overhead. 8 | 9 | To accomplish this we have taken advantage of the C preprocessor and C++ templates. The result allows creating 10 | objects like so 11 | -------------------------------------------------------------------------------- /docs/license.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | ============== 3 | 4 | _Version 2.0, January 2004_ 5 | _<>_ 6 | 7 | ### Terms and Conditions for use, reproduction, and distribution 8 | 9 | #### 1. Definitions 10 | 11 | “License” shall mean the terms and conditions for use, reproduction, and 12 | distribution as defined by Sections 1 through 9 of this document. 13 | 14 | “Licensor” shall mean the copyright owner or entity authorized by the copyright 15 | owner that is granting the License. 16 | 17 | “Legal Entity” shall mean the union of the acting entity and all other entities 18 | that control, are controlled by, or are under common control with that entity. 19 | For the purposes of this definition, “control” means **(i)** the power, direct or 20 | indirect, to cause the direction or management of such entity, whether by 21 | contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the 22 | outstanding shares, or **(iii)** beneficial ownership of such entity. 23 | 24 | “You” (or “Your”) shall mean an individual or Legal Entity exercising 25 | permissions granted by this License. 26 | 27 | “Source” form shall mean the preferred form for making modifications, including 28 | but not limited to software source code, documentation source, and configuration 29 | files. 30 | 31 | “Object” form shall mean any form resulting from mechanical transformation or 32 | translation of a Source form, including but not limited to compiled object code, 33 | generated documentation, and conversions to other media types. 34 | 35 | “Work” shall mean the work of authorship, whether in Source or Object form, made 36 | available under the License, as indicated by a copyright notice that is included 37 | in or attached to the work (an example is provided in the Appendix below). 38 | 39 | “Derivative Works” shall mean any work, whether in Source or Object form, that 40 | is based on (or derived from) the Work and for which the editorial revisions, 41 | annotations, elaborations, or other modifications represent, as a whole, an 42 | original work of authorship. For the purposes of this License, Derivative Works 43 | shall not include works that remain separable from, or merely link (or bind by 44 | name) to the interfaces of, the Work and Derivative Works thereof. 45 | 46 | “Contribution” shall mean any work of authorship, including the original version 47 | of the Work and any modifications or additions to that Work or Derivative Works 48 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 49 | by the copyright owner or by an individual or Legal Entity authorized to submit 50 | on behalf of the copyright owner. For the purposes of this definition, 51 | “submitted” means any form of electronic, verbal, or written communication sent 52 | to the Licensor or its representatives, including but not limited to 53 | communication on electronic mailing lists, source code control systems, and 54 | issue tracking systems that are managed by, or on behalf of, the Licensor for 55 | the purpose of discussing and improving the Work, but excluding communication 56 | that is conspicuously marked or otherwise designated in writing by the copyright 57 | owner as “Not a Contribution.” 58 | 59 | “Contributor” shall mean Licensor and any individual or Legal Entity on behalf 60 | of whom a Contribution has been received by Licensor and subsequently 61 | incorporated within the Work. 62 | 63 | #### 2. Grant of Copyright License 64 | 65 | Subject to the terms and conditions of this License, each Contributor hereby 66 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 67 | irrevocable copyright license to reproduce, prepare Derivative Works of, 68 | publicly display, publicly perform, sublicense, and distribute the Work and such 69 | Derivative Works in Source or Object form. 70 | 71 | #### 3. Grant of Patent License 72 | 73 | Subject to the terms and conditions of this License, each Contributor hereby 74 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 75 | irrevocable (except as stated in this section) patent license to make, have 76 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 77 | such license applies only to those patent claims licensable by such Contributor 78 | that are necessarily infringed by their Contribution(s) alone or by combination 79 | of their Contribution(s) with the Work to which such Contribution(s) was 80 | submitted. If You institute patent litigation against any entity (including a 81 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 82 | Contribution incorporated within the Work constitutes direct or contributory 83 | patent infringement, then any patent licenses granted to You under this License 84 | for that Work shall terminate as of the date such litigation is filed. 85 | 86 | #### 4. Redistribution 87 | 88 | You may reproduce and distribute copies of the Work or Derivative Works thereof 89 | in any medium, with or without modifications, and in Source or Object form, 90 | provided that You meet the following conditions: 91 | 92 | * **(a)** You must give any other recipients of the Work or Derivative Works a copy of 93 | this License; and 94 | * **(b)** You must cause any modified files to carry prominent notices stating that You 95 | changed the files; and 96 | * **(c)** You must retain, in the Source form of any Derivative Works that You distribute, 97 | all copyright, patent, trademark, and attribution notices from the Source form 98 | of the Work, excluding those notices that do not pertain to any part of the 99 | Derivative Works; and 100 | * **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any 101 | Derivative Works that You distribute must include a readable copy of the 102 | attribution notices contained within such NOTICE file, excluding those notices 103 | that do not pertain to any part of the Derivative Works, in at least one of the 104 | following places: within a NOTICE text file distributed as part of the 105 | Derivative Works; within the Source form or documentation, if provided along 106 | with the Derivative Works; or, within a display generated by the Derivative 107 | Works, if and wherever such third-party notices normally appear. The contents of 108 | the NOTICE file are for informational purposes only and do not modify the 109 | License. You may add Your own attribution notices within Derivative Works that 110 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 111 | provided that such additional attribution notices cannot be construed as 112 | modifying the License. 113 | 114 | You may add Your own copyright statement to Your modifications and may provide 115 | additional or different license terms and conditions for use, reproduction, or 116 | distribution of Your modifications, or for any such Derivative Works as a whole, 117 | provided Your use, reproduction, and distribution of the Work otherwise complies 118 | with the conditions stated in this License. 119 | 120 | #### 5. Submission of Contributions 121 | 122 | Unless You explicitly state otherwise, any Contribution intentionally submitted 123 | for inclusion in the Work by You to the Licensor shall be under the terms and 124 | conditions of this License, without any additional terms or conditions. 125 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 126 | any separate license agreement you may have executed with Licensor regarding 127 | such Contributions. 128 | 129 | #### 6. Trademarks 130 | 131 | This License does not grant permission to use the trade names, trademarks, 132 | service marks, or product names of the Licensor, except as required for 133 | reasonable and customary use in describing the origin of the Work and 134 | reproducing the content of the NOTICE file. 135 | 136 | #### 7. Disclaimer of Warranty 137 | 138 | Unless required by applicable law or agreed to in writing, Licensor provides the 139 | Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, 140 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 141 | including, without limitation, any warranties or conditions of TITLE, 142 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 143 | solely responsible for determining the appropriateness of using or 144 | redistributing the Work and assume any risks associated with Your exercise of 145 | permissions under this License. 146 | 147 | #### 8. Limitation of Liability 148 | 149 | In no event and under no legal theory, whether in tort (including negligence), 150 | contract, or otherwise, unless required by applicable law (such as deliberate 151 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 152 | liable to You for damages, including any direct, indirect, special, incidental, 153 | or consequential damages of any character arising as a result of this License or 154 | out of the use or inability to use the Work (including but not limited to 155 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 156 | any and all other commercial damages or losses), even if such Contributor has 157 | been advised of the possibility of such damages. 158 | 159 | #### 9. Accepting Warranty or Additional Liability 160 | 161 | While redistributing the Work or Derivative Works thereof, You may choose to 162 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 163 | other liability obligations and/or rights consistent with this License. However, 164 | in accepting such obligations, You may act only on Your own behalf and on Your 165 | sole responsibility, not on behalf of any other Contributor, and only if You 166 | agree to indemnify, defend, and hold each Contributor harmless for any liability 167 | incurred by, or claims asserted against, such Contributor by reason of your 168 | accepting any such warranty or additional liability. 169 | 170 | _END OF TERMS AND CONDITIONS_ 171 | 172 | ### APPENDIX: How to apply the Apache License to your work 173 | 174 | To apply the Apache License to your work, attach the following boilerplate 175 | notice, with the fields enclosed by brackets `[]` replaced with your own 176 | identifying information. (Don't include the brackets!) The text should be 177 | enclosed in the appropriate comment syntax for the file format. We also 178 | recommend that a file or class name and description of purpose be included on 179 | the same “printed page” as the copyright notice for easier identification within 180 | third-party archives. 181 | 182 | Copyright [yyyy] [name of copyright owner] 183 | 184 | Licensed under the Apache License, Version 2.0 (the "License"); 185 | you may not use this file except in compliance with the License. 186 | You may obtain a copy of the License at 187 | 188 | http://www.apache.org/licenses/LICENSE-2.0 189 | 190 | Unless required by applicable law or agreed to in writing, software 191 | distributed under the License is distributed on an "AS IS" BASIS, 192 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 193 | See the License for the specific language governing permissions and 194 | limitations under the License. 195 | 196 | 197 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | # This is the bare minimum to use libsigmf along with some example usage patterns 4 | add_executable(example_record_with_variadic_dataclass 5 | example_record_with_variadic_dataclass.cpp) 6 | target_link_libraries(example_record_with_variadic_dataclass libsigmf) 7 | target_include_directories(example_record_with_variadic_dataclass PRIVATE ${CMAKE_BINARY_DIR}/include) 8 | 9 | add_executable(example_record_with_multiple_namespaces example_record_with_multiple_namespaces.cpp) 10 | target_link_libraries(example_record_with_multiple_namespaces libsigmf) 11 | target_include_directories(example_record_with_multiple_namespaces PRIVATE ${CMAKE_BINARY_DIR}/include) 12 | 13 | add_executable(example_sigmf_json_roundtrip example_sigmf_json_roundtrip.cpp) 14 | target_link_libraries(example_sigmf_json_roundtrip libsigmf) 15 | target_include_directories(example_sigmf_json_roundtrip PRIVATE ${CMAKE_BINARY_DIR}/include) 16 | 17 | add_executable(example_reading_sigmf_file example_reading_sigmf_file.cpp) 18 | target_link_libraries(example_reading_sigmf_file libsigmf) 19 | target_include_directories(example_reading_sigmf_file PRIVATE ${CMAKE_BINARY_DIR}/include) 20 | 21 | add_test(NAME simple_variadic_sigmf_to_json 22 | COMMAND example_record_with_variadic_dataclass) 23 | add_test(NAME simple_variadic_2ns_sigmf_to_json 24 | COMMAND example_record_with_multiple_namespaces) 25 | 26 | 27 | # This demonstrates some of the features of flatbuffers we use internally to libsigmf. This is primaryily useful to 28 | # experiment / understand the libsigmf internals on concrete flatbuffers types outside of the heavily templated 29 | # VariadicDataClass 30 | 31 | add_executable(flatbuffer_patterns flatbuffer_patterns.cpp) 32 | target_link_libraries(flatbuffer_patterns libsigmf) 33 | target_include_directories(flatbuffer_patterns PRIVATE ${CMAKE_BINARY_DIR}/include) 34 | -------------------------------------------------------------------------------- /examples/example.sigmf-meta: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": [ 3 | { 4 | "core:description": "signal1", 5 | "core:freq_lower_edge": 443062254.4144396, 6 | "core:freq_upper_edge": 443106250.0, 7 | "core:sample_count": 571392, 8 | "core:sample_start": 2497536 9 | }, 10 | { 11 | "signal:detail": { 12 | "type": "digital", 13 | "duplexing": "ofdm" 14 | }, 15 | "signal:emitter": { 16 | "seid": 123, 17 | "manufacturer": "DeepSig Inc.", 18 | "power_tx": 30.0, 19 | "power_eirp": 36.1, 20 | "geolocation": { 21 | "type": "point", 22 | "coordinates": [ 0, 0 ] 23 | } 24 | }, 25 | "core:description": "signal1", 26 | "core:freq_lower_edge": 444156250.0, 27 | "core:freq_upper_edge": 444198750.0, 28 | "core:sample_count": 718848, 29 | "core:sample_start": 961536 30 | } 31 | ], 32 | "captures": [ 33 | { 34 | "core:frequency": 440000000.0, 35 | "core:global_index": 0, 36 | "core:sample_start": 0 37 | } 38 | ], 39 | "global": { 40 | "antenna:horizontal_gain_pattern": [ 0.1, 0.2, 0.3 ], 41 | "antenna:mobile": false, 42 | "core:author": "DeepSig Inc.", 43 | "core:datatype": "ci16_le", 44 | "core:description": "example sigmf-meta file with a wide range of fields and extensions", 45 | "core:extensions": [ 46 | { "name": "antenna", "optional": false, "version": "1.0.0" }, 47 | { "name": "capture_details", "optional": false, "version": "1.0.0" }, 48 | { "name": "signal", "optional": false, "version": "1.0.0" } 49 | ], 50 | "core:geolocation": { 51 | "coordinates": [ 12.34, 43.21, 0.99 ], 52 | "type": "point" 53 | }, 54 | "core:license": "Apache License, Version 2.0", 55 | "core:metadata_only": true, 56 | "core:sample_rate": 30720000.0, 57 | "core:version": "0.0.1" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /examples/example2.sigmf-meta: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": [ 3 | { 4 | "core:description": "signal1", 5 | "core:freq_lower_edge": 4.4306225441443962E+8, 6 | "core:freq_upper_edge": 4.4310625E+8, 7 | "core:sample_start": 2.497536E+6, 8 | "core:sample_count": 571392 9 | }, 10 | { 11 | "core:sample_start": 961536, 12 | "core:sample_count": 718848 13 | } 14 | ], 15 | "captures": [ 16 | { 17 | "core:global_index": 0, 18 | "core:sample_start": 0 19 | } 20 | ], 21 | "global":{ 22 | "core:datatype": "ci16_le", 23 | "core:description": "minimal sigmf-meta example using only `core` fields", 24 | "core:license": "Apache License, Version 2.0", 25 | "core:metadata_only": true 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/example_reading_sigmf_file.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2021, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "sigmf_core_generated.h" 18 | #include "sigmf_antenna_generated.h" 19 | #include "sigmf_capture_details_generated.h" 20 | #include "sigmf_signal_generated.h" 21 | #include "sigmf.h" 22 | #include "sigmf_helpers.h" 23 | #include 24 | #include 25 | 26 | int main(int argc, char* argv[]) { 27 | std::cout << "Reading file " << argv[1] << std::endl;; 28 | auto meta_fstream = std::ifstream(argv[1]); 29 | 30 | // returns a sigmf object 31 | auto record = sigmf::metadata_file_to_json(meta_fstream); 32 | 33 | std::cout << "The data size is " << sigmf::get_sample_size(record->global.access().datatype) << " bytes\n"; 34 | 35 | std::cout << "The record we read is: \n" << 36 | record->to_json().dump(2) << std::endl; 37 | 38 | std::cout << "example_reading_sigmf_file passed (just a smoke test, no field validation)" << std::endl; 39 | return 0; // assert passed, we're good :+1: 40 | } 41 | -------------------------------------------------------------------------------- /examples/example_record_with_multiple_namespaces.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2021, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "sigmf_core_generated.h" 18 | #include "sigmf_antenna_generated.h" 19 | #include "sigmf_capture_details_generated.h" 20 | #include "sigmf_signal_generated.h" 21 | #include "sigmf.h" 22 | #include "testing_protocols_generated.h" 23 | 24 | using namespace sigmf; 25 | 26 | int main() { 27 | 28 | /* 29 | * Create a record with 2 namespace available in it. Note that antenna namespace doesnt have capture segments. 30 | * Also use this to show off using the sigmf::Global, sigmf::Capture, and sigmf::Annotation classes. These 31 | * classes are light wrappers around the sigmf::VariadicDataClass but make it easier to express intent of 32 | * what kind of stuff (in sigmf-lingo) the underlying class is supposed to hold. 33 | */ 34 | sigmf::SigMF, 35 | sigmf::Capture, 36 | sigmf::Annotation > latest_record; 37 | latest_record.global.access().author = "Nathan"; 38 | latest_record.global.access().description = "Example of creating a new record"; 39 | latest_record.global.access().sample_rate = 1.0; 40 | latest_record.global.access().mobile = true; 41 | latest_record.global.access().gain = 40.0; 42 | latest_record.global.access().low_frequency = 600e6; 43 | latest_record.global.access().high_frequency = 1200e6; 44 | latest_record.global.access().vertical_gain_pattern = {-40,-40,-40,0,10,0,-40,-40,-40}; 45 | 46 | // Add a capture segment 47 | auto antenna_capture = sigmf::Capture(); 48 | antenna_capture.get().frequency = 870e6; 49 | antenna_capture.get().global_index = 0; 50 | latest_record.captures.emplace_back(antenna_capture); 51 | 52 | auto &fancy_capture = latest_record.captures.create_new(); 53 | auto &fancy_cap_core = fancy_capture.get(); 54 | fancy_cap_core.datetime = "the future"; 55 | fancy_cap_core.sample_start = 9001; 56 | 57 | 58 | // Add some annotations (sigmf::core_annotations is typedef of core::AnnotationT, so they're interchangeable) 59 | // This example uses the core::AnnotationT to access data elements which is more using the VariadicDataClass interface 60 | auto anno2 = sigmf::Annotation(); 61 | anno2.access().sample_count = 500000; 62 | anno2.access().description = "Annotation 1"; 63 | anno2.access().generator = "libsigmf"; 64 | anno2.access().description = "Woah!"; 65 | latest_record.annotations.emplace_back(anno2); 66 | 67 | // This example shows off using the Annotation-specific interface where we know it's an annotation, so we 68 | // get annotation field from the underlying DescrT... This uses a little bit of syntactic sugar on top of 69 | // the VariadicDataClass and basically you don't have to repeat "annotation" in your get/access method. 70 | auto anno3 = sigmf::Annotation(); 71 | anno3.get().sample_count = 600000; 72 | anno3.get().description = "Annotation 2"; 73 | anno3.get().generator = "libsigmf"; 74 | anno3.get().description = "Pretty easy"; 75 | anno3.get().elevation_angle = 4.2; 76 | // here are some examples of how to initialize subtable fields: 77 | signal::signal_detailT detail_obj; 78 | detail_obj.type = std::string("analog"); 79 | detail_obj.duplexing = std::string("fdm"); 80 | anno3.get().detail = std::make_shared(detail_obj); 81 | core::geojson_pointT anno3_geo; 82 | anno3_geo.type = "point"; 83 | anno3_geo.coordinates = std::vector( { 98, 123.4, 1e-9} ); 84 | signal::signal_emitterT emitter_obj; 85 | emitter_obj.manufacturer = std::string("deepsig"); 86 | emitter_obj.power_tx = 27.1; 87 | emitter_obj.geolocation = std::make_shared(anno3_geo); 88 | anno3.get().emitter = std::make_shared(emitter_obj); 89 | // You can also drop in this syntactic acid using this interface which I personally don't really like because 90 | // it mixes real calls with macros without it being obvious and doesn't really feel like c++ 91 | anno3.sigmfns(antenna).azimuth_angle = 0.1; 92 | anno3.get().polarization = "circular"; 93 | anno3.get().SNRdB = 12.34; 94 | 95 | latest_record.annotations.emplace_back(anno3); 96 | 97 | 98 | auto expected_json = R"({ 99 | "annotations": [ 100 | { 101 | "core:description": "Woah!", 102 | "core:generator": "libsigmf", 103 | "core:sample_count": 500000 104 | }, 105 | { 106 | "antenna:azimuth_angle": 0.1, 107 | "antenna:elevation_angle": 4.2, 108 | "antenna:polarization": "circular", 109 | "capture_details:SNRdB": 12.34, 110 | "core:description": "Pretty easy", 111 | "core:generator": "libsigmf", 112 | "core:sample_count": 600000, 113 | "signal:detail": { 114 | "duplexing": "fdm", 115 | "type": "analog" 116 | }, 117 | "signal:emitter": { 118 | "geolocation": { 119 | "coordinates": [ 120 | 98.0, 121 | 123.4, 122 | 1e-09 123 | ], 124 | "type": "point" 125 | }, 126 | "manufacturer": "deepsig", 127 | "power_tx": 27.1 128 | } 129 | } 130 | ], 131 | "captures": [ 132 | { 133 | "core:frequency": 870000000.0, 134 | "core:global_index": 0 135 | }, 136 | { 137 | "core:datetime": "the future", 138 | "core:sample_start": 9001 139 | } 140 | ], 141 | "global": { 142 | "antenna:gain": 40.0, 143 | "antenna:high_frequency": 1200000000.0, 144 | "antenna:low_frequency": 600000000.0, 145 | "antenna:mobile": true, 146 | "antenna:vertical_gain_pattern": [ 147 | -40.0, 148 | -40.0, 149 | -40.0, 150 | 0.0, 151 | 10.0, 152 | 0.0, 153 | -40.0, 154 | -40.0, 155 | -40.0 156 | ], 157 | "core:author": "Nathan", 158 | "core:description": "Example of creating a new record", 159 | "core:sample_rate": 1.0 160 | } 161 | })"; 162 | 163 | // std::cout << "JSON Record:\n" << json(latest_record).dump(2) << std::endl; 164 | assert(expected_json == json(latest_record).dump(2)); 165 | 166 | std::cout << "example_record_with_multiple_namespaces passed" << std::endl; 167 | return 0; // assert passed, we're good :+1: 168 | } 169 | 170 | -------------------------------------------------------------------------------- /examples/example_record_with_variadic_dataclass.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2021, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include "sigmf_core_generated.h" 19 | #include "sigmf.h" 20 | #include 21 | 22 | using namespace sigmf; 23 | 24 | int main() { 25 | /* 26 | * Create a record with core namespace using the VariadicDataClass as an example. This is kind of 27 | * like a "pure" usage of the variadic data class lightly wrapped together with our SigMF object. 28 | * The suggested usage for SigMF purposes is that you do not directly use sigmf::VariadticDataClass<...> 29 | * but instead use the more descriptive sigmf::Annotation, sigmf::Capture, sigmf::Global classes. 30 | */ 31 | sigmf::SigMF, 32 | sigmf::VariadicDataClass, 33 | sigmf::VariadicDataClass > example_record; 34 | 35 | example_record.global.access().author = "Nathan"; 36 | example_record.global.access().description = "Example of creating a new record"; 37 | example_record.global.access().sample_rate = 1.0; 38 | 39 | // Add a capture segment 40 | auto new_capture = sigmf::VariadicDataClass(); 41 | new_capture.access().frequency = 870e6; 42 | new_capture.access().global_index = 5000; 43 | new_capture.access().sample_start = 10; 44 | new_capture.access().datetime = "now"; 45 | example_record.captures.emplace_back(new_capture); 46 | 47 | // Add some annotations 48 | auto anno0 = sigmf::VariadicDataClass(); 49 | anno0.access().description = "Annotation 1"; 50 | anno0.access().generator = "libsigmf"; 51 | anno0.access().description = "Woah!"; 52 | auto &ref = anno0.access(); 53 | // You can get it once at keep a reference if you want 54 | ref.comment = "References make it a bit easier to access and modify the data parts"; 55 | ref.sample_count = 500000; 56 | example_record.annotations.emplace_back(anno0); 57 | 58 | auto anno1 = sigmf::VariadicDataClass(); 59 | anno1.access().sample_count = 600000; 60 | anno1.access().description = "Annotation 2"; 61 | anno1.access().generator = "libsigmf"; 62 | anno1.access().description = "Pretty easy"; 63 | example_record.annotations.emplace_back(anno1); 64 | 65 | // You can also use reference_wrappers to make it slightly less verbose... 66 | auto anno2 = sigmf::VariadicDataClass(); 67 | auto core_anno_ref = std::ref(anno1.access()); 68 | core_anno_ref.get().sample_count = 100000; 69 | core_anno_ref.get().description = "ref-wrapped"; 70 | 71 | auto anno3 = sigmf::VariadicDataClass(); 72 | core_anno_ref = std::ref(anno3.access()); 73 | // Notice we didn't push anno2 or anno3 on to the annotations vector, so they aren't part of the record 74 | 75 | // Make it a json (from modernjson) object and verify its output 76 | std::stringstream json_output; 77 | json_output << json(example_record).dump(2) << std::flush; 78 | 79 | std::string expected_output = R"({ 80 | "annotations": [ 81 | { 82 | "core:comment": "References make it a bit easier to access and modify the data parts", 83 | "core:description": "Woah!", 84 | "core:generator": "libsigmf", 85 | "core:sample_count": 500000 86 | }, 87 | { 88 | "core:description": "Pretty easy", 89 | "core:generator": "libsigmf", 90 | "core:sample_count": 600000 91 | } 92 | ], 93 | "captures": [ 94 | { 95 | "core:datetime": "now", 96 | "core:frequency": 870000000.0, 97 | "core:global_index": 5000, 98 | "core:sample_start": 10 99 | } 100 | ], 101 | "global": { 102 | "core:author": "Nathan", 103 | "core:description": "Example of creating a new record", 104 | "core:sample_rate": 1.0 105 | } 106 | })"; 107 | 108 | // std::cout << "JSON Record:\n" << json_output.str() << std::endl; 109 | assert(expected_output == json_output.str()); 110 | 111 | std::cout << "expected_record_with_variadic_dataclass passed" << std::endl; 112 | return 0; // assert passed, we're good :+1: 113 | } 114 | -------------------------------------------------------------------------------- /examples/example_sigmf_json_roundtrip.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2021, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "sigmf.h" 18 | #include 19 | 20 | using namespace sigmf; 21 | 22 | int main() { 23 | 24 | 25 | /* 26 | * this test will fail right now because the annotation core:sample_count field 27 | * is still not truly optional (default = 0). adding `=null` to this field will 28 | * make this test pass demonstrating the std::optional scalar field operation. 29 | */ 30 | 31 | 32 | std::string starting_str(R"({ 33 | "annotations": [ 34 | { 35 | "core:description": "no fish", 36 | "core:sample_count": 0, 37 | "core:sample_start": 0 38 | }, 39 | { 40 | "core:description": "one fish", 41 | "core:sample_count": 1, 42 | "core:sample_start": 1 43 | }, 44 | { 45 | "core:description": "two fish", 46 | "core:sample_count": 2, 47 | "core:sample_start": 2 48 | }, 49 | { 50 | "core:description": "red fish", 51 | "core:freq_lower_edge": 0.0, 52 | "core:freq_upper_edge": 100000000.0, 53 | "core:sample_count": 3, 54 | "core:sample_start": 3 55 | }, 56 | { 57 | "core:description": "blue fish", 58 | "core:sample_count": 4, 59 | "core:sample_start": 4 60 | } 61 | ], 62 | "captures": [ 63 | { 64 | "core:frequency": 99999.1, 65 | "core:sample_start": 0 66 | }, 67 | { 68 | "core:frequency": 99999.2, 69 | "core:sample_start": 42 70 | } 71 | ], 72 | "global": { 73 | "antenna:mobile": false, 74 | "antenna:vertical_gain_pattern": [ 75 | 0.0, 76 | 1.0, 77 | 6.0, 78 | 10.0, 79 | 6.0, 80 | 1.0, 81 | 0.0 82 | ], 83 | "core:author": "DeepSig", 84 | "core:description": "Round-trip from json -> libsigmf -> back", 85 | "core:extensions": [ 86 | { 87 | "name": "fake_extension_1", 88 | "optional": false, 89 | "version": "0.1.2.3.4.5.6" 90 | }, 91 | { 92 | "name": "another fake ext", 93 | "optional": true, 94 | "version": "2" 95 | } 96 | ], 97 | "core:geolocation": { 98 | "coordinates": [ 99 | 12.34, 100 | 5.678, 101 | 9.0 102 | ], 103 | "type": "point" 104 | }, 105 | "core:sample_rate": 1000000.0 106 | } 107 | })"); 108 | 109 | auto as_json = json::parse(starting_str); 110 | sigmf::SigMF, 111 | sigmf::Capture, 112 | sigmf::Annotation > roundtripstuff = as_json; 113 | 114 | 115 | auto back_to_json = json(roundtripstuff); 116 | 117 | std::cout << back_to_json.dump(4) << std::endl; 118 | assert(back_to_json.dump(4) == starting_str); 119 | 120 | std::cout << "example_sigmf_json_roundtrip passed" << std::endl; 121 | return 0; // assert passed, we're good :+1: 122 | } 123 | -------------------------------------------------------------------------------- /examples/flatbuffer_patterns.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "flatbuffers/minireflect.h" // For flatbuffers::FlatBufferToString 18 | #include "sigmf_core_generated.h" 19 | #include "testing_protocols_generated.h" 20 | #include 21 | #include 22 | 23 | using namespace sigmf; 24 | 25 | int main() { 26 | // 27 | // The standard way of dealing with flatbuffers... 28 | // 29 | // You have to create a FlatBufferBuilder which manages the memory and has generic mutators for all of flatbuffer's internal types 30 | flatbuffers::FlatBufferBuilder fbb; 31 | // This is a Builder for our type-- you need to give it a FlatBufferBuilder 32 | // This basically knows how to translate our named fields in to flatbuffer's internal types/field indexes 33 | core::AnnotationBuilder abb(fbb); 34 | // Now we can set some field 35 | abb.add_freq_lower_edge(30.0); 36 | 37 | // When you're done adding data you finish your buffer 38 | flatbuffers::Offset offset_in_buffer = abb.Finish(); 39 | // Now you have to finish the original buffer by telling it the offset (basically how big our type is) 40 | fbb.Finish(offset_in_buffer); 41 | 42 | // Now you can get an object back from the original FlatBufferBuilder using a templated GetRoot... 43 | const core::Annotation *anno = flatbuffers::GetRoot(fbb.GetBufferPointer()); 44 | // And inspect the values you put it 45 | std::cout << anno->freq_lower_edge().value_or(-1) << std::endl; 46 | 47 | // 48 | // Adding more complex types (strings, composite types,... ) 49 | // 50 | flatbuffers::FlatBufferBuilder composite_fbb; 51 | uint32_t vvv[] = {1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1}; 52 | std::cout << "vec has size " << sizeof(vvv) / sizeof(uint32_t) << std::endl; 53 | auto vecoffset = composite_fbb.CreateVector(vvv, sizeof(vvv) / sizeof(uint32_t)); 54 | 55 | auto stroffset = composite_fbb.CreateString("testing one two"); 56 | std::vector > nativevecstr = {composite_fbb.CreateString("one"), 57 | composite_fbb.CreateString("two"), 58 | composite_fbb.CreateString("thre")}; 59 | 60 | auto vecofstrings = composite_fbb.CreateVector(nativevecstr); 61 | // need Offset > > > 62 | 63 | testing_vecsBuilder vecbuilder(composite_fbb); 64 | vecbuilder.add_myvecfortesting(vecoffset); 65 | vecbuilder.add_name(stroffset); 66 | auto testvecadded = vecbuilder.Finish(); 67 | composite_fbb.Finish(testvecadded); 68 | 69 | const testing_vecs *vecs = flatbuffers::GetRoot(composite_fbb.GetBufferPointer()); 70 | std::cout << "O: " << flatbuffers::FlatBufferToString(composite_fbb.GetBufferPointer(), testing_vecsTypeTable()) 71 | << std::endl; 72 | 73 | 74 | 75 | // 76 | // Now there is also the object API which we use exclusively in libsigmf.... 77 | // 78 | core::AnnotationT annotation_object; 79 | annotation_object.generator = "this is much easier"; 80 | annotation_object.sample_count = 1; 81 | // To get a transportable (encoded) flatbuffer you need to pack it with a flatbuffer... 82 | flatbuffers::FlatBufferBuilder fbb2; 83 | // (A core::Annotation is a core::AnnotationT::TableType, but it's exposed through the object API) 84 | // From the object, you need to pack it in to a FlatBufferBuilder and Finish that 85 | auto offset = core::AnnotationT::TableType::Pack(fbb2, &annotation_object); // this is a static method 86 | fbb2.Finish(offset); 87 | std::cout << "presumably we would transmit starting at fbb2.GetBufferPointer() for " << fbb2.GetSize() << " B" 88 | << std::endl; 89 | std::cout << "O: " << flatbuffers::FlatBufferToString(fbb2.GetBufferPointer(), 90 | core::AnnotationT::TableType::MiniReflectTypeTable()) 91 | << std::endl; 92 | // If you want to access that buffer as a core::Annotation... 93 | const core::AnnotationT::TableType *packed_anno = flatbuffers::GetRoot( 94 | fbb2.GetBufferPointer()); 95 | std::cout << packed_anno->generator()->c_str() << std::endl; 96 | 97 | 98 | // 99 | // For the more generic building case we can just use the enums to fill the fbb 100 | // 101 | flatbuffers::FlatBufferBuilder generic_fbb; 102 | auto strloc = generic_fbb.CreateString("glarble"); 103 | auto startoftable = generic_fbb.StartTable(); 104 | generic_fbb.AddElement(core::AnnotationT::TableType::VT_FREQ_LOWER_EDGE, double(4.0), double(0.0)); 105 | generic_fbb.AddElement(core::AnnotationT::TableType::VT_FREQ_UPPER_EDGE, double(5.0), double(0.0)); 106 | generic_fbb.AddOffset(core::AnnotationT::TableType::VT_GENERATOR, strloc); 107 | auto endoftable = generic_fbb.EndTable(startoftable); 108 | generic_fbb.Finish(flatbuffers::Offset(endoftable)); 109 | const core::AnnotationT::TableType *generic_anno = flatbuffers::GetRoot( 110 | generic_fbb.GetBufferPointer()); 111 | std::cout << generic_anno->freq_lower_edge().value_or(-1) << std::endl; 112 | std::cout << generic_anno->freq_upper_edge().value_or(-1) << std::endl; 113 | std::cout << generic_anno->generator()->c_str() << std::endl; 114 | 115 | } 116 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | 2 | site_name: libsigmf 3 | site_url: https://pages.gitlab.io/deepsig/opensource/libsigmf 4 | repo_url: https://github.com/deepsig/opensource/libsigmf/ 5 | 6 | theme: 7 | name: readthedocs 8 | 9 | nav: 10 | - Home: 'index.md' 11 | - License: 'license.md' 12 | -------------------------------------------------------------------------------- /performance.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "subject": "/gitlab-org/gitlab-ce/issues/1", 4 | "metrics": [ 5 | { 6 | "name": "Transfer Size (KB)", 7 | "value": "1529.2", 8 | "desiredSize": "smaller" 9 | }, 10 | { 11 | "name": "Speed Index", 12 | "value": 1162, 13 | "desiredSize": "smaller" 14 | }, 15 | { 16 | "name": "Total Score", 17 | "value": 57, 18 | "desiredSize": "larger" 19 | }, 20 | { 21 | "name": "Requests", 22 | "value": 41, 23 | "desiredSize": "smaller" 24 | } 25 | ] 26 | }, 27 | { 28 | "subject": "/gitlab-org/gitlab-ee/merge_requests/3507", 29 | "metrics": [ 30 | { 31 | "name": "Transfer Size (KB)", 32 | "value": "2399.8", 33 | "desiredSize": "smaller" 34 | }, 35 | { 36 | "name": "Speed Index", 37 | "value": 3122, 38 | "desiredSize": "smaller" 39 | }, 40 | { 41 | "name": "Total Score", 42 | "value": 53, 43 | "desiredSize": "larger" 44 | }, 45 | { 46 | "name": "Requests", 47 | "value": 41, 48 | "desiredSize": "smaller" 49 | } 50 | ] 51 | } 52 | ] 53 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_adsb.fbs: -------------------------------------------------------------------------------- 1 | 2 | namespace sigmf.adsb; 3 | 4 | table Global { /*`adsb` does not extend `global`*/ } 5 | 6 | table Capture { /*`adsb` does not extend `captures`*/ } 7 | 8 | table Annotation { 9 | standard:string; 10 | frame_type_phy:string; 11 | channel:long=null; 12 | start_time_s:double=null; 13 | stop_time_s:double=null; 14 | frame_duration_s:double=null; 15 | MCS:double=null; 16 | MAC_frame_type:string; 17 | MAC_ta:string; 18 | MAC_ra:string; 19 | manufacturer_ta:string; 20 | MAC_frame:string; 21 | CRC:string; 22 | start_of_packet:double=null; 23 | stop_of_packet:double=null; 24 | number_of_samples_in_packet:double=null; 25 | } 26 | 27 | table Descr { 28 | global:Global; 29 | annotation:Annotation; 30 | capture:Capture; 31 | } 32 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_antenna.fbs: -------------------------------------------------------------------------------- 1 | 2 | namespace sigmf.antenna; 3 | 4 | table Global { 5 | model:string; 6 | type:string; 7 | low_frequency:double=null; 8 | high_frequency:double=null; 9 | gain:double=null; 10 | horizontal_gain_pattern:[double]; 11 | vertical_gain_pattern:[double]; 12 | horizontal_beam_width:double=null; 13 | vertical_beam_width:double=null; 14 | cross_polar_discrimination:double=null; 15 | voltage_standing_wave_ratio:double=null; 16 | cable_loss:double=null; 17 | steerable:bool=null; 18 | mobile:bool=null; 19 | hagl:double=null; 20 | } 21 | 22 | table Capture { /*`antenna` does not extend `captures`*/ } 23 | 24 | table Annotation { 25 | azimuth_angle:double=null; 26 | elevation_angle:double=null; 27 | polarization:string; 28 | } 29 | 30 | table Descr { 31 | global:Global; 32 | annotation:Annotation; 33 | capture:Capture; 34 | } 35 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_capture_details.fbs: -------------------------------------------------------------------------------- 1 | 2 | namespace sigmf.capture_details; 3 | 4 | table Global { /*`capture_details` does not extend `global`*/ } 5 | 6 | table Capture { 7 | acq_scale_factor:double=null; 8 | attentuation:double=null; 9 | acquisition_bandwidth:double=null; 10 | start_capture:string; 11 | stop_capture:string; 12 | source_file:string; 13 | gain:double=null; 14 | } 15 | 16 | table Annotation { 17 | SNRdB:double=null; 18 | signal_reference_number:ulong=null; 19 | } 20 | 21 | table Descr { 22 | global:Global; 23 | annotation:Annotation; 24 | capture:Capture; 25 | } 26 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_capture_details_generated.h: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | 4 | #ifndef FLATBUFFERS_GENERATED_SIGMFCAPTUREDETAILS_SIGMF_CAPTURE_DETAILS_H_ 5 | #define FLATBUFFERS_GENERATED_SIGMFCAPTUREDETAILS_SIGMF_CAPTURE_DETAILS_H_ 6 | 7 | #include "flatbuffers/flatbuffers.h" 8 | 9 | namespace sigmf { 10 | namespace capture_details { 11 | 12 | struct Global; 13 | struct GlobalBuilder; 14 | struct GlobalT; 15 | 16 | struct Capture; 17 | struct CaptureBuilder; 18 | struct CaptureT; 19 | 20 | struct Annotation; 21 | struct AnnotationBuilder; 22 | struct AnnotationT; 23 | 24 | struct Descr; 25 | struct DescrBuilder; 26 | struct DescrT; 27 | 28 | inline const flatbuffers::TypeTable *GlobalTypeTable(); 29 | 30 | inline const flatbuffers::TypeTable *CaptureTypeTable(); 31 | 32 | inline const flatbuffers::TypeTable *AnnotationTypeTable(); 33 | 34 | inline const flatbuffers::TypeTable *DescrTypeTable(); 35 | 36 | struct GlobalT : public flatbuffers::NativeTable { 37 | typedef Global TableType; 38 | }; 39 | 40 | struct Global FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { 41 | typedef GlobalT NativeTableType; 42 | typedef GlobalBuilder Builder; 43 | static const flatbuffers::TypeTable *MiniReflectTypeTable() { 44 | return GlobalTypeTable(); 45 | } 46 | bool Verify(flatbuffers::Verifier &verifier) const { 47 | return VerifyTableStart(verifier) && 48 | verifier.EndTable(); 49 | } 50 | GlobalT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; 51 | void UnPackTo(GlobalT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; 52 | static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const GlobalT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 53 | }; 54 | 55 | struct GlobalBuilder { 56 | typedef Global Table; 57 | flatbuffers::FlatBufferBuilder &fbb_; 58 | flatbuffers::uoffset_t start_; 59 | explicit GlobalBuilder(flatbuffers::FlatBufferBuilder &_fbb) 60 | : fbb_(_fbb) { 61 | start_ = fbb_.StartTable(); 62 | } 63 | flatbuffers::Offset Finish() { 64 | const auto end = fbb_.EndTable(start_); 65 | auto o = flatbuffers::Offset(end); 66 | return o; 67 | } 68 | }; 69 | 70 | inline flatbuffers::Offset CreateGlobal( 71 | flatbuffers::FlatBufferBuilder &_fbb) { 72 | GlobalBuilder builder_(_fbb); 73 | return builder_.Finish(); 74 | } 75 | 76 | flatbuffers::Offset CreateGlobal(flatbuffers::FlatBufferBuilder &_fbb, const GlobalT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 77 | 78 | struct CaptureT : public flatbuffers::NativeTable { 79 | typedef Capture TableType; 80 | flatbuffers::Optional acq_scale_factor = flatbuffers::nullopt; 81 | flatbuffers::Optional attentuation = flatbuffers::nullopt; 82 | flatbuffers::Optional acquisition_bandwidth = flatbuffers::nullopt; 83 | std::string start_capture{}; 84 | std::string stop_capture{}; 85 | std::string source_file{}; 86 | flatbuffers::Optional gain = flatbuffers::nullopt; 87 | }; 88 | 89 | struct Capture FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { 90 | typedef CaptureT NativeTableType; 91 | typedef CaptureBuilder Builder; 92 | static const flatbuffers::TypeTable *MiniReflectTypeTable() { 93 | return CaptureTypeTable(); 94 | } 95 | enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { 96 | VT_ACQ_SCALE_FACTOR = 4, 97 | VT_ATTENTUATION = 6, 98 | VT_ACQUISITION_BANDWIDTH = 8, 99 | VT_START_CAPTURE = 10, 100 | VT_STOP_CAPTURE = 12, 101 | VT_SOURCE_FILE = 14, 102 | VT_GAIN = 16 103 | }; 104 | flatbuffers::Optional acq_scale_factor() const { 105 | return GetOptional(VT_ACQ_SCALE_FACTOR); 106 | } 107 | flatbuffers::Optional attentuation() const { 108 | return GetOptional(VT_ATTENTUATION); 109 | } 110 | flatbuffers::Optional acquisition_bandwidth() const { 111 | return GetOptional(VT_ACQUISITION_BANDWIDTH); 112 | } 113 | const flatbuffers::String *start_capture() const { 114 | return GetPointer(VT_START_CAPTURE); 115 | } 116 | const flatbuffers::String *stop_capture() const { 117 | return GetPointer(VT_STOP_CAPTURE); 118 | } 119 | const flatbuffers::String *source_file() const { 120 | return GetPointer(VT_SOURCE_FILE); 121 | } 122 | flatbuffers::Optional gain() const { 123 | return GetOptional(VT_GAIN); 124 | } 125 | bool Verify(flatbuffers::Verifier &verifier) const { 126 | return VerifyTableStart(verifier) && 127 | VerifyField(verifier, VT_ACQ_SCALE_FACTOR) && 128 | VerifyField(verifier, VT_ATTENTUATION) && 129 | VerifyField(verifier, VT_ACQUISITION_BANDWIDTH) && 130 | VerifyOffset(verifier, VT_START_CAPTURE) && 131 | verifier.VerifyString(start_capture()) && 132 | VerifyOffset(verifier, VT_STOP_CAPTURE) && 133 | verifier.VerifyString(stop_capture()) && 134 | VerifyOffset(verifier, VT_SOURCE_FILE) && 135 | verifier.VerifyString(source_file()) && 136 | VerifyField(verifier, VT_GAIN) && 137 | verifier.EndTable(); 138 | } 139 | CaptureT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; 140 | void UnPackTo(CaptureT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; 141 | static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const CaptureT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 142 | }; 143 | 144 | struct CaptureBuilder { 145 | typedef Capture Table; 146 | flatbuffers::FlatBufferBuilder &fbb_; 147 | flatbuffers::uoffset_t start_; 148 | void add_acq_scale_factor(double acq_scale_factor) { 149 | fbb_.AddElement(Capture::VT_ACQ_SCALE_FACTOR, acq_scale_factor); 150 | } 151 | void add_attentuation(double attentuation) { 152 | fbb_.AddElement(Capture::VT_ATTENTUATION, attentuation); 153 | } 154 | void add_acquisition_bandwidth(double acquisition_bandwidth) { 155 | fbb_.AddElement(Capture::VT_ACQUISITION_BANDWIDTH, acquisition_bandwidth); 156 | } 157 | void add_start_capture(flatbuffers::Offset start_capture) { 158 | fbb_.AddOffset(Capture::VT_START_CAPTURE, start_capture); 159 | } 160 | void add_stop_capture(flatbuffers::Offset stop_capture) { 161 | fbb_.AddOffset(Capture::VT_STOP_CAPTURE, stop_capture); 162 | } 163 | void add_source_file(flatbuffers::Offset source_file) { 164 | fbb_.AddOffset(Capture::VT_SOURCE_FILE, source_file); 165 | } 166 | void add_gain(double gain) { 167 | fbb_.AddElement(Capture::VT_GAIN, gain); 168 | } 169 | explicit CaptureBuilder(flatbuffers::FlatBufferBuilder &_fbb) 170 | : fbb_(_fbb) { 171 | start_ = fbb_.StartTable(); 172 | } 173 | flatbuffers::Offset Finish() { 174 | const auto end = fbb_.EndTable(start_); 175 | auto o = flatbuffers::Offset(end); 176 | return o; 177 | } 178 | }; 179 | 180 | inline flatbuffers::Offset CreateCapture( 181 | flatbuffers::FlatBufferBuilder &_fbb, 182 | flatbuffers::Optional acq_scale_factor = flatbuffers::nullopt, 183 | flatbuffers::Optional attentuation = flatbuffers::nullopt, 184 | flatbuffers::Optional acquisition_bandwidth = flatbuffers::nullopt, 185 | flatbuffers::Offset start_capture = 0, 186 | flatbuffers::Offset stop_capture = 0, 187 | flatbuffers::Offset source_file = 0, 188 | flatbuffers::Optional gain = flatbuffers::nullopt) { 189 | CaptureBuilder builder_(_fbb); 190 | if(gain) { builder_.add_gain(*gain); } 191 | if(acquisition_bandwidth) { builder_.add_acquisition_bandwidth(*acquisition_bandwidth); } 192 | if(attentuation) { builder_.add_attentuation(*attentuation); } 193 | if(acq_scale_factor) { builder_.add_acq_scale_factor(*acq_scale_factor); } 194 | builder_.add_source_file(source_file); 195 | builder_.add_stop_capture(stop_capture); 196 | builder_.add_start_capture(start_capture); 197 | return builder_.Finish(); 198 | } 199 | 200 | inline flatbuffers::Offset CreateCaptureDirect( 201 | flatbuffers::FlatBufferBuilder &_fbb, 202 | flatbuffers::Optional acq_scale_factor = flatbuffers::nullopt, 203 | flatbuffers::Optional attentuation = flatbuffers::nullopt, 204 | flatbuffers::Optional acquisition_bandwidth = flatbuffers::nullopt, 205 | const char *start_capture = nullptr, 206 | const char *stop_capture = nullptr, 207 | const char *source_file = nullptr, 208 | flatbuffers::Optional gain = flatbuffers::nullopt) { 209 | auto start_capture__ = start_capture ? _fbb.CreateString(start_capture) : 0; 210 | auto stop_capture__ = stop_capture ? _fbb.CreateString(stop_capture) : 0; 211 | auto source_file__ = source_file ? _fbb.CreateString(source_file) : 0; 212 | return sigmf::capture_details::CreateCapture( 213 | _fbb, 214 | acq_scale_factor, 215 | attentuation, 216 | acquisition_bandwidth, 217 | start_capture__, 218 | stop_capture__, 219 | source_file__, 220 | gain); 221 | } 222 | 223 | flatbuffers::Offset CreateCapture(flatbuffers::FlatBufferBuilder &_fbb, const CaptureT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 224 | 225 | struct AnnotationT : public flatbuffers::NativeTable { 226 | typedef Annotation TableType; 227 | flatbuffers::Optional SNRdB = flatbuffers::nullopt; 228 | flatbuffers::Optional signal_reference_number = flatbuffers::nullopt; 229 | }; 230 | 231 | struct Annotation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { 232 | typedef AnnotationT NativeTableType; 233 | typedef AnnotationBuilder Builder; 234 | static const flatbuffers::TypeTable *MiniReflectTypeTable() { 235 | return AnnotationTypeTable(); 236 | } 237 | enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { 238 | VT_SNRDB = 4, 239 | VT_SIGNAL_REFERENCE_NUMBER = 6 240 | }; 241 | flatbuffers::Optional SNRdB() const { 242 | return GetOptional(VT_SNRDB); 243 | } 244 | flatbuffers::Optional signal_reference_number() const { 245 | return GetOptional(VT_SIGNAL_REFERENCE_NUMBER); 246 | } 247 | bool Verify(flatbuffers::Verifier &verifier) const { 248 | return VerifyTableStart(verifier) && 249 | VerifyField(verifier, VT_SNRDB) && 250 | VerifyField(verifier, VT_SIGNAL_REFERENCE_NUMBER) && 251 | verifier.EndTable(); 252 | } 253 | AnnotationT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; 254 | void UnPackTo(AnnotationT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; 255 | static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const AnnotationT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 256 | }; 257 | 258 | struct AnnotationBuilder { 259 | typedef Annotation Table; 260 | flatbuffers::FlatBufferBuilder &fbb_; 261 | flatbuffers::uoffset_t start_; 262 | void add_SNRdB(double SNRdB) { 263 | fbb_.AddElement(Annotation::VT_SNRDB, SNRdB); 264 | } 265 | void add_signal_reference_number(uint64_t signal_reference_number) { 266 | fbb_.AddElement(Annotation::VT_SIGNAL_REFERENCE_NUMBER, signal_reference_number); 267 | } 268 | explicit AnnotationBuilder(flatbuffers::FlatBufferBuilder &_fbb) 269 | : fbb_(_fbb) { 270 | start_ = fbb_.StartTable(); 271 | } 272 | flatbuffers::Offset Finish() { 273 | const auto end = fbb_.EndTable(start_); 274 | auto o = flatbuffers::Offset(end); 275 | return o; 276 | } 277 | }; 278 | 279 | inline flatbuffers::Offset CreateAnnotation( 280 | flatbuffers::FlatBufferBuilder &_fbb, 281 | flatbuffers::Optional SNRdB = flatbuffers::nullopt, 282 | flatbuffers::Optional signal_reference_number = flatbuffers::nullopt) { 283 | AnnotationBuilder builder_(_fbb); 284 | if(signal_reference_number) { builder_.add_signal_reference_number(*signal_reference_number); } 285 | if(SNRdB) { builder_.add_SNRdB(*SNRdB); } 286 | return builder_.Finish(); 287 | } 288 | 289 | flatbuffers::Offset CreateAnnotation(flatbuffers::FlatBufferBuilder &_fbb, const AnnotationT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 290 | 291 | struct DescrT : public flatbuffers::NativeTable { 292 | typedef Descr TableType; 293 | std::shared_ptr global{}; 294 | std::shared_ptr annotation{}; 295 | std::shared_ptr capture{}; 296 | }; 297 | 298 | struct Descr FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { 299 | typedef DescrT NativeTableType; 300 | typedef DescrBuilder Builder; 301 | static const flatbuffers::TypeTable *MiniReflectTypeTable() { 302 | return DescrTypeTable(); 303 | } 304 | enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { 305 | VT_GLOBAL = 4, 306 | VT_ANNOTATION = 6, 307 | VT_CAPTURE = 8 308 | }; 309 | const sigmf::capture_details::Global *global() const { 310 | return GetPointer(VT_GLOBAL); 311 | } 312 | const sigmf::capture_details::Annotation *annotation() const { 313 | return GetPointer(VT_ANNOTATION); 314 | } 315 | const sigmf::capture_details::Capture *capture() const { 316 | return GetPointer(VT_CAPTURE); 317 | } 318 | bool Verify(flatbuffers::Verifier &verifier) const { 319 | return VerifyTableStart(verifier) && 320 | VerifyOffset(verifier, VT_GLOBAL) && 321 | verifier.VerifyTable(global()) && 322 | VerifyOffset(verifier, VT_ANNOTATION) && 323 | verifier.VerifyTable(annotation()) && 324 | VerifyOffset(verifier, VT_CAPTURE) && 325 | verifier.VerifyTable(capture()) && 326 | verifier.EndTable(); 327 | } 328 | DescrT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; 329 | void UnPackTo(DescrT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; 330 | static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const DescrT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 331 | }; 332 | 333 | struct DescrBuilder { 334 | typedef Descr Table; 335 | flatbuffers::FlatBufferBuilder &fbb_; 336 | flatbuffers::uoffset_t start_; 337 | void add_global(flatbuffers::Offset global) { 338 | fbb_.AddOffset(Descr::VT_GLOBAL, global); 339 | } 340 | void add_annotation(flatbuffers::Offset annotation) { 341 | fbb_.AddOffset(Descr::VT_ANNOTATION, annotation); 342 | } 343 | void add_capture(flatbuffers::Offset capture) { 344 | fbb_.AddOffset(Descr::VT_CAPTURE, capture); 345 | } 346 | explicit DescrBuilder(flatbuffers::FlatBufferBuilder &_fbb) 347 | : fbb_(_fbb) { 348 | start_ = fbb_.StartTable(); 349 | } 350 | flatbuffers::Offset Finish() { 351 | const auto end = fbb_.EndTable(start_); 352 | auto o = flatbuffers::Offset(end); 353 | return o; 354 | } 355 | }; 356 | 357 | inline flatbuffers::Offset CreateDescr( 358 | flatbuffers::FlatBufferBuilder &_fbb, 359 | flatbuffers::Offset global = 0, 360 | flatbuffers::Offset annotation = 0, 361 | flatbuffers::Offset capture = 0) { 362 | DescrBuilder builder_(_fbb); 363 | builder_.add_capture(capture); 364 | builder_.add_annotation(annotation); 365 | builder_.add_global(global); 366 | return builder_.Finish(); 367 | } 368 | 369 | flatbuffers::Offset CreateDescr(flatbuffers::FlatBufferBuilder &_fbb, const DescrT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 370 | 371 | inline GlobalT *Global::UnPack(const flatbuffers::resolver_function_t *_resolver) const { 372 | auto _o = std::unique_ptr(new GlobalT()); 373 | UnPackTo(_o.get(), _resolver); 374 | return _o.release(); 375 | } 376 | 377 | inline void Global::UnPackTo(GlobalT *_o, const flatbuffers::resolver_function_t *_resolver) const { 378 | (void)_o; 379 | (void)_resolver; 380 | } 381 | 382 | inline flatbuffers::Offset Global::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GlobalT* _o, const flatbuffers::rehasher_function_t *_rehasher) { 383 | return CreateGlobal(_fbb, _o, _rehasher); 384 | } 385 | 386 | inline flatbuffers::Offset CreateGlobal(flatbuffers::FlatBufferBuilder &_fbb, const GlobalT *_o, const flatbuffers::rehasher_function_t *_rehasher) { 387 | (void)_rehasher; 388 | (void)_o; 389 | struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GlobalT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; 390 | return sigmf::capture_details::CreateGlobal( 391 | _fbb); 392 | } 393 | 394 | inline CaptureT *Capture::UnPack(const flatbuffers::resolver_function_t *_resolver) const { 395 | auto _o = std::unique_ptr(new CaptureT()); 396 | UnPackTo(_o.get(), _resolver); 397 | return _o.release(); 398 | } 399 | 400 | inline void Capture::UnPackTo(CaptureT *_o, const flatbuffers::resolver_function_t *_resolver) const { 401 | (void)_o; 402 | (void)_resolver; 403 | { auto _e = acq_scale_factor(); _o->acq_scale_factor = _e; } 404 | { auto _e = attentuation(); _o->attentuation = _e; } 405 | { auto _e = acquisition_bandwidth(); _o->acquisition_bandwidth = _e; } 406 | { auto _e = start_capture(); if (_e) _o->start_capture = _e->str(); } 407 | { auto _e = stop_capture(); if (_e) _o->stop_capture = _e->str(); } 408 | { auto _e = source_file(); if (_e) _o->source_file = _e->str(); } 409 | { auto _e = gain(); _o->gain = _e; } 410 | } 411 | 412 | inline flatbuffers::Offset Capture::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CaptureT* _o, const flatbuffers::rehasher_function_t *_rehasher) { 413 | return CreateCapture(_fbb, _o, _rehasher); 414 | } 415 | 416 | inline flatbuffers::Offset CreateCapture(flatbuffers::FlatBufferBuilder &_fbb, const CaptureT *_o, const flatbuffers::rehasher_function_t *_rehasher) { 417 | (void)_rehasher; 418 | (void)_o; 419 | struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CaptureT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; 420 | auto _acq_scale_factor = _o->acq_scale_factor; 421 | auto _attentuation = _o->attentuation; 422 | auto _acquisition_bandwidth = _o->acquisition_bandwidth; 423 | auto _start_capture = _o->start_capture.empty() ? 0 : _fbb.CreateString(_o->start_capture); 424 | auto _stop_capture = _o->stop_capture.empty() ? 0 : _fbb.CreateString(_o->stop_capture); 425 | auto _source_file = _o->source_file.empty() ? 0 : _fbb.CreateString(_o->source_file); 426 | auto _gain = _o->gain; 427 | return sigmf::capture_details::CreateCapture( 428 | _fbb, 429 | _acq_scale_factor, 430 | _attentuation, 431 | _acquisition_bandwidth, 432 | _start_capture, 433 | _stop_capture, 434 | _source_file, 435 | _gain); 436 | } 437 | 438 | inline AnnotationT *Annotation::UnPack(const flatbuffers::resolver_function_t *_resolver) const { 439 | auto _o = std::unique_ptr(new AnnotationT()); 440 | UnPackTo(_o.get(), _resolver); 441 | return _o.release(); 442 | } 443 | 444 | inline void Annotation::UnPackTo(AnnotationT *_o, const flatbuffers::resolver_function_t *_resolver) const { 445 | (void)_o; 446 | (void)_resolver; 447 | { auto _e = SNRdB(); _o->SNRdB = _e; } 448 | { auto _e = signal_reference_number(); _o->signal_reference_number = _e; } 449 | } 450 | 451 | inline flatbuffers::Offset Annotation::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AnnotationT* _o, const flatbuffers::rehasher_function_t *_rehasher) { 452 | return CreateAnnotation(_fbb, _o, _rehasher); 453 | } 454 | 455 | inline flatbuffers::Offset CreateAnnotation(flatbuffers::FlatBufferBuilder &_fbb, const AnnotationT *_o, const flatbuffers::rehasher_function_t *_rehasher) { 456 | (void)_rehasher; 457 | (void)_o; 458 | struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AnnotationT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; 459 | auto _SNRdB = _o->SNRdB; 460 | auto _signal_reference_number = _o->signal_reference_number; 461 | return sigmf::capture_details::CreateAnnotation( 462 | _fbb, 463 | _SNRdB, 464 | _signal_reference_number); 465 | } 466 | 467 | inline DescrT *Descr::UnPack(const flatbuffers::resolver_function_t *_resolver) const { 468 | auto _o = std::unique_ptr(new DescrT()); 469 | UnPackTo(_o.get(), _resolver); 470 | return _o.release(); 471 | } 472 | 473 | inline void Descr::UnPackTo(DescrT *_o, const flatbuffers::resolver_function_t *_resolver) const { 474 | (void)_o; 475 | (void)_resolver; 476 | { auto _e = global(); if (_e) _o->global = std::shared_ptr(_e->UnPack(_resolver)); } 477 | { auto _e = annotation(); if (_e) _o->annotation = std::shared_ptr(_e->UnPack(_resolver)); } 478 | { auto _e = capture(); if (_e) _o->capture = std::shared_ptr(_e->UnPack(_resolver)); } 479 | } 480 | 481 | inline flatbuffers::Offset Descr::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DescrT* _o, const flatbuffers::rehasher_function_t *_rehasher) { 482 | return CreateDescr(_fbb, _o, _rehasher); 483 | } 484 | 485 | inline flatbuffers::Offset CreateDescr(flatbuffers::FlatBufferBuilder &_fbb, const DescrT *_o, const flatbuffers::rehasher_function_t *_rehasher) { 486 | (void)_rehasher; 487 | (void)_o; 488 | struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DescrT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; 489 | auto _global = _o->global ? CreateGlobal(_fbb, _o->global.get(), _rehasher) : 0; 490 | auto _annotation = _o->annotation ? CreateAnnotation(_fbb, _o->annotation.get(), _rehasher) : 0; 491 | auto _capture = _o->capture ? CreateCapture(_fbb, _o->capture.get(), _rehasher) : 0; 492 | return sigmf::capture_details::CreateDescr( 493 | _fbb, 494 | _global, 495 | _annotation, 496 | _capture); 497 | } 498 | 499 | inline const flatbuffers::TypeTable *GlobalTypeTable() { 500 | static const flatbuffers::TypeTable tt = { 501 | flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr, nullptr 502 | }; 503 | return &tt; 504 | } 505 | 506 | inline const flatbuffers::TypeTable *CaptureTypeTable() { 507 | static const flatbuffers::TypeCode type_codes[] = { 508 | { flatbuffers::ET_DOUBLE, 0, -1 }, 509 | { flatbuffers::ET_DOUBLE, 0, -1 }, 510 | { flatbuffers::ET_DOUBLE, 0, -1 }, 511 | { flatbuffers::ET_STRING, 0, -1 }, 512 | { flatbuffers::ET_STRING, 0, -1 }, 513 | { flatbuffers::ET_STRING, 0, -1 }, 514 | { flatbuffers::ET_DOUBLE, 0, -1 } 515 | }; 516 | static const char * const names[] = { 517 | "acq_scale_factor", 518 | "attentuation", 519 | "acquisition_bandwidth", 520 | "start_capture", 521 | "stop_capture", 522 | "source_file", 523 | "gain" 524 | }; 525 | static const flatbuffers::TypeTable tt = { 526 | flatbuffers::ST_TABLE, 7, type_codes, nullptr, nullptr, nullptr, names 527 | }; 528 | return &tt; 529 | } 530 | 531 | inline const flatbuffers::TypeTable *AnnotationTypeTable() { 532 | static const flatbuffers::TypeCode type_codes[] = { 533 | { flatbuffers::ET_DOUBLE, 0, -1 }, 534 | { flatbuffers::ET_ULONG, 0, -1 } 535 | }; 536 | static const char * const names[] = { 537 | "SNRdB", 538 | "signal_reference_number" 539 | }; 540 | static const flatbuffers::TypeTable tt = { 541 | flatbuffers::ST_TABLE, 2, type_codes, nullptr, nullptr, nullptr, names 542 | }; 543 | return &tt; 544 | } 545 | 546 | inline const flatbuffers::TypeTable *DescrTypeTable() { 547 | static const flatbuffers::TypeCode type_codes[] = { 548 | { flatbuffers::ET_SEQUENCE, 0, 0 }, 549 | { flatbuffers::ET_SEQUENCE, 0, 1 }, 550 | { flatbuffers::ET_SEQUENCE, 0, 2 } 551 | }; 552 | static const flatbuffers::TypeFunction type_refs[] = { 553 | sigmf::capture_details::GlobalTypeTable, 554 | sigmf::capture_details::AnnotationTypeTable, 555 | sigmf::capture_details::CaptureTypeTable 556 | }; 557 | static const char * const names[] = { 558 | "global", 559 | "annotation", 560 | "capture" 561 | }; 562 | static const flatbuffers::TypeTable tt = { 563 | flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, nullptr, names 564 | }; 565 | return &tt; 566 | } 567 | 568 | } // namespace capture_details 569 | } // namespace sigmf 570 | 571 | #endif // FLATBUFFERS_GENERATED_SIGMFCAPTUREDETAILS_SIGMF_CAPTURE_DETAILS_H_ 572 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_core.fbs: -------------------------------------------------------------------------------- 1 | 2 | namespace sigmf.core; 3 | 4 | table sigmf_extension { 5 | name:string; 6 | version:string; 7 | optional:bool=null; 8 | } 9 | 10 | table sigmf_stream { 11 | name:string; 12 | hash:string; 13 | } 14 | 15 | table geojson_point { 16 | type:string; 17 | coordinates:[double]; 18 | } 19 | 20 | table Global { 21 | datatype:string; 22 | sample_rate:double=null; 23 | version:string; 24 | num_channels:ulong=null; 25 | sha512:string; 26 | offset:ulong=null; 27 | description:string; 28 | author:string; 29 | meta_doi:string; 30 | data_doi:string; 31 | recorder:string; 32 | license:string; 33 | hw:string; 34 | dataset:string; 35 | trailing_bytes:ulong=null; 36 | metadata_only:bool=null; 37 | geolocation:geojson_point; 38 | extensions:[sigmf_extension]; 39 | collection:string; 40 | } 41 | 42 | table Capture { 43 | sample_start:ulong=null; 44 | global_index:ulong=null; 45 | header_bytes:ulong=null; 46 | frequency:double=null; 47 | datetime:string; 48 | } 49 | 50 | table Annotation { 51 | sample_start:ulong=null; 52 | sample_count:ulong=null; 53 | generator:string; 54 | description:string; // not defined by SigMF; included for compatibility - use `label` 55 | label:string; 56 | comment:string; 57 | freq_lower_edge:double=null; 58 | freq_upper_edge:double=null; 59 | latitude:double=null; // deprecated, use the `global` `geolocation` field 60 | longitude:double=null; // deprecated, use the `global` `geolocation` field 61 | } 62 | 63 | table Collection { 64 | version:string; 65 | description:string; 66 | author:string; 67 | collection_doi:string; 68 | license:string; 69 | extensions:[sigmf_extension]; 70 | streams:[sigmf_stream]; 71 | } 72 | 73 | table Descr { 74 | global:Global; 75 | annotation:Annotation; 76 | capture:Capture; 77 | collection:Collection; 78 | } 79 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_signal.fbs: -------------------------------------------------------------------------------- 1 | 2 | include "sigmf_core.fbs"; 3 | 4 | namespace sigmf.signal; 5 | 6 | table Global { /*`signal` does not extend `global`*/ } 7 | 8 | table Capture { /*`signal` does not extend `captures`*/ } 9 | 10 | table signal_detail { // permitted string values: 11 | type:string; // analog, digital 12 | mod_class:string; // am, fm, pm, ssb, dsb, vsb, ask, fsk, psk, qam, ook, cpm, msk 13 | standard:string; 14 | carrier_variant:string; // with_carrier, suppressed_carrier, reduced_carrier, single_carrier, multi_carrier 15 | symbol_variant:string; // differential, offset 16 | order:ulong=null; 17 | duplexing:string; // tdd, fdd 18 | multiplexing:string; // tdm, fdm, cdm, ofdm, sdm, pdm 19 | multiple_access:string; // fdma, ofdma, tdma, cdma, sdma, pdma 20 | spreading:string; // fhss, thss, dsss, css 21 | channel_bw:double=null; 22 | channel:ulong=null; 23 | class_variant:string; 24 | } 25 | 26 | table signal_emitter { 27 | seid:ulong=null; 28 | manufacturer:string; 29 | power_tx:double=null; 30 | power_eirp:double=null; 31 | geolocation:core.geojson_point; 32 | } 33 | 34 | table Annotation { 35 | detail:signal_detail; 36 | emitter:signal_emitter; 37 | } 38 | 39 | table Descr { 40 | global:Global; 41 | annotation:Annotation; 42 | capture:Capture; 43 | } 44 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_spatial.fbs: -------------------------------------------------------------------------------- 1 | 2 | namespace sigmf.spatial; 3 | 4 | table sigmf_bearing { 5 | azimuth:double=null; 6 | elevation:double=null; 7 | range:double=null; 8 | az_error:double=null; 9 | el_error:double=null; 10 | range_error:double=null; 11 | } 12 | 13 | table cartesian_point { 14 | point:[double]; 15 | unknown:bool=null; 16 | } 17 | 18 | table sigmf_calibration { 19 | caltype:string; // "tone", "xcorr", "ref", "other" 20 | bearing:sigmf_bearing; 21 | cal_geometry:cartesian_point; 22 | } 23 | 24 | table Global { 25 | num_elements:uint64=null; 26 | channel_index:uint64=null; 27 | } 28 | 29 | table Capture { 30 | aperture_azimuth:double=null; 31 | aperture_bearing:sigmf_bearing; 32 | emitter_bearing:sigmf_bearing; 33 | element_geometry:[cartesian_point]; 34 | phase_offset:double=null; 35 | calibration:sigmf_calibration; 36 | } 37 | 38 | table Annotation { 39 | signal_azimuth:double=null; 40 | signal_bearing:sigmf_bearing; 41 | } 42 | 43 | table Collection { 44 | element_geometry:[cartesian_point]; 45 | } 46 | 47 | table Descr { 48 | global:Global; 49 | annotation:Annotation; 50 | capture:Capture; 51 | collection:Collection; 52 | } 53 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_wifi.fbs: -------------------------------------------------------------------------------- 1 | 2 | namespace sigmf.wifi; 3 | 4 | table Global { /*`wifi` does not extend `global`*/ } 5 | 6 | table Capture { /*`wifi` does not extend `captures`*/ } 7 | 8 | table Annotation { 9 | downlink_format:long=null; 10 | message_type:long=null; 11 | ICA_address:double=null; 12 | binary:string; 13 | } 14 | 15 | table Descr { 16 | global:Global; 17 | annotation:Annotation; 18 | capture:Capture; 19 | } 20 | -------------------------------------------------------------------------------- /sigmf_protocols/sigmf_wifi_generated.h: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | 4 | #ifndef FLATBUFFERS_GENERATED_SIGMFWIFI_SIGMF_WIFI_H_ 5 | #define FLATBUFFERS_GENERATED_SIGMFWIFI_SIGMF_WIFI_H_ 6 | 7 | #include "flatbuffers/flatbuffers.h" 8 | 9 | namespace sigmf { 10 | namespace wifi { 11 | 12 | struct Global; 13 | struct GlobalBuilder; 14 | struct GlobalT; 15 | 16 | struct Capture; 17 | struct CaptureBuilder; 18 | struct CaptureT; 19 | 20 | struct Annotation; 21 | struct AnnotationBuilder; 22 | struct AnnotationT; 23 | 24 | struct Descr; 25 | struct DescrBuilder; 26 | struct DescrT; 27 | 28 | inline const flatbuffers::TypeTable *GlobalTypeTable(); 29 | 30 | inline const flatbuffers::TypeTable *CaptureTypeTable(); 31 | 32 | inline const flatbuffers::TypeTable *AnnotationTypeTable(); 33 | 34 | inline const flatbuffers::TypeTable *DescrTypeTable(); 35 | 36 | struct GlobalT : public flatbuffers::NativeTable { 37 | typedef Global TableType; 38 | }; 39 | 40 | struct Global FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { 41 | typedef GlobalT NativeTableType; 42 | typedef GlobalBuilder Builder; 43 | static const flatbuffers::TypeTable *MiniReflectTypeTable() { 44 | return GlobalTypeTable(); 45 | } 46 | bool Verify(flatbuffers::Verifier &verifier) const { 47 | return VerifyTableStart(verifier) && 48 | verifier.EndTable(); 49 | } 50 | GlobalT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; 51 | void UnPackTo(GlobalT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; 52 | static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const GlobalT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 53 | }; 54 | 55 | struct GlobalBuilder { 56 | typedef Global Table; 57 | flatbuffers::FlatBufferBuilder &fbb_; 58 | flatbuffers::uoffset_t start_; 59 | explicit GlobalBuilder(flatbuffers::FlatBufferBuilder &_fbb) 60 | : fbb_(_fbb) { 61 | start_ = fbb_.StartTable(); 62 | } 63 | flatbuffers::Offset Finish() { 64 | const auto end = fbb_.EndTable(start_); 65 | auto o = flatbuffers::Offset(end); 66 | return o; 67 | } 68 | }; 69 | 70 | inline flatbuffers::Offset CreateGlobal( 71 | flatbuffers::FlatBufferBuilder &_fbb) { 72 | GlobalBuilder builder_(_fbb); 73 | return builder_.Finish(); 74 | } 75 | 76 | flatbuffers::Offset CreateGlobal(flatbuffers::FlatBufferBuilder &_fbb, const GlobalT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 77 | 78 | struct CaptureT : public flatbuffers::NativeTable { 79 | typedef Capture TableType; 80 | }; 81 | 82 | struct Capture FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { 83 | typedef CaptureT NativeTableType; 84 | typedef CaptureBuilder Builder; 85 | static const flatbuffers::TypeTable *MiniReflectTypeTable() { 86 | return CaptureTypeTable(); 87 | } 88 | bool Verify(flatbuffers::Verifier &verifier) const { 89 | return VerifyTableStart(verifier) && 90 | verifier.EndTable(); 91 | } 92 | CaptureT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; 93 | void UnPackTo(CaptureT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; 94 | static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const CaptureT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 95 | }; 96 | 97 | struct CaptureBuilder { 98 | typedef Capture Table; 99 | flatbuffers::FlatBufferBuilder &fbb_; 100 | flatbuffers::uoffset_t start_; 101 | explicit CaptureBuilder(flatbuffers::FlatBufferBuilder &_fbb) 102 | : fbb_(_fbb) { 103 | start_ = fbb_.StartTable(); 104 | } 105 | flatbuffers::Offset Finish() { 106 | const auto end = fbb_.EndTable(start_); 107 | auto o = flatbuffers::Offset(end); 108 | return o; 109 | } 110 | }; 111 | 112 | inline flatbuffers::Offset CreateCapture( 113 | flatbuffers::FlatBufferBuilder &_fbb) { 114 | CaptureBuilder builder_(_fbb); 115 | return builder_.Finish(); 116 | } 117 | 118 | flatbuffers::Offset CreateCapture(flatbuffers::FlatBufferBuilder &_fbb, const CaptureT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 119 | 120 | struct AnnotationT : public flatbuffers::NativeTable { 121 | typedef Annotation TableType; 122 | flatbuffers::Optional downlink_format = flatbuffers::nullopt; 123 | flatbuffers::Optional message_type = flatbuffers::nullopt; 124 | flatbuffers::Optional ICA_address = flatbuffers::nullopt; 125 | std::string binary{}; 126 | }; 127 | 128 | struct Annotation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { 129 | typedef AnnotationT NativeTableType; 130 | typedef AnnotationBuilder Builder; 131 | static const flatbuffers::TypeTable *MiniReflectTypeTable() { 132 | return AnnotationTypeTable(); 133 | } 134 | enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { 135 | VT_DOWNLINK_FORMAT = 4, 136 | VT_MESSAGE_TYPE = 6, 137 | VT_ICA_ADDRESS = 8, 138 | VT_BINARY = 10 139 | }; 140 | flatbuffers::Optional downlink_format() const { 141 | return GetOptional(VT_DOWNLINK_FORMAT); 142 | } 143 | flatbuffers::Optional message_type() const { 144 | return GetOptional(VT_MESSAGE_TYPE); 145 | } 146 | flatbuffers::Optional ICA_address() const { 147 | return GetOptional(VT_ICA_ADDRESS); 148 | } 149 | const flatbuffers::String *binary() const { 150 | return GetPointer(VT_BINARY); 151 | } 152 | bool Verify(flatbuffers::Verifier &verifier) const { 153 | return VerifyTableStart(verifier) && 154 | VerifyField(verifier, VT_DOWNLINK_FORMAT) && 155 | VerifyField(verifier, VT_MESSAGE_TYPE) && 156 | VerifyField(verifier, VT_ICA_ADDRESS) && 157 | VerifyOffset(verifier, VT_BINARY) && 158 | verifier.VerifyString(binary()) && 159 | verifier.EndTable(); 160 | } 161 | AnnotationT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; 162 | void UnPackTo(AnnotationT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; 163 | static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const AnnotationT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 164 | }; 165 | 166 | struct AnnotationBuilder { 167 | typedef Annotation Table; 168 | flatbuffers::FlatBufferBuilder &fbb_; 169 | flatbuffers::uoffset_t start_; 170 | void add_downlink_format(int64_t downlink_format) { 171 | fbb_.AddElement(Annotation::VT_DOWNLINK_FORMAT, downlink_format); 172 | } 173 | void add_message_type(int64_t message_type) { 174 | fbb_.AddElement(Annotation::VT_MESSAGE_TYPE, message_type); 175 | } 176 | void add_ICA_address(double ICA_address) { 177 | fbb_.AddElement(Annotation::VT_ICA_ADDRESS, ICA_address); 178 | } 179 | void add_binary(flatbuffers::Offset binary) { 180 | fbb_.AddOffset(Annotation::VT_BINARY, binary); 181 | } 182 | explicit AnnotationBuilder(flatbuffers::FlatBufferBuilder &_fbb) 183 | : fbb_(_fbb) { 184 | start_ = fbb_.StartTable(); 185 | } 186 | flatbuffers::Offset Finish() { 187 | const auto end = fbb_.EndTable(start_); 188 | auto o = flatbuffers::Offset(end); 189 | return o; 190 | } 191 | }; 192 | 193 | inline flatbuffers::Offset CreateAnnotation( 194 | flatbuffers::FlatBufferBuilder &_fbb, 195 | flatbuffers::Optional downlink_format = flatbuffers::nullopt, 196 | flatbuffers::Optional message_type = flatbuffers::nullopt, 197 | flatbuffers::Optional ICA_address = flatbuffers::nullopt, 198 | flatbuffers::Offset binary = 0) { 199 | AnnotationBuilder builder_(_fbb); 200 | if(ICA_address) { builder_.add_ICA_address(*ICA_address); } 201 | if(message_type) { builder_.add_message_type(*message_type); } 202 | if(downlink_format) { builder_.add_downlink_format(*downlink_format); } 203 | builder_.add_binary(binary); 204 | return builder_.Finish(); 205 | } 206 | 207 | inline flatbuffers::Offset CreateAnnotationDirect( 208 | flatbuffers::FlatBufferBuilder &_fbb, 209 | flatbuffers::Optional downlink_format = flatbuffers::nullopt, 210 | flatbuffers::Optional message_type = flatbuffers::nullopt, 211 | flatbuffers::Optional ICA_address = flatbuffers::nullopt, 212 | const char *binary = nullptr) { 213 | auto binary__ = binary ? _fbb.CreateString(binary) : 0; 214 | return sigmf::wifi::CreateAnnotation( 215 | _fbb, 216 | downlink_format, 217 | message_type, 218 | ICA_address, 219 | binary__); 220 | } 221 | 222 | flatbuffers::Offset CreateAnnotation(flatbuffers::FlatBufferBuilder &_fbb, const AnnotationT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 223 | 224 | struct DescrT : public flatbuffers::NativeTable { 225 | typedef Descr TableType; 226 | std::shared_ptr global{}; 227 | std::shared_ptr annotation{}; 228 | std::shared_ptr capture{}; 229 | }; 230 | 231 | struct Descr FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { 232 | typedef DescrT NativeTableType; 233 | typedef DescrBuilder Builder; 234 | static const flatbuffers::TypeTable *MiniReflectTypeTable() { 235 | return DescrTypeTable(); 236 | } 237 | enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { 238 | VT_GLOBAL = 4, 239 | VT_ANNOTATION = 6, 240 | VT_CAPTURE = 8 241 | }; 242 | const sigmf::wifi::Global *global() const { 243 | return GetPointer(VT_GLOBAL); 244 | } 245 | const sigmf::wifi::Annotation *annotation() const { 246 | return GetPointer(VT_ANNOTATION); 247 | } 248 | const sigmf::wifi::Capture *capture() const { 249 | return GetPointer(VT_CAPTURE); 250 | } 251 | bool Verify(flatbuffers::Verifier &verifier) const { 252 | return VerifyTableStart(verifier) && 253 | VerifyOffset(verifier, VT_GLOBAL) && 254 | verifier.VerifyTable(global()) && 255 | VerifyOffset(verifier, VT_ANNOTATION) && 256 | verifier.VerifyTable(annotation()) && 257 | VerifyOffset(verifier, VT_CAPTURE) && 258 | verifier.VerifyTable(capture()) && 259 | verifier.EndTable(); 260 | } 261 | DescrT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; 262 | void UnPackTo(DescrT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; 263 | static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const DescrT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 264 | }; 265 | 266 | struct DescrBuilder { 267 | typedef Descr Table; 268 | flatbuffers::FlatBufferBuilder &fbb_; 269 | flatbuffers::uoffset_t start_; 270 | void add_global(flatbuffers::Offset global) { 271 | fbb_.AddOffset(Descr::VT_GLOBAL, global); 272 | } 273 | void add_annotation(flatbuffers::Offset annotation) { 274 | fbb_.AddOffset(Descr::VT_ANNOTATION, annotation); 275 | } 276 | void add_capture(flatbuffers::Offset capture) { 277 | fbb_.AddOffset(Descr::VT_CAPTURE, capture); 278 | } 279 | explicit DescrBuilder(flatbuffers::FlatBufferBuilder &_fbb) 280 | : fbb_(_fbb) { 281 | start_ = fbb_.StartTable(); 282 | } 283 | flatbuffers::Offset Finish() { 284 | const auto end = fbb_.EndTable(start_); 285 | auto o = flatbuffers::Offset(end); 286 | return o; 287 | } 288 | }; 289 | 290 | inline flatbuffers::Offset CreateDescr( 291 | flatbuffers::FlatBufferBuilder &_fbb, 292 | flatbuffers::Offset global = 0, 293 | flatbuffers::Offset annotation = 0, 294 | flatbuffers::Offset capture = 0) { 295 | DescrBuilder builder_(_fbb); 296 | builder_.add_capture(capture); 297 | builder_.add_annotation(annotation); 298 | builder_.add_global(global); 299 | return builder_.Finish(); 300 | } 301 | 302 | flatbuffers::Offset CreateDescr(flatbuffers::FlatBufferBuilder &_fbb, const DescrT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); 303 | 304 | inline GlobalT *Global::UnPack(const flatbuffers::resolver_function_t *_resolver) const { 305 | auto _o = std::unique_ptr(new GlobalT()); 306 | UnPackTo(_o.get(), _resolver); 307 | return _o.release(); 308 | } 309 | 310 | inline void Global::UnPackTo(GlobalT *_o, const flatbuffers::resolver_function_t *_resolver) const { 311 | (void)_o; 312 | (void)_resolver; 313 | } 314 | 315 | inline flatbuffers::Offset Global::Pack(flatbuffers::FlatBufferBuilder &_fbb, const GlobalT* _o, const flatbuffers::rehasher_function_t *_rehasher) { 316 | return CreateGlobal(_fbb, _o, _rehasher); 317 | } 318 | 319 | inline flatbuffers::Offset CreateGlobal(flatbuffers::FlatBufferBuilder &_fbb, const GlobalT *_o, const flatbuffers::rehasher_function_t *_rehasher) { 320 | (void)_rehasher; 321 | (void)_o; 322 | struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const GlobalT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; 323 | return sigmf::wifi::CreateGlobal( 324 | _fbb); 325 | } 326 | 327 | inline CaptureT *Capture::UnPack(const flatbuffers::resolver_function_t *_resolver) const { 328 | auto _o = std::unique_ptr(new CaptureT()); 329 | UnPackTo(_o.get(), _resolver); 330 | return _o.release(); 331 | } 332 | 333 | inline void Capture::UnPackTo(CaptureT *_o, const flatbuffers::resolver_function_t *_resolver) const { 334 | (void)_o; 335 | (void)_resolver; 336 | } 337 | 338 | inline flatbuffers::Offset Capture::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CaptureT* _o, const flatbuffers::rehasher_function_t *_rehasher) { 339 | return CreateCapture(_fbb, _o, _rehasher); 340 | } 341 | 342 | inline flatbuffers::Offset CreateCapture(flatbuffers::FlatBufferBuilder &_fbb, const CaptureT *_o, const flatbuffers::rehasher_function_t *_rehasher) { 343 | (void)_rehasher; 344 | (void)_o; 345 | struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const CaptureT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; 346 | return sigmf::wifi::CreateCapture( 347 | _fbb); 348 | } 349 | 350 | inline AnnotationT *Annotation::UnPack(const flatbuffers::resolver_function_t *_resolver) const { 351 | auto _o = std::unique_ptr(new AnnotationT()); 352 | UnPackTo(_o.get(), _resolver); 353 | return _o.release(); 354 | } 355 | 356 | inline void Annotation::UnPackTo(AnnotationT *_o, const flatbuffers::resolver_function_t *_resolver) const { 357 | (void)_o; 358 | (void)_resolver; 359 | { auto _e = downlink_format(); _o->downlink_format = _e; } 360 | { auto _e = message_type(); _o->message_type = _e; } 361 | { auto _e = ICA_address(); _o->ICA_address = _e; } 362 | { auto _e = binary(); if (_e) _o->binary = _e->str(); } 363 | } 364 | 365 | inline flatbuffers::Offset Annotation::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AnnotationT* _o, const flatbuffers::rehasher_function_t *_rehasher) { 366 | return CreateAnnotation(_fbb, _o, _rehasher); 367 | } 368 | 369 | inline flatbuffers::Offset CreateAnnotation(flatbuffers::FlatBufferBuilder &_fbb, const AnnotationT *_o, const flatbuffers::rehasher_function_t *_rehasher) { 370 | (void)_rehasher; 371 | (void)_o; 372 | struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AnnotationT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; 373 | auto _downlink_format = _o->downlink_format; 374 | auto _message_type = _o->message_type; 375 | auto _ICA_address = _o->ICA_address; 376 | auto _binary = _o->binary.empty() ? 0 : _fbb.CreateString(_o->binary); 377 | return sigmf::wifi::CreateAnnotation( 378 | _fbb, 379 | _downlink_format, 380 | _message_type, 381 | _ICA_address, 382 | _binary); 383 | } 384 | 385 | inline DescrT *Descr::UnPack(const flatbuffers::resolver_function_t *_resolver) const { 386 | auto _o = std::unique_ptr(new DescrT()); 387 | UnPackTo(_o.get(), _resolver); 388 | return _o.release(); 389 | } 390 | 391 | inline void Descr::UnPackTo(DescrT *_o, const flatbuffers::resolver_function_t *_resolver) const { 392 | (void)_o; 393 | (void)_resolver; 394 | { auto _e = global(); if (_e) _o->global = std::shared_ptr(_e->UnPack(_resolver)); } 395 | { auto _e = annotation(); if (_e) _o->annotation = std::shared_ptr(_e->UnPack(_resolver)); } 396 | { auto _e = capture(); if (_e) _o->capture = std::shared_ptr(_e->UnPack(_resolver)); } 397 | } 398 | 399 | inline flatbuffers::Offset Descr::Pack(flatbuffers::FlatBufferBuilder &_fbb, const DescrT* _o, const flatbuffers::rehasher_function_t *_rehasher) { 400 | return CreateDescr(_fbb, _o, _rehasher); 401 | } 402 | 403 | inline flatbuffers::Offset CreateDescr(flatbuffers::FlatBufferBuilder &_fbb, const DescrT *_o, const flatbuffers::rehasher_function_t *_rehasher) { 404 | (void)_rehasher; 405 | (void)_o; 406 | struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const DescrT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; 407 | auto _global = _o->global ? CreateGlobal(_fbb, _o->global.get(), _rehasher) : 0; 408 | auto _annotation = _o->annotation ? CreateAnnotation(_fbb, _o->annotation.get(), _rehasher) : 0; 409 | auto _capture = _o->capture ? CreateCapture(_fbb, _o->capture.get(), _rehasher) : 0; 410 | return sigmf::wifi::CreateDescr( 411 | _fbb, 412 | _global, 413 | _annotation, 414 | _capture); 415 | } 416 | 417 | inline const flatbuffers::TypeTable *GlobalTypeTable() { 418 | static const flatbuffers::TypeTable tt = { 419 | flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr, nullptr 420 | }; 421 | return &tt; 422 | } 423 | 424 | inline const flatbuffers::TypeTable *CaptureTypeTable() { 425 | static const flatbuffers::TypeTable tt = { 426 | flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr, nullptr 427 | }; 428 | return &tt; 429 | } 430 | 431 | inline const flatbuffers::TypeTable *AnnotationTypeTable() { 432 | static const flatbuffers::TypeCode type_codes[] = { 433 | { flatbuffers::ET_LONG, 0, -1 }, 434 | { flatbuffers::ET_LONG, 0, -1 }, 435 | { flatbuffers::ET_DOUBLE, 0, -1 }, 436 | { flatbuffers::ET_STRING, 0, -1 } 437 | }; 438 | static const char * const names[] = { 439 | "downlink_format", 440 | "message_type", 441 | "ICA_address", 442 | "binary" 443 | }; 444 | static const flatbuffers::TypeTable tt = { 445 | flatbuffers::ST_TABLE, 4, type_codes, nullptr, nullptr, nullptr, names 446 | }; 447 | return &tt; 448 | } 449 | 450 | inline const flatbuffers::TypeTable *DescrTypeTable() { 451 | static const flatbuffers::TypeCode type_codes[] = { 452 | { flatbuffers::ET_SEQUENCE, 0, 0 }, 453 | { flatbuffers::ET_SEQUENCE, 0, 1 }, 454 | { flatbuffers::ET_SEQUENCE, 0, 2 } 455 | }; 456 | static const flatbuffers::TypeFunction type_refs[] = { 457 | sigmf::wifi::GlobalTypeTable, 458 | sigmf::wifi::AnnotationTypeTable, 459 | sigmf::wifi::CaptureTypeTable 460 | }; 461 | static const char * const names[] = { 462 | "global", 463 | "annotation", 464 | "capture" 465 | }; 466 | static const flatbuffers::TypeTable tt = { 467 | flatbuffers::ST_TABLE, 3, type_codes, type_refs, nullptr, nullptr, names 468 | }; 469 | return &tt; 470 | } 471 | 472 | } // namespace wifi 473 | } // namespace sigmf 474 | 475 | #endif // FLATBUFFERS_GENERATED_SIGMFWIFI_SIGMF_WIFI_H_ 476 | -------------------------------------------------------------------------------- /sigmf_protocols/testing_protocols.fbs: -------------------------------------------------------------------------------- 1 | 2 | table testing_vecs { 3 | myvecfortesting: [uint32]; 4 | name: string; 5 | } 6 | 7 | table one { 8 | fieldone: float; 9 | } 10 | 11 | table two { 12 | fieldtwo: float; 13 | } 14 | 15 | table three { 16 | fieldthree: float; 17 | } 18 | 19 | table very_nested_thing { 20 | wow: uint64; 21 | } 22 | 23 | table composed_type { 24 | name: string; 25 | comments: [string]; 26 | index: int32; 27 | nnnnnn: [very_nested_thing]; 28 | } 29 | 30 | union myunion { 31 | one, two, three 32 | } 33 | 34 | table testingunions { 35 | myfield: myunion; 36 | dumbfield: int; 37 | } 38 | -------------------------------------------------------------------------------- /src/annotation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef LIBSIGMF_ANNOTATIONS_H 18 | #define LIBSIGMF_ANNOTATIONS_H 19 | 20 | #include "variadic_data_class.h" 21 | 22 | /* 23 | * Helper macros-- mixed opinions abound! 24 | */ 25 | #define ca0(x0) Annotation 26 | 27 | #define ca1(x0, x1) Annotation 28 | 29 | #define ca2(x0, x1, x2) Annotation 30 | 31 | #define ca3(x0, x1, x2, x3) Annotation 32 | 33 | #define ca4(x0, x1, x2, x3, x4) Annotation 35 | 36 | #define ca5(x0, x1, x2, x3, x4, x5) Annotation 38 | 39 | #define ca6(x0, x1, x2, x3, x4, x5, x6) Annotation 41 | 42 | #define ca7(x0, x1, x2, x3, x4, x5, x6, x7) Annotation 44 | 45 | #define ca8(x0, x1, x2, x3, x4, x5, x6, x7, x8) Annotation 47 | 48 | #define ca9(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) Annotation 50 | 51 | 52 | #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME 53 | #define create_annotation(...) GET_MACRO(__VA_ARGS__, ca9, ca8, ca7, ca6, ca5, ca4, ca3, ca2, ca1, ca0)(__VA_ARGS__) 54 | 55 | #define sigmfns(x) get() 56 | 57 | 58 | namespace sigmf { 59 | 60 | // This template is mostly here so we can specialize it. If we can get an expansion/loop of T... so that for every 61 | // T we can create a VariadicDataClass 63 | class Annotation : public VariadicDataClass { 64 | }; 65 | 66 | template 67 | class Annotation 68 | : public VariadicDataClass::element_type> { 69 | public: 70 | template 71 | auto &get() {// -> typename std::pointer_traits::element_type& { 72 | return this->template access::element_type>(); 73 | } 74 | }; 75 | 76 | template 77 | class Annotation 78 | : public VariadicDataClass::element_type, 79 | typename std::pointer_traits::element_type> { 80 | public: 81 | template 82 | auto &get() { 83 | return this->template access::element_type>(); 84 | } 85 | }; 86 | 87 | template 88 | class Annotation 89 | : public VariadicDataClass::element_type, 90 | typename std::pointer_traits::element_type, 91 | typename std::pointer_traits::element_type> { 92 | public: 93 | template 94 | auto &get() { 95 | return this->template access::element_type>(); 96 | } 97 | }; 98 | 99 | 100 | template 101 | class Annotation 102 | : public VariadicDataClass::element_type, 103 | typename std::pointer_traits::element_type, 104 | typename std::pointer_traits::element_type, 105 | typename std::pointer_traits::element_type> { 106 | public: 107 | template 108 | auto &get() { 109 | return this->template access::element_type>(); 110 | } 111 | }; 112 | 113 | template 114 | class Annotation 115 | : public VariadicDataClass::element_type, 116 | typename std::pointer_traits::element_type, 117 | typename std::pointer_traits::element_type, 118 | typename std::pointer_traits::element_type, 119 | typename std::pointer_traits::element_type> { 120 | public: 121 | template 122 | auto &get() { 123 | return this->template access::element_type>(); 124 | } 125 | }; 126 | 127 | template 128 | class Annotation 129 | : public VariadicDataClass::element_type, 130 | typename std::pointer_traits::element_type, 131 | typename std::pointer_traits::element_type, 132 | typename std::pointer_traits::element_type, 133 | typename std::pointer_traits::element_type, 134 | typename std::pointer_traits::element_type> { 135 | public: 136 | template 137 | auto &get() { 138 | return this->template access::element_type>(); 139 | } 140 | }; 141 | 142 | template 143 | class Annotation 144 | : public VariadicDataClass::element_type, 145 | typename std::pointer_traits::element_type, 146 | typename std::pointer_traits::element_type, 147 | typename std::pointer_traits::element_type, 148 | typename std::pointer_traits::element_type, 149 | typename std::pointer_traits::element_type, 150 | typename std::pointer_traits::element_type> { 151 | public: 152 | template 153 | auto &get() { 154 | return this->template access::element_type>(); 155 | } 156 | }; 157 | 158 | template 159 | class Annotation 160 | : public VariadicDataClass::element_type, 161 | typename std::pointer_traits::element_type, 162 | typename std::pointer_traits::element_type, 163 | typename std::pointer_traits::element_type, 164 | typename std::pointer_traits::element_type, 165 | typename std::pointer_traits::element_type, 166 | typename std::pointer_traits::element_type, 167 | typename std::pointer_traits::element_type> { 168 | public: 169 | template 170 | auto &get() { 171 | return this->template access::element_type>(); 172 | } 173 | }; 174 | 175 | template 176 | class Annotation 177 | : public VariadicDataClass::element_type, 178 | typename std::pointer_traits::element_type, 179 | typename std::pointer_traits::element_type, 180 | typename std::pointer_traits::element_type, 181 | typename std::pointer_traits::element_type, 182 | typename std::pointer_traits::element_type, 183 | typename std::pointer_traits::element_type, 184 | typename std::pointer_traits::element_type, 185 | typename std::pointer_traits::element_type> { 186 | public: 187 | template 188 | auto &get() { 189 | return this->template access::element_type>(); 190 | } 191 | }; 192 | 193 | template 194 | class Annotation 195 | : public VariadicDataClass::element_type, 196 | typename std::pointer_traits::element_type, 197 | typename std::pointer_traits::element_type, 198 | typename std::pointer_traits::element_type, 199 | typename std::pointer_traits::element_type, 200 | typename std::pointer_traits::element_type, 201 | typename std::pointer_traits::element_type, 202 | typename std::pointer_traits::element_type, 203 | typename std::pointer_traits::element_type, 204 | typename std::pointer_traits::element_type> { 205 | public: 206 | template 207 | auto &get() { 208 | return this->template access::element_type>(); 209 | } 210 | }; 211 | 212 | } // namespace sigmf 213 | 214 | #endif //LIBSIGMF_ANNOTATIONS_H 215 | -------------------------------------------------------------------------------- /src/capture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef LIBSIGMF_CAPTURE_H 18 | #define LIBSIGMF_CAPTURE_H 19 | 20 | #include "variadic_data_class.h" 21 | 22 | /* 23 | * Helper macros-- mixed opinions abound! 24 | */ 25 | #define cc0(x0) Capture 26 | 27 | #define cc1(x0, x1) Capture 28 | 29 | #define cc2(x0, x1, x2) Capture 30 | 31 | #define cc3(x0, x1, x2, x3) Capture 32 | 33 | #define cc4(x0, x1, x2, x3, x4) Capture 35 | 36 | #define cc5(x0, x1, x2, x3, x4, x5) Capture 38 | 39 | #define cc6(x0, x1, x2, x3, x4, x5, x6) Capture 41 | 42 | #define cc7(x0, x1, x2, x3, x4, x5, x6, x7) Capture 44 | 45 | #define cc8(x0, x1, x2, x3, x4, x5, x6, x7, x8) Capture 47 | 48 | #define cc9(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) Capture 50 | 51 | 52 | #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME 53 | #define create_capture(...) GET_MACRO(__VA_ARGS__, cc9, cc8, cc7, cc6, cc5, cc4, cc3, cc2, cc1, cc0)(__VA_ARGS__) 54 | 55 | 56 | namespace sigmf { 57 | 58 | // This template is mostly here so we can specialize it. If we can get an expansion/loop of T... so that for every 59 | // T we can create a VariadicDataClass 61 | class Capture : public VariadicDataClass { 62 | }; 63 | 64 | template 65 | class Capture 66 | : public VariadicDataClass::element_type> { 67 | public: 68 | template 69 | auto &get() {// -> typename std::pointer_traits::element_type& { 70 | return this->template access::element_type>(); 71 | } 72 | }; 73 | 74 | template 75 | class Capture 76 | : public VariadicDataClass::element_type, 77 | typename std::pointer_traits::element_type> { 78 | public: 79 | template 80 | auto &get() { 81 | return this->template access::element_type>(); 82 | } 83 | }; 84 | 85 | template 86 | class Capture 87 | : public VariadicDataClass::element_type, 88 | typename std::pointer_traits::element_type, 89 | typename std::pointer_traits::element_type> { 90 | public: 91 | template 92 | auto &get() { 93 | return this->template access::element_type>(); 94 | } 95 | }; 96 | 97 | 98 | template 99 | class Capture 100 | : public VariadicDataClass::element_type, 101 | typename std::pointer_traits::element_type, 102 | typename std::pointer_traits::element_type, 103 | typename std::pointer_traits::element_type> { 104 | public: 105 | template 106 | auto &get() { 107 | return this->template access::element_type>(); 108 | } 109 | }; 110 | 111 | template 112 | class Capture 113 | : public VariadicDataClass::element_type, 114 | typename std::pointer_traits::element_type, 115 | typename std::pointer_traits::element_type, 116 | typename std::pointer_traits::element_type, 117 | typename std::pointer_traits::element_type> { 118 | public: 119 | template 120 | auto &get() { 121 | return this->template access::element_type>(); 122 | } 123 | }; 124 | 125 | template 126 | class Capture 127 | : public VariadicDataClass::element_type, 128 | typename std::pointer_traits::element_type, 129 | typename std::pointer_traits::element_type, 130 | typename std::pointer_traits::element_type, 131 | typename std::pointer_traits::element_type, 132 | typename std::pointer_traits::element_type> { 133 | public: 134 | template 135 | auto &get() { 136 | return this->template access::element_type>(); 137 | } 138 | }; 139 | 140 | template 141 | class Capture 142 | : public VariadicDataClass::element_type, 143 | typename std::pointer_traits::element_type, 144 | typename std::pointer_traits::element_type, 145 | typename std::pointer_traits::element_type, 146 | typename std::pointer_traits::element_type, 147 | typename std::pointer_traits::element_type, 148 | typename std::pointer_traits::element_type> { 149 | public: 150 | template 151 | auto &get() { 152 | return this->template access::element_type>(); 153 | } 154 | }; 155 | 156 | template 157 | class Capture 158 | : public VariadicDataClass::element_type, 159 | typename std::pointer_traits::element_type, 160 | typename std::pointer_traits::element_type, 161 | typename std::pointer_traits::element_type, 162 | typename std::pointer_traits::element_type, 163 | typename std::pointer_traits::element_type, 164 | typename std::pointer_traits::element_type, 165 | typename std::pointer_traits::element_type> { 166 | public: 167 | template 168 | auto &get() { 169 | return this->template access::element_type>(); 170 | } 171 | }; 172 | 173 | template 174 | class Capture 175 | : public VariadicDataClass::element_type, 176 | typename std::pointer_traits::element_type, 177 | typename std::pointer_traits::element_type, 178 | typename std::pointer_traits::element_type, 179 | typename std::pointer_traits::element_type, 180 | typename std::pointer_traits::element_type, 181 | typename std::pointer_traits::element_type, 182 | typename std::pointer_traits::element_type, 183 | typename std::pointer_traits::element_type> { 184 | public: 185 | template 186 | auto &get() { 187 | return this->template access::element_type>(); 188 | } 189 | }; 190 | 191 | template 192 | class Capture 193 | : public VariadicDataClass::element_type, 194 | typename std::pointer_traits::element_type, 195 | typename std::pointer_traits::element_type, 196 | typename std::pointer_traits::element_type, 197 | typename std::pointer_traits::element_type, 198 | typename std::pointer_traits::element_type, 199 | typename std::pointer_traits::element_type, 200 | typename std::pointer_traits::element_type, 201 | typename std::pointer_traits::element_type, 202 | typename std::pointer_traits::element_type> { 203 | public: 204 | template 205 | auto &get() { 206 | return this->template access::element_type>(); 207 | } 208 | }; 209 | 210 | } // namespace sigmf 211 | 212 | #endif //LIBSIGMF_ANNOTATIONS_H 213 | -------------------------------------------------------------------------------- /src/collection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef LIBSIGMF_COLLECTION_H 18 | #define LIBSIGMF_COLLECTION_H 19 | 20 | #include "variadic_data_class.h" 21 | 22 | /* 23 | * Helper macros-- mixed opinions abound! 24 | */ 25 | #define cl0(x0) Collection 26 | 27 | #define cl1(x0, x1) Collection 28 | 29 | #define cl2(x0, x1, x2) Collection 30 | 31 | #define cl3(x0, x1, x2, x3) Collection 32 | 33 | #define cl4(x0, x1, x2, x3, x4) Collection 35 | 36 | #define cl5(x0, x1, x2, x3, x4, x5) Collection 38 | 39 | #define cl6(x0, x1, x2, x3, x4, x5, x6) Collection 41 | 42 | #define cl7(x0, x1, x2, x3, x4, x5, x6, x7) Collection 44 | 45 | #define cl8(x0, x1, x2, x3, x4, x5, x6, x7, x8) Collection 47 | 48 | #define cl9(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) Collection 50 | 51 | 52 | #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME 53 | #define create_collection(...) GET_MACRO(__VA_ARGS__, cl9, cl8, cl7, cl6, cl5, cl4, cl3, cl2, cl1, cl0)(__VA_ARGS__) 54 | 55 | #define sigmfns(x) get() 56 | 57 | 58 | namespace sigmf { 59 | 60 | // This template is mostly here so we cln specialize it. If we cln get an expansion/loop of T... so that for every 61 | // T we cln create a VariadicDataClass 63 | class Collection : public VariadicDataClass { 64 | }; 65 | 66 | template 67 | class Collection 68 | : public VariadicDataClass::element_type> { 69 | public: 70 | template 71 | auto &get() {// -> typename std::pointer_traits::element_type& { 72 | return this->template access::element_type>(); 73 | } 74 | }; 75 | 76 | template 77 | class Collection 78 | : public VariadicDataClass::element_type, 79 | typename std::pointer_traits::element_type> { 80 | public: 81 | template 82 | auto &get() { 83 | return this->template access::element_type>(); 84 | } 85 | }; 86 | 87 | template 88 | class Collection 89 | : public VariadicDataClass::element_type, 90 | typename std::pointer_traits::element_type, 91 | typename std::pointer_traits::element_type> { 92 | public: 93 | template 94 | auto &get() { 95 | return this->template access::element_type>(); 96 | } 97 | }; 98 | 99 | 100 | template 101 | class Collection 102 | : public VariadicDataClass::element_type, 103 | typename std::pointer_traits::element_type, 104 | typename std::pointer_traits::element_type, 105 | typename std::pointer_traits::element_type> { 106 | public: 107 | template 108 | auto &get() { 109 | return this->template access::element_type>(); 110 | } 111 | }; 112 | 113 | template 114 | class Collection 115 | : public VariadicDataClass::element_type, 116 | typename std::pointer_traits::element_type, 117 | typename std::pointer_traits::element_type, 118 | typename std::pointer_traits::element_type, 119 | typename std::pointer_traits::element_type> { 120 | public: 121 | template 122 | auto &get() { 123 | return this->template access::element_type>(); 124 | } 125 | }; 126 | 127 | template 128 | class Collection 129 | : public VariadicDataClass::element_type, 130 | typename std::pointer_traits::element_type, 131 | typename std::pointer_traits::element_type, 132 | typename std::pointer_traits::element_type, 133 | typename std::pointer_traits::element_type, 134 | typename std::pointer_traits::element_type> { 135 | public: 136 | template 137 | auto &get() { 138 | return this->template access::element_type>(); 139 | } 140 | }; 141 | 142 | template 143 | class Collection 144 | : public VariadicDataClass::element_type, 145 | typename std::pointer_traits::element_type, 146 | typename std::pointer_traits::element_type, 147 | typename std::pointer_traits::element_type, 148 | typename std::pointer_traits::element_type, 149 | typename std::pointer_traits::element_type, 150 | typename std::pointer_traits::element_type> { 151 | public: 152 | template 153 | auto &get() { 154 | return this->template access::element_type>(); 155 | } 156 | }; 157 | 158 | template 159 | class Collection 160 | : public VariadicDataClass::element_type, 161 | typename std::pointer_traits::element_type, 162 | typename std::pointer_traits::element_type, 163 | typename std::pointer_traits::element_type, 164 | typename std::pointer_traits::element_type, 165 | typename std::pointer_traits::element_type, 166 | typename std::pointer_traits::element_type, 167 | typename std::pointer_traits::element_type> { 168 | public: 169 | template 170 | auto &get() { 171 | return this->template access::element_type>(); 172 | } 173 | }; 174 | 175 | template 176 | class Collection 177 | : public VariadicDataClass::element_type, 178 | typename std::pointer_traits::element_type, 179 | typename std::pointer_traits::element_type, 180 | typename std::pointer_traits::element_type, 181 | typename std::pointer_traits::element_type, 182 | typename std::pointer_traits::element_type, 183 | typename std::pointer_traits::element_type, 184 | typename std::pointer_traits::element_type, 185 | typename std::pointer_traits::element_type> { 186 | public: 187 | template 188 | auto &get() { 189 | return this->template access::element_type>(); 190 | } 191 | }; 192 | 193 | template 194 | class Collection 195 | : public VariadicDataClass::element_type, 196 | typename std::pointer_traits::element_type, 197 | typename std::pointer_traits::element_type, 198 | typename std::pointer_traits::element_type, 199 | typename std::pointer_traits::element_type, 200 | typename std::pointer_traits::element_type, 201 | typename std::pointer_traits::element_type, 202 | typename std::pointer_traits::element_type, 203 | typename std::pointer_traits::element_type, 204 | typename std::pointer_traits::element_type> { 205 | public: 206 | template 207 | auto &get() { 208 | return this->template access::element_type>(); 209 | } 210 | }; 211 | 212 | } // namespace sigmf 213 | 214 | #endif //LIBSIGMF_COLLECTION_H 215 | -------------------------------------------------------------------------------- /src/flatbuffers_type_to_json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2021, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include "variadic_data_class.h" 19 | #include 20 | #include 21 | 22 | #ifndef OMNISIG_FLATBUFFERS_TYPE_TO_JSON_H 23 | #define OMNISIG_FLATBUFFERS_TYPE_TO_JSON_H 24 | 25 | using json = nlohmann::json; 26 | 27 | namespace sigmf { 28 | 29 | template 30 | static json to_json(const typename R::NativeTableType &obj) { 31 | 32 | R *ttype; 33 | 34 | flatbuffers::FlatBufferBuilder fbb; 35 | auto loc = ttype->Pack(fbb, &obj); 36 | fbb.Finish(loc); 37 | 38 | auto bfrptr = fbb.GetBufferPointer(); 39 | auto rtptr = flatbuffers::GetRoot(bfrptr); 40 | json asjson = FlatBufferToJson(rtptr, ttype->MiniReflectTypeTable(), ""); 41 | 42 | return asjson; 43 | } 44 | 45 | template 46 | static typename R::NativeTableType from_json(json json_value) { 47 | R *ttype; 48 | typename R::NativeTableType return_object; 49 | 50 | auto reflection_table = ttype->MiniReflectTypeTable(); 51 | 52 | FromSigMFVisitor dumb_ripoff_visitor("", json_value); 53 | IterateType(reflection_table, &dumb_ripoff_visitor, json_value); 54 | dumb_ripoff_visitor.fbb.Finish(flatbuffers::Offset(dumb_ripoff_visitor._stop)); 55 | 56 | auto *annoptr = flatbuffers::GetRoot(dumb_ripoff_visitor.fbb.GetBufferPointer()); 57 | annoptr->UnPackTo(&return_object); 58 | 59 | return return_object; 60 | } 61 | 62 | } // namespace sigmf 63 | 64 | #endif //OMNISIG_FLATBUFFERS_TYPE_TO_JSON_H 65 | -------------------------------------------------------------------------------- /src/global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef LIBSIGMF_GLOBAL_H 18 | #define LIBSIGMF_GLOBAL_H 19 | 20 | #include "variadic_data_class.h" 21 | 22 | /* 23 | * Helper macros-- mixed opinions abound! 24 | */ 25 | #define cg0(x0) Global 26 | 27 | #define cg1(x0, x1) Global 28 | 29 | #define cg2(x0, x1, x2) Global 30 | 31 | #define cg3(x0, x1, x2, x3) Global 32 | 33 | #define cg4(x0, x1, x2, x3, x4) Global 35 | 36 | #define cg5(x0, x1, x2, x3, x4, x5) Global 38 | 39 | #define cg6(x0, x1, x2, x3, x4, x5, x6) Global 41 | 42 | #define cg7(x0, x1, x2, x3, x4, x5, x6, x7) Global 44 | 45 | #define cg8(x0, x1, x2, x3, x4, x5, x6, x7, x8) Global 47 | 48 | #define cg9(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) Global 50 | 51 | 52 | #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME 53 | #define create_global(...) GET_MACRO(__VA_ARGS__, cg9, cg8, cg7, cg6, cg5, cg4, cg3, cg2, cg1, cg0)(__VA_ARGS__) 54 | 55 | 56 | namespace sigmf { 57 | 58 | // This template is mostly here so we can specialize it. If we can get an expansion/loop of T... so that for every 59 | // T we can create a VariadicDataClass 61 | class Global : public VariadicDataClass { 62 | }; 63 | 64 | template 65 | class Global 66 | : public VariadicDataClass::element_type> { 67 | public: 68 | template 69 | auto &get() {// -> typename std::pointer_traits::element_type& { 70 | return this->template access::element_type>(); 71 | } 72 | }; 73 | 74 | template 75 | class Global 76 | : public VariadicDataClass::element_type, 77 | typename std::pointer_traits::element_type> { 78 | public: 79 | template 80 | auto &get() { 81 | return this->template access::element_type>(); 82 | } 83 | }; 84 | 85 | template 86 | class Global 87 | : public VariadicDataClass::element_type, 88 | typename std::pointer_traits::element_type, 89 | typename std::pointer_traits::element_type> { 90 | public: 91 | template 92 | auto &get() { 93 | return this->template access::element_type>(); 94 | } 95 | }; 96 | 97 | 98 | template 99 | class Global 100 | : public VariadicDataClass::element_type, 101 | typename std::pointer_traits::element_type, 102 | typename std::pointer_traits::element_type, 103 | typename std::pointer_traits::element_type> { 104 | public: 105 | template 106 | auto &get() { 107 | return this->template access::element_type>(); 108 | } 109 | }; 110 | 111 | template 112 | class Global 113 | : public VariadicDataClass::element_type, 114 | typename std::pointer_traits::element_type, 115 | typename std::pointer_traits::element_type, 116 | typename std::pointer_traits::element_type, 117 | typename std::pointer_traits::element_type> { 118 | public: 119 | template 120 | auto &get() { 121 | return this->template access::element_type>(); 122 | } 123 | }; 124 | 125 | template 126 | class Global 127 | : public VariadicDataClass::element_type, 128 | typename std::pointer_traits::element_type, 129 | typename std::pointer_traits::element_type, 130 | typename std::pointer_traits::element_type, 131 | typename std::pointer_traits::element_type, 132 | typename std::pointer_traits::element_type> { 133 | public: 134 | template 135 | auto &get() { 136 | return this->template access::element_type>(); 137 | } 138 | }; 139 | 140 | template 141 | class Global 142 | : public VariadicDataClass::element_type, 143 | typename std::pointer_traits::element_type, 144 | typename std::pointer_traits::element_type, 145 | typename std::pointer_traits::element_type, 146 | typename std::pointer_traits::element_type, 147 | typename std::pointer_traits::element_type, 148 | typename std::pointer_traits::element_type> { 149 | public: 150 | template 151 | auto &get() { 152 | return this->template access::element_type>(); 153 | } 154 | }; 155 | 156 | template 157 | class Global 158 | : public VariadicDataClass::element_type, 159 | typename std::pointer_traits::element_type, 160 | typename std::pointer_traits::element_type, 161 | typename std::pointer_traits::element_type, 162 | typename std::pointer_traits::element_type, 163 | typename std::pointer_traits::element_type, 164 | typename std::pointer_traits::element_type, 165 | typename std::pointer_traits::element_type> { 166 | public: 167 | template 168 | auto &get() { 169 | return this->template access::element_type>(); 170 | } 171 | }; 172 | 173 | template 174 | class Global 175 | : public VariadicDataClass::element_type, 176 | typename std::pointer_traits::element_type, 177 | typename std::pointer_traits::element_type, 178 | typename std::pointer_traits::element_type, 179 | typename std::pointer_traits::element_type, 180 | typename std::pointer_traits::element_type, 181 | typename std::pointer_traits::element_type, 182 | typename std::pointer_traits::element_type, 183 | typename std::pointer_traits::element_type> { 184 | public: 185 | template 186 | auto &get() { 187 | return this->template access::element_type>(); 188 | } 189 | }; 190 | 191 | template 192 | class Global 193 | : public VariadicDataClass::element_type, 194 | typename std::pointer_traits::element_type, 195 | typename std::pointer_traits::element_type, 196 | typename std::pointer_traits::element_type, 197 | typename std::pointer_traits::element_type, 198 | typename std::pointer_traits::element_type, 199 | typename std::pointer_traits::element_type, 200 | typename std::pointer_traits::element_type, 201 | typename std::pointer_traits::element_type, 202 | typename std::pointer_traits::element_type> { 203 | public: 204 | template 205 | auto &get() { 206 | return this->template access::element_type>(); 207 | } 208 | }; 209 | 210 | } // namespace sigmf 211 | 212 | #endif //LIBSIGMF_ANNOTATIONS_H 213 | -------------------------------------------------------------------------------- /src/sigmf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2021, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef LIBSIGMF_SIGMF_H 18 | #define LIBSIGMF_SIGMF_H 19 | 20 | #include "variadic_data_class.h" 21 | #include "global.h" 22 | #include "capture.h" 23 | #include "annotation.h" 24 | #include "collection.h" 25 | #include "sigmf_core_generated.h" 26 | #include "sigmf_antenna_generated.h" 27 | #include "sigmf_capture_details_generated.h" 28 | #include "sigmf_signal_generated.h" 29 | #include 30 | #include 31 | 32 | 33 | namespace sigmf { 34 | 35 | template 36 | class SigMFVector : public std::vector { 37 | public: 38 | T &create_new() { 39 | T new_element; 40 | this->emplace_back(new_element); 41 | return this->back(); 42 | } 43 | }; 44 | 45 | template 46 | struct SigMF { 47 | GlobalType global; 48 | SigMFVector captures; 49 | SigMFVector annotations; 50 | 51 | /** 52 | * Export the record to a JSON object 53 | */ 54 | json to_json() const { 55 | json j; 56 | j["global"] = global.to_json(); 57 | j["captures"] = captures; 58 | j["annotations"] = annotations; 59 | return j; 60 | } 61 | 62 | /** 63 | * Write over the fields with a new record from a JSON object 64 | */ 65 | void from_json(const json &j) { 66 | global.from_json(j["global"]); 67 | captures.clear(); 68 | annotations.clear(); 69 | for (auto &element : j["annotations"]) { 70 | AnnotationType a; 71 | a.from_json(element); 72 | annotations.emplace_back(a); 73 | } 74 | for (auto &element : j["captures"]) { 75 | CaptureType c; 76 | c.from_json(element); 77 | captures.emplace_back(c); 78 | } 79 | } 80 | }; 81 | 82 | template 83 | struct SigMFCollection { 84 | CollectionType collection; 85 | 86 | /** 87 | * Export the record to a JSON object 88 | */ 89 | json to_json() const { 90 | json j; 91 | j["collection"] = collection.to_json(); 92 | return j; 93 | } 94 | 95 | /** 96 | * Write over the fields with a new record from a JSON object 97 | */ 98 | void from_json(const json &j) { 99 | collection.from_json(j["collection"]); 100 | } 101 | }; 102 | 103 | /* 104 | * This makes conversion between json types and SigMF types work out of the box 105 | */ 106 | 107 | template 108 | void to_json(json &j, const SigMF &t) { 109 | j = t.to_json(); 110 | } 111 | 112 | template 113 | void from_json(const json &j, SigMF &t) { 114 | t.from_json(j); 115 | } 116 | 117 | template 118 | void to_json(json &j, const SigMFCollection &t) { 119 | j = t.to_json(); 120 | } 121 | 122 | template 123 | void from_json(const json &j, SigMFCollection &t) { 124 | t.from_json(j); 125 | } 126 | 127 | } // namespace sigmf 128 | 129 | #endif //LIBSIGMF_SIGMF_H 130 | -------------------------------------------------------------------------------- /src/sigmf_helpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2021, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef SIGMF_HELPERS_H 18 | #define SIGMF_HELPERS_H 19 | 20 | #include "sigmf.h" 21 | #include "sigmf_core_generated.h" 22 | #include "sigmf_antenna_generated.h" 23 | #include "sigmf_capture_details_generated.h" 24 | #include "sigmf_signal_generated.h" 25 | #include 26 | 27 | 28 | namespace sigmf { 29 | 30 | /** 31 | * 32 | * Sort elements of SigMF Vector 33 | * 34 | * Standard in place sort using sample_start as the comparand 35 | * 36 | * @param sigmf_vector SigMF vector to be sorted 37 | */ 38 | template 39 | void sort_sigmf_vector(sigmf::SigMFVector &sigmf_vector) { 40 | std::sort(sigmf_vector.begin(), sigmf_vector.end(), 41 | [](typename sigmf::SigMFVector::value_type first, 42 | typename sigmf::SigMFVector::value_type second) -> bool { 43 | return (first.template get().sample_start < 44 | second.template get().sample_start); 45 | }); 46 | } 47 | 48 | /** 49 | * 50 | * Get SigMF element applicable to sample 51 | * 52 | * NOTE: SigMF Vector should be validated before calling this function 53 | * 54 | * @param sample_number The sample_start of target annotation 55 | * @param sigmf_vector Reference to non-empty SigMF vector 56 | * @return Iterator to SigMF element 57 | * 58 | */ 59 | template 60 | typename VectorT::iterator get_first_of_sigmf_vector(ComparisonT sample_number, VectorT &sigmf_vector) { 61 | // get iterator to first SigMF item with a sample_start greater than the reference sample_start 62 | // NOTE: if no capture sample_start is greater then `upper_bound === sigmf_vector.end()` 63 | if(sigmf_vector.empty()) { 64 | throw std::runtime_error("Invalid memory access attempted on SigMF vector."); 65 | } 66 | 67 | auto upper_bound = std::upper_bound(sigmf_vector.begin(), sigmf_vector.end(), sample_number, 68 | [](ComparisonT sample_number_to_compare, 69 | typename VectorT::value_type first 70 | ) -> bool { 71 | return sample_number_to_compare < 72 | first.template get().sample_start; 73 | } 74 | ); 75 | 76 | // return the capture right before the upper_bound 77 | return (upper_bound - 1); 78 | } 79 | 80 | /** 81 | * 82 | * Get a subset of SigMF data that applies to a specific number of samples, 83 | * and normalized to a sample_start, from a larger set of SigMF data 84 | * 85 | * @param input_md Full set of SigMF data 86 | * @param segment_sample_start Starting sample to normalize 87 | * @param segment_sample_count Number of samples in subset 88 | * 89 | * @return Applicable subset of SigMF data 90 | * 91 | */ 92 | template 93 | sigmf::SigMF 94 | get_sigmf_in_range(sigmf::SigMF &input_md, uint64_t segment_sample_start, uint64_t segment_sample_count) { 95 | sigmf::SigMF new_md; 96 | // Copy global data to latest_metadata 97 | new_md.global = input_md.global; 98 | 99 | // Copy the normalized captures in range to the latest_metadata 100 | sort_sigmf_vector(input_md.captures); 101 | auto applicable_capture = get_first_of_sigmf_vector(segment_sample_start, input_md.captures); 102 | while (applicable_capture != input_md.captures.end() && 103 | (applicable_capture->template get().sample_start < 104 | (segment_sample_start + segment_sample_count))) { 105 | auto new_capture = *applicable_capture; 106 | if (segment_sample_start < new_capture.template get().sample_start.value_or(0)) { 107 | new_capture.template get().sample_start = 108 | new_capture.template get().sample_start.value_or(0) - segment_sample_start; 109 | } else { 110 | new_capture.template get().sample_start = 0; 111 | } 112 | new_md.captures.emplace_back(new_capture); 113 | ++applicable_capture; 114 | } 115 | 116 | // Copy the annotations in range to the latest_metadata 117 | sort_sigmf_vector(input_md.annotations); 118 | auto original_annotation = input_md.annotations.begin(); 119 | while (original_annotation != input_md.annotations.end()) { 120 | bool increment_iterator = true; 121 | core::AnnotationT &original_annotation_md = original_annotation->template get(); 122 | 123 | if (!original_annotation_md.sample_start.has_value()) { 124 | continue; // this is not a valid annotation, skip it 125 | } 126 | 127 | if (original_annotation_md.sample_start.value() >= (segment_sample_start + segment_sample_count)) { 128 | // annotations are in sorted order, if above is true, all other annotations will be out of bounds 129 | break; 130 | } else if ((original_annotation_md.sample_start.value() + original_annotation_md.sample_count.value_or(0)) > 131 | segment_sample_start) { 132 | auto new_annotation = *original_annotation; 133 | uint64_t start_offset = std::max(original_annotation_md.sample_start.value(), segment_sample_start); 134 | uint64_t count_from_new_offset = 135 | original_annotation_md.sample_start.value() + original_annotation_md.sample_count.value_or(0) - start_offset; 136 | uint64_t new_start = start_offset - segment_sample_start; 137 | uint64_t new_count = std::min(count_from_new_offset, segment_sample_count - new_start); 138 | 139 | auto first_applicable_capture = get_first_of_sigmf_vector(new_start, new_md.captures); 140 | auto new_sample_last = new_start + new_count - 1; 141 | auto last_applicable_capture = get_first_of_sigmf_vector(new_sample_last, new_md.captures); 142 | 143 | if (first_applicable_capture != last_applicable_capture) { 144 | auto next_applicable_capture = first_applicable_capture + 1; 145 | 146 | new_count = next_applicable_capture->template get().sample_start.value() 147 | - new_start; 148 | 149 | auto implicit_annotation = *original_annotation; 150 | implicit_annotation.template get().sample_start = 151 | next_applicable_capture->template get().sample_start.value() + 152 | segment_sample_start; 153 | 154 | original_annotation_md.sample_count = 155 | implicit_annotation.template get().sample_start.value() - 156 | original_annotation_md.sample_start.value(); 157 | 158 | implicit_annotation.template get().sample_count = 159 | implicit_annotation.template get().sample_count.value_or(0) - 160 | original_annotation_md.sample_count.value_or(0); 161 | if (implicit_annotation.template get().sample_start.value() < 162 | (segment_sample_start + segment_sample_count)) { 163 | original_annotation = input_md.annotations.insert((original_annotation + 1), 164 | implicit_annotation); 165 | increment_iterator = false; 166 | } 167 | } 168 | new_annotation.template get().sample_start = new_start; 169 | new_annotation.template get().sample_count = new_count; 170 | new_md.annotations.emplace_back(new_annotation); 171 | } 172 | if (increment_iterator) { 173 | original_annotation++; 174 | } 175 | } 176 | return std::move(new_md); 177 | } 178 | 179 | /** 180 | * 181 | * Read data from SigMF file into SigMF object 182 | * 183 | * @param meta_file Constant reference input file stream 184 | * @return Pointer to SigMF object 185 | * 186 | */ 187 | static std::unique_ptr, 188 | sigmf::Capture, 189 | sigmf::Annotation>> 190 | metadata_file_to_json(const std::ifstream &meta_file) { 191 | 192 | std::ostringstream meta_buffer; 193 | meta_buffer << meta_file.rdbuf(); 194 | auto sigmf_md = std::make_unique, 196 | sigmf::Capture, 197 | sigmf::Annotation>>(); 198 | 199 | *sigmf_md = json::parse(meta_buffer.str()); 200 | return sigmf_md; 201 | } 202 | 203 | /** 204 | * 205 | * Returns the size of a single data sample in bytes given the datatype string 206 | * 207 | * @param datatype_string 208 | * @return size of a sample in bytes 209 | */ 210 | static uint32_t get_sample_size(std::string dtype_str) 211 | { 212 | uint32_t sample_size; 213 | // possible bit widths are 64, 32, 16, 8 214 | if (dtype_str.find("64") != std::string::npos) { 215 | sample_size = 8; 216 | } else if (dtype_str.find("32") != std::string::npos) { 217 | sample_size = 4; 218 | } else if (dtype_str.find("16") != std::string::npos) { 219 | sample_size = 2; 220 | } else if (dtype_str.find("8") != std::string::npos) { 221 | sample_size = 1; 222 | } else { 223 | throw std::invalid_argument("Invalid datatype string."); 224 | } 225 | 226 | if (dtype_str.at(0) == 'c') { 227 | sample_size *= 2; 228 | } 229 | return sample_size; 230 | } 231 | 232 | struct SigMFCaptureBoundary { 233 | uint64_t start_byte; 234 | uint64_t stop_byte; 235 | }; 236 | 237 | /** 238 | * 239 | * Returns the file byte start offset for a given captures array 240 | * 241 | * @param captures_vector SigMF captures vector 242 | * @param index specific capture to return information for 243 | * @param sample_size size of one sample in bytes 244 | */ 245 | template 246 | static SigMFCaptureBoundary get_capture_range(sigmf::SigMFVector &captures_vector, int index, int sample_size) { 247 | if (index >= captures_vector.size()) { 248 | // index exceeds captures vector length, no data to read 249 | return SigMFCaptureBoundary{0,0}; 250 | } 251 | SigMFCaptureBoundary bounds; 252 | bounds.start_byte = captures_vector[0].template get().header_bytes.value_or(0); 253 | for (auto ii = 1; ii <= index; ii++) { 254 | bounds.start_byte += captures_vector[ii].template get().header_bytes.value_or(0); 255 | } 256 | bounds.start_byte += captures_vector[index].template get().sample_start * sample_size; 257 | bounds.stop_byte = bounds.start_byte + captures_vector[index].template get().sample_start * sample_size; 258 | return bounds; 259 | } 260 | 261 | } // namespace sigmf 262 | 263 | #endif //OMNISIG_SIGMF_HELPERS_H 264 | -------------------------------------------------------------------------------- /src/variadic_data_class.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, 2021, 2022 DeepSig Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef LIBSIGMF_VARIADICDATACLASS_H 18 | #define LIBSIGMF_VARIADICDATACLASS_H 19 | 20 | #include "flatbuffers_json_visitor.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace sigmf { 27 | 28 | template 29 | struct SameType { 30 | static const bool value = false; 31 | }; 32 | 33 | template 34 | struct SameType { 35 | static const bool value = true; 36 | }; 37 | 38 | template 39 | struct ReachedEnd { 40 | static const bool value = false; 41 | }; 42 | 43 | template 44 | struct ReachedEnd { 45 | static const bool value = true; 46 | }; 47 | 48 | 49 | template 50 | class VariadicDataClass { 51 | public: 52 | /** 53 | * Access a reference to the (first) element of the tuple that is of type T 54 | * @tparam T 55 | * @return 56 | */ 57 | template 58 | T &access() { 59 | return MatchingField<0, T, sigmftypes, SigMFNamespaceOfType<0, T>::value>::get(sigmf_namespaces); 60 | } 61 | 62 | /** 63 | * Overload of access that accepts an object of type T rather than type T as template param 64 | * @tparam T 65 | * @return 66 | */ 67 | template 68 | T &access(T) { 69 | return access(); 70 | } 71 | 72 | template 73 | T &operator[](T) { 74 | return access(); 75 | } 76 | 77 | /** 78 | * return a json object representing the data class with namespaces to match sigmf-spec 79 | * @return 80 | */ 81 | json to_json() const { 82 | constexpr auto tuple_size = std::tuple_size::value; 83 | constexpr auto at_the_end = ReachedEnd<0, tuple_size>::value; 84 | json r = TupleIterator<0, sigmftypes, at_the_end>::to_json(sigmf_namespaces); 85 | return r; 86 | } 87 | 88 | /** 89 | * fill in data elements from a json object 90 | * @return 91 | */ 92 | void from_json(json j) { 93 | constexpr auto tuple_size = std::tuple_size::value; 94 | constexpr auto at_the_end = ReachedEnd<0, tuple_size>::value; 95 | TupleIterator<0, sigmftypes, at_the_end>::from_json(sigmf_namespaces, j); 96 | } 97 | 98 | private: 99 | typedef std::tuple sigmftypes; 100 | sigmftypes sigmf_namespaces; 101 | 102 | /** 103 | * Convenience class for iterating over every element in Tuple at compile time. 104 | * @tparam Index 105 | * @tparam Size 106 | * @tparam Tuple 107 | * @tparam End 108 | */ 109 | template 110 | struct TupleIterator { 111 | /** 112 | * Stringify the object's namespace (using cxxabi from compiler) so we can use the literal 113 | * c++ namespace as a prefix in the sigmf record (the sigmf namespace); this function also 114 | * removes the outer `sigmf::` class form the literal namespace 115 | * @tparam T 116 | * @param ttype 117 | * @return 118 | */ 119 | template 120 | static std::string get_namespace(const T *ttype) { 121 | // TODO: can we do this once at compile-time/ctor, store result, and just look it up? 122 | std::string mangled_name = typeid(ttype).name(); 123 | size_t size_of_demangled_name = 1024; 124 | char *demangled_name = static_cast(malloc(size_of_demangled_name)); 125 | int status; 126 | demangled_name = abi::__cxa_demangle(mangled_name.c_str(), demangled_name, &size_of_demangled_name, 127 | &status); 128 | auto demangled_string = std::string(demangled_name); 129 | free(static_cast(demangled_name)); 130 | auto ns_start = demangled_string.find("::"); 131 | auto ns_end = demangled_string.rfind("::"); 132 | auto ns_part = std::string(""); 133 | if (ns_start != std::string::npos && ns_end != std::string::npos) { 134 | ns_start += 2; 135 | ns_part = demangled_string.substr(ns_start, ns_end - ns_start + 1); 136 | } 137 | return ns_part; 138 | } 139 | 140 | /** 141 | * Iterate through the types in tuple (namespaces) creating a json object with field 142 | * names prefixed by the object's owning namespace 143 | * @param tp 144 | * @return 145 | */ 146 | static json to_json(const Tuple &tp) { 147 | typename std::tuple_element::type::TableType *ttype=nullptr; 148 | auto &flatbuffers_type = std::get(tp); 149 | auto reflection_table = ttype->MiniReflectTypeTable(); 150 | std::string namespace_part = get_namespace(ttype); 151 | 152 | flatbuffers::FlatBufferBuilder fbb; 153 | auto loc = ttype->Pack(fbb, &flatbuffers_type); 154 | fbb.Finish(loc); 155 | 156 | auto bfrptr = fbb.GetBufferPointer(); 157 | auto rtptr = flatbuffers::GetRoot(bfrptr); 158 | json asjson = FlatBufferToJson(rtptr, reflection_table, namespace_part); 159 | 160 | constexpr auto next = Index + 1; 161 | constexpr auto size = std::tuple_size::value; 162 | json existing_vals = TupleIterator::value>::to_json(tp); 163 | 164 | for (auto &val : asjson.items()) { 165 | existing_vals[val.key()] = val.value(); 166 | } 167 | return existing_vals; 168 | } 169 | 170 | /** 171 | * From json with namespaces ("core:fieldname", core is the namespace) fill in the corresponding fields 172 | * of our tuple'd objects 173 | * @param tp 174 | * @param j 175 | */ 176 | static void from_json(Tuple &tp, const json j) { 177 | typename std::tuple_element::type::TableType *ttype=nullptr; 178 | auto &flatbuffers_type = std::get(tp); 179 | auto reflection_table = ttype->MiniReflectTypeTable(); 180 | std::string namespace_part = get_namespace(ttype); 181 | 182 | FromSigMFVisitor dumb_ripoff_visitor(namespace_part, j); 183 | IterateType(reflection_table, &dumb_ripoff_visitor, j); 184 | 185 | dumb_ripoff_visitor.fbb.Finish(flatbuffers::Offset(dumb_ripoff_visitor._stop)); 186 | 187 | auto *annoptr = flatbuffers::GetRoot::type::TableType>( 188 | dumb_ripoff_visitor.fbb.GetBufferPointer()); 189 | annoptr->UnPackTo(&flatbuffers_type); 190 | 191 | constexpr auto next = Index + 1; 192 | constexpr auto size = std::tuple_size::value; 193 | TupleIterator::value>::from_json(tp, j); 194 | } 195 | }; 196 | 197 | /** 198 | * Template specialization for reaching the end of compile-time loop over Tuple 199 | * @tparam Index 200 | * @tparam Size 201 | * @tparam Tuple 202 | */ 203 | template 204 | struct TupleIterator { 205 | static json to_json(const Tuple &tp) { 206 | json r; 207 | return r; 208 | } 209 | 210 | static void from_json(const Tuple &tp, json j) { 211 | } 212 | }; 213 | 214 | /** 215 | * Convenience class for determining if the Nth element of sigmftypes is of type T. Will have bool ::value 216 | * @tparam N 217 | * @tparam T 218 | */ 219 | template 220 | struct SigMFNamespaceOfType : SameType::type> { 221 | }; 222 | 223 | /** 224 | * MatchingField::get to compile-time loop over sigmf_namespaces until the current index N is of type T 225 | * at which point it calls the end-condition (because of the template specialization) 226 | * @tparam N 227 | * @tparam T 228 | * @tparam Tuple 229 | * @tparam Match 230 | */ 231 | template 232 | struct MatchingField { 233 | static T &get(const Tuple &tp) { 234 | return MatchingField::value>::get(tp); 235 | } 236 | }; 237 | 238 | /** 239 | * MatchingField::get template-specializes the loop condition (true) to match when the object in Tuple at 240 | * index N is of type T. 241 | * @tparam N 242 | * @tparam T 243 | * @tparam Tuple 244 | */ 245 | template 246 | struct MatchingField { 247 | static T &get(const Tuple &tp) { 248 | return const_cast(std::get(tp)); 249 | } 250 | }; 251 | }; 252 | 253 | template 254 | void to_json(json &j, const VariadicDataClass t) { 255 | j = t.to_json(); 256 | } 257 | 258 | template 259 | void from_json(json &j, const VariadicDataClass t) { 260 | t.from_json(j); 261 | } 262 | 263 | } // namespace sigmf 264 | 265 | #endif 266 | --------------------------------------------------------------------------------