├── .gitignore ├── .mbedignore ├── .travis.yml ├── Gemfile ├── LICENSE ├── contributing.md ├── design_goals.md ├── doxygen ├── .gitignore ├── Doxyfile ├── DoxygenLayout.xml ├── Makefile ├── conf.py ├── footer.html ├── header.html ├── html │ └── .gitignore ├── index.rst ├── mainpage.md └── style.css ├── examples ├── chip_interface │ ├── .mbedignore │ ├── bin │ │ └── .gitignore │ ├── build │ │ └── .gitignore │ ├── interrupt_example.c │ ├── makefile │ ├── read_example.c │ ├── set_mode_example.c │ └── write_example.c ├── doxygen │ ├── .mbedignore │ ├── bin │ │ └── .gitignore │ ├── build │ │ └── .gitignore │ ├── example.c │ └── makefile ├── mbed │ ├── .gitignore │ ├── Dockerfile │ ├── bare_metal │ │ ├── .gitignore │ │ ├── lora_device_lib.lib │ │ ├── main.cpp │ │ ├── mbed-os.lib │ │ ├── mbed_app.json │ │ └── readme.md │ ├── makefile │ ├── readme.md │ ├── rtos │ │ ├── .gitignore │ │ ├── lora_device_lib.lib │ │ ├── main.cpp │ │ ├── mbed_app.json │ │ └── readme.md │ └── targets │ │ ├── bm_lrwan1.mk │ │ ├── bm_wl55.mk │ │ ├── readme.md │ │ ├── rtos_sx126x.mk │ │ ├── rtos_sx1272.mk │ │ └── rtos_wl55.mk └── ruby │ ├── Gemfile │ ├── example.rb │ └── readme.md ├── history.md ├── include ├── ldl_aes.h ├── ldl_chip.h ├── ldl_cmac.h ├── ldl_ctr.h ├── ldl_debug.h ├── ldl_frame.h ├── ldl_internal.h ├── ldl_mac.h ├── ldl_mac_commands.h ├── ldl_mac_internal.h ├── ldl_ops.h ├── ldl_platform.h ├── ldl_radio.h ├── ldl_radio_defs.h ├── ldl_region.h ├── ldl_sm.h ├── ldl_sm_internal.h ├── ldl_stream.h ├── ldl_sx126x.h ├── ldl_sx127x.h └── ldl_system.h ├── ldl.gemspec ├── mbed_lib.json ├── pclint ├── environment │ ├── .gitignore │ └── co-gcc.mak ├── makefile ├── readme.md ├── report │ └── .gitignore └── settings │ ├── au-misra3.lnt │ ├── co-gcc.h │ └── co-gcc.lnt ├── porting.md ├── rakefile ├── readme.md ├── src ├── ldl_aes.c ├── ldl_cmac.c ├── ldl_ctr.c ├── ldl_frame.c ├── ldl_mac.c ├── ldl_mac_commands.c ├── ldl_ops.c ├── ldl_radio.c ├── ldl_region.c ├── ldl_sm.c ├── ldl_stream.c ├── ldl_sx126x.c └── ldl_sx127x.c ├── test ├── bin │ └── .gitignore ├── build │ └── .gitignore ├── debug_include.h ├── makefile ├── mock_ldl_system.c ├── mock_ldl_system.h ├── tc_aes.c ├── tc_cmac.c ├── tc_dummy.c ├── tc_frame.c ├── tc_frame_with_encryption.c ├── tc_mac_commands.c └── tc_timer.c ├── todo.md ├── vendor └── cmocka │ ├── .clang_complete │ ├── .gitignore │ ├── .ycm_extra_conf.py │ ├── AUTHORS │ ├── CMakeLists.txt │ ├── COPYING │ ├── CPackConfig.cmake │ ├── CTestConfig.cmake │ ├── ChangeLog │ ├── ConfigureChecks.cmake │ ├── DefineOptions.cmake │ ├── INSTALL │ ├── NEWS │ ├── README │ ├── cmake │ └── Modules │ │ ├── AddCMockaTest.cmake │ │ ├── COPYING-CMAKE-SCRIPTS │ │ ├── CheckCCompilerFlagSSP.cmake │ │ ├── DefineCMakeDefaults.cmake │ │ ├── DefineCompilerFlags.cmake │ │ ├── DefineInstallationPaths.cmake │ │ ├── DefinePlatformDefaults.cmake │ │ ├── FindNSIS.cmake │ │ ├── MacroEnsureOutOfSourceBuild.cmake │ │ └── UseDoxygen.cmake │ ├── cmocka-build-tree-settings.cmake.in │ ├── cmocka-config-version.cmake.in │ ├── cmocka-config.cmake.in │ ├── cmocka.pc.cmake │ ├── config.h.cmake │ ├── coverity │ ├── README │ ├── coverity_assert_model.c │ └── coverity_internal_model.c │ ├── doc │ ├── CMakeLists.txt │ ├── Doxyfile.in │ ├── index.html │ └── mainpage.dox │ ├── example │ ├── CMakeLists.txt │ ├── allocate_module.c │ ├── allocate_module_test.c │ ├── assert_macro.c │ ├── assert_macro.h │ ├── assert_macro_test.c │ ├── assert_module.c │ ├── assert_module.h │ ├── assert_module_test.c │ ├── calculator.c │ ├── calculator_test.c │ ├── chef_wrap │ │ ├── CMakeLists.txt │ │ ├── chef.c │ │ ├── chef.h │ │ ├── waiter_test_wrap.c │ │ └── waiter_test_wrap.h │ ├── customer_database.c │ ├── customer_database_test.c │ ├── database.h │ ├── key_value.c │ ├── key_value.h │ ├── key_value_test.c │ ├── product_database.c │ ├── product_database_test.c │ └── simple_test.c │ ├── include │ ├── CMakeLists.txt │ ├── cmocka.h │ ├── cmocka_pbc.h │ ├── cmocka_private.h │ └── cmockery │ │ ├── cmockery.h │ │ └── pbc.h │ ├── src │ ├── CMakeLists.txt │ ├── cmocka.c │ └── cmocka.def │ ├── test_ordering_fail.c │ └── tests │ ├── CMakeLists.txt │ ├── ctest-default.cmake │ ├── test_alloc.c │ ├── test_assert_macros.c │ ├── test_assert_macros_fail.c │ ├── test_basics.c │ ├── test_cmockery.c │ ├── test_exception_handler.c │ ├── test_fixtures.c │ ├── test_group_fixtures.c │ ├── test_group_setup_assert.c │ ├── test_group_setup_fail.c │ ├── test_groups.c │ ├── test_ordering.c │ ├── test_ordering_fail.c │ ├── test_returns.c │ ├── test_returns_fail.c │ ├── test_setup_fail.c │ └── test_skip.c ├── version └── wrappers ├── mbed ├── _device.h ├── default_sm.cpp ├── default_sm.h ├── default_store.h ├── device.cpp ├── hw │ ├── cmwx1zzabz.h │ ├── nucleo_wl55jc.h │ ├── readme.md │ ├── sx126xmb2xas.h │ └── sx1272mb2xas.h ├── mac.cpp ├── mac.h ├── mbed_ldl.h ├── mbed_ldl_port.cpp ├── mbed_ldl_port.h ├── radio.cpp ├── radio.h ├── readme.md ├── sm.cpp ├── sm.h ├── spi_radio.cpp ├── spi_radio.h ├── store.h ├── sx1261.h ├── sx1262.h ├── sx126x.cpp ├── sx126x.h ├── sx1272.h ├── sx1276.h ├── sx127x.cpp ├── sx127x.h ├── wl55.cpp └── wl55.h └── ruby ├── ext └── ldl │ └── ext_ldl │ ├── ext_ldl.c │ ├── ext_ldl.h │ ├── ext_mac.c │ ├── ext_mac.h │ ├── ext_radio.c │ ├── ext_radio.h │ ├── ext_sm.c │ ├── ext_sm.h │ ├── extconf.rb │ └── platform.h ├── lib ├── ldl.rb ├── ldl │ ├── clock.rb │ ├── composite_logger.rb │ ├── device.rb │ ├── error.rb │ ├── eui.rb │ ├── frame_logger.rb │ ├── gateway.rb │ ├── key.rb │ ├── location.rb │ ├── logger_methods.rb │ ├── lora_assert.rb │ ├── lora_error.rb │ ├── mac.rb │ ├── radio.rb │ ├── radio_model.rb │ ├── scenario.rb │ ├── semtech.rb │ ├── semtech │ │ ├── message.rb │ │ ├── pull_ack.rb │ │ ├── pull_data.rb │ │ ├── pull_resp.rb │ │ ├── push_ack.rb │ │ ├── push_data.rb │ │ ├── rx_packet.rb │ │ ├── semtech_forwarder_format.md │ │ ├── status_packet.rb │ │ ├── tx_ack.rb │ │ ├── tx_packet.rb │ │ └── tx_packet_ack.rb │ └── version.rb ├── small_event.rb ├── small_event │ └── version.rb ├── timeout_queue.rb └── timeout_queue │ └── version.rb └── test ├── clock_test.rb ├── gateway_test.rb ├── pull_ack_test.rb ├── pull_data_test.rb ├── pull_resp_test.rb ├── push_ack_test.rb ├── push_data_test.rb ├── rx_packet_test.rb ├── status_packet_test.rb ├── tx_ack_test.rb ├── tx_packet_ack_test.rb └── tx_packet_test.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.map 2 | *.elf 3 | *.gem 4 | *.o 5 | *.so 6 | *.dll 7 | *.sublime* 8 | tmp/* 9 | !.gitignore 10 | Gemfile.lock 11 | .yardoc 12 | secrets 13 | */**/.git 14 | doxygen/deploy 15 | BUILD 16 | mbed-os 17 | .mbed 18 | -------------------------------------------------------------------------------- /.mbedignore: -------------------------------------------------------------------------------- 1 | doxygen/* 2 | pclint/* 3 | secrets/* 4 | test/* 5 | vendor/* 6 | wrappers/ruby/* 7 | examples/* 8 | tmp/* 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | notifications: 2 | email: false 3 | language: C 4 | sudo: required 5 | branches: 6 | only: 7 | - master 8 | script: 9 | - cd $TRAVIS_BUILD_DIR/test && make build_and_run 10 | - cd $TRAVIS_BUILD_DIR/examples/doxygen && make example 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2021 Cameron Harper 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | Contribution Guidelines 2 | ======================= 3 | 4 | ## How Can I Contribute? 5 | 6 | ### Bug Reports and Fixes 7 | 8 | Raise an issue, and if you have a fix, make a pull request. 9 | 10 | ### Documentation Improvements 11 | 12 | Raise an issue if it's complicated. 13 | 14 | Make a pull request if it's simple. 15 | 16 | ### Feature Requests and Proposals 17 | 18 | Raise an issue. 19 | 20 | ### Questions / Clarifications 21 | 22 | Raise an issue. 23 | 24 | ### Feature Contributions 25 | 26 | It is important to find out if you contribution will be accepted before 27 | you spend time implementing it. 28 | 29 | Feature contributions are likely be rejected if: 30 | 31 | - They introduce significant complexity that must be maintained to support a niche usecase 32 | - They conflict with something already in development in a local branch 33 | 34 | ## Code Style 35 | 36 | Try your best to use the same style as the rest of your project. Contributions that 37 | have a significantly different style will be nitpicked. 38 | 39 | The following patterns are encouraged: 40 | 41 | - one return per function (although this is not always possible) 42 | - one break per loop (although this is not always possible) 43 | - do not allow switch cases to fall-through 44 | - always wrap blocks in braces (e.g. if, else, while) 45 | - configure your editor to remove trailing whitespace 46 | - goto is forbidden 47 | - spaces not tabs 48 | - four space indent 49 | - don't break long lines if they are more readable unbroken 50 | 51 | ## Pull Requests 52 | 53 | Pull requests should explain what the change is and why you've made it. 54 | 55 | Commit comments should describe the change that is made. 56 | 57 | In most cases multiple commits will be squashed prior to merging using 58 | the Github squash feature. 59 | 60 | ## Licensing 61 | 62 | All contributions shall be licensed the same as LDL (i.e. [MIT License](LICENSE)). 63 | 64 | -------------------------------------------------------------------------------- /design_goals.md: -------------------------------------------------------------------------------- 1 | Design Goals 2 | ============ 3 | 4 | LDL should be simple to use and port. 5 | 6 | LDL should provide minimal interfaces that line up with words used in the 7 | specification. More sophisticated interfaces should be implemented as wrappers. 8 | 9 | LDL should not repeat itself when implementing regions. All LoRaWAN regions are based on one of two patterns; fixed or 10 | programmable channels. LDL should take advantage of the overlap. 11 | 12 | It should be possible to wrap LDL in another programming language. 13 | 14 | It should be possible to run LDL with the hardware layer replaced by software. 15 | 16 | LDL should be able to share a single thread of execution with other tasks. It should: 17 | 18 | - not block 19 | - indicate when it requires prioritisation 20 | - indicate time until the next event 21 | - calculate how late it is to handling an event 22 | - compensate for timing jitter 23 | - push events to the application asynchronously 24 | 25 | LDL should fit into an existing system, the existing system should not 26 | have to fit into LDL. 27 | -------------------------------------------------------------------------------- /doxygen/.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | html 3 | -------------------------------------------------------------------------------- /doxygen/Doxyfile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = LDL 2 | PROJECT_NUMBER = $(LDL_VERSION) 3 | BRIEF_MEMBER_DESC = NO 4 | ALWAYS_DETAILED_SEC = YES 5 | FULL_PATH_NAMES = NO 6 | OPTIMIZE_OUTPUT_FOR_C = YES 7 | SORT_MEMBER_DOCS = NO 8 | SHOW_FILES = NO 9 | INPUT = ../include mainpage.md 10 | EXAMPLE_PATH = ../ 11 | USE_MDFILE_AS_MAINPAGE = mainpage.md 12 | HTML_HEADER = header.html 13 | HTML_FOOTER = footer.html 14 | HTML_STYLESHEET = style.css 15 | SEARCHENGINE = NO 16 | GENERATE_LATEX = NO 17 | PREDEFINED = DOXYGEN 18 | CLASS_DIAGRAMS = NO 19 | HAVE_DOT = NO 20 | CLASS_GRAPH = NO 21 | COLLABORATION_GRAPH = NO 22 | GROUP_GRAPHS = NO 23 | INLINE_SIMPLE_STRUCTS = YES 24 | HIDE_UNDOC_MEMBERS = YES 25 | HIDE_UNDOC_CLASSES = YES 26 | CASE_SENSE_NAMES = NO 27 | VERBATIM_HEADERS = NO 28 | SOURCE_TOOLTIPS = NO 29 | 30 | -------------------------------------------------------------------------------- /doxygen/Makefile: -------------------------------------------------------------------------------- 1 | DIR_ROOT := ../ 2 | SPACE := 3 | SPACE += 4 | 5 | SPHINXOPTS ?= 6 | SPHINXBUILD ?= sphinx-build 7 | SOURCEDIR = . 8 | BUILDDIR = _build 9 | 10 | VERSION := $(shell cat $(DIR_ROOT)/version) 11 | UMLS := $(notdir $(wildcard *.uml)) 12 | 13 | all: clean 14 | LDL_VERSION=$(VERSION) doxygen 15 | 16 | uml: $(UMLS:.uml=.png) 17 | 18 | %.png: %.uml 19 | plantuml $< 20 | 21 | clean: 22 | rm -rf html/* 23 | rm -rf _build/* 24 | 25 | deploy: all 26 | rm -rf deploy 27 | mkdir deploy 28 | git clone git@github.com:cjhdev/lora_device_lib_api.git deploy 29 | rm -r deploy/docs/* 30 | cp -r html/* deploy/docs/ 31 | git -C deploy add -A 32 | git -C deploy commit -m "update" 33 | git -C deploy push origin master 34 | 35 | help: 36 | $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 37 | 38 | %: clean Makefile 39 | LDL_VERSION=$(VERSION) $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 40 | 41 | .PHONY: all clean deploy help Makefile 42 | -------------------------------------------------------------------------------- /doxygen/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | #from sphinx.builders.html import StandaloneHTMLBuilder 18 | import subprocess, os 19 | 20 | subprocess.call('make all', shell=True) 21 | 22 | # -- Project information ----------------------------------------------------- 23 | 24 | project = 'LDL' 25 | copyright = '2021, Cameron Harper' 26 | author = 'Cameron Harper' 27 | 28 | 29 | # -- General configuration --------------------------------------------------- 30 | 31 | # Add any Sphinx extension module names here, as strings. They can be 32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 33 | # ones. 34 | extensions = [] 35 | 36 | # Add any paths that contain templates here, relative to this directory. 37 | templates_path = ['_templates'] 38 | 39 | # List of patterns, relative to source directory, that match files and 40 | # directories to ignore when looking for source files. 41 | # This pattern also affects html_static_path and html_extra_path. 42 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 43 | 44 | highlight_language = 'C' 45 | 46 | html_extra_path = ['html'] 47 | 48 | 49 | # -- Options for HTML output ------------------------------------------------- 50 | 51 | # The theme to use for HTML and HTML Help pages. See the documentation for 52 | # a list of builtin themes. 53 | # 54 | html_theme = 'sphinx_rtd_theme' 55 | 56 | # Add any paths that contain custom static files (such as style sheets) here, 57 | # relative to this directory. They are copied after the builtin static files, 58 | # so a file named "default.css" will overwrite the builtin "default.css". 59 | html_static_path = [] 60 | 61 | -------------------------------------------------------------------------------- /doxygen/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /doxygen/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | $projectname: $title 9 | $title 10 | 11 | $treeview 12 | $search 13 | $mathjax 14 | 15 | $extrastylesheet 16 | 17 | 18 |
19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
29 |
$projectname 30 |  $projectnumber 31 |
32 |
$projectbrief
33 |
38 |
$projectbrief
39 |
49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /doxygen/html/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /doxygen/index.rst: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /doxygen/mainpage.md: -------------------------------------------------------------------------------- 1 | LDL Interface Documentation 2 | =========================== 3 | 4 | Interface documentation for LDL. 5 | 6 | ## Interface Groups 7 | 8 | - [MAC](@ref ldl_mac) 9 | - [Radio Driver](@ref ldl_radio) 10 | - [Chip Interface](@ref ldl_chip_interface) 11 | - [Security Module](@ref ldl_tsm) 12 | - [Default Cryptography](@ref ldl_crypto) 13 | - [Build Options](@ref ldl_build_options) 14 | - [System](@ref ldl_system) 15 | 16 | ## Useful Links 17 | 18 | - [**project repository**](https://github.com/cjhdev/lora_device_lib) 19 | - [**issue tracker**](https://github.com/cjhdev/lora_device_lib/issues) 20 | 21 | ## Example 22 | 23 | Below is an example of how to use the interfaces to activate a device 24 | and send data. 25 | 26 | Functions marked as "extern" have not been implemented for brevity. 27 | 28 | This example would need the following @ref ldl_build_options to be defined: 29 | 30 | - #LDL_ENABLE_SX1272 31 | - #LDL_ENABLE_EU_863_870 32 | 33 | @include examples/doxygen/example.c 34 | -------------------------------------------------------------------------------- /examples/chip_interface/.mbedignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /examples/chip_interface/bin/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /examples/chip_interface/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /examples/chip_interface/interrupt_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | LDL must be connected to the rising edge of some interrupt lines. 4 | 5 | On SX127X this is DIO0 and DIO1. 6 | 7 | On SX126X this is DIO1. 8 | 9 | */ 10 | 11 | 12 | void dio0_rising_edge_isr(void) 13 | { 14 | LDL_Radio_handleInterrupt(&radio, 0); 15 | } 16 | 17 | void dio1_rising_edge_isr(void) 18 | { 19 | LDL_Radio_handleInterrupt(&radio, 1); 20 | } -------------------------------------------------------------------------------- /examples/chip_interface/makefile: -------------------------------------------------------------------------------- 1 | DIR_ROOT := ../.. 2 | 3 | DIR_BUILD := build 4 | DIR_BIN := bin 5 | 6 | SRC := read_example.c write_example.c set_mode_example.c 7 | OBJ := $(SRC:.c=.o) 8 | 9 | VPATH += . 10 | VPATH += $(DIR_ROOT)/src 11 | 12 | INCLUDES += -I. 13 | INCLUDES += -I$(DIR_ROOT)/include 14 | 15 | CFLAGS += $(INCLUDES) 16 | 17 | CLFAGS += -Wall 18 | 19 | example: $(addprefix $(DIR_BUILD)/, $(OBJ)) 20 | # $(CC) $(CFLAGS) $^ -o $@ 21 | 22 | $(DIR_BUILD)/%.o: %.c 23 | $(CC) $(CFLAGS) -c $< -o $@ 24 | 25 | clean: 26 | @ echo cleaning up objects 27 | @ rm -f $(DIR_BUILD)/* 28 | 29 | .PHONY: example 30 | -------------------------------------------------------------------------------- /examples/chip_interface/read_example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern void spi_chip_select(void); 6 | extern void spi_chip_release(void); 7 | extern void spi_write(uint8_t byte); 8 | extern uint8_t spi_read(void); 9 | extern bool read_busy_pin(void); 10 | 11 | bool LDL_Chip_read(void *self, const void *opcode, size_t opcode_size, void *data, size_t size) 12 | { 13 | /* unused in this example */ 14 | (void)self; 15 | 16 | size_t i; 17 | 18 | spi_chip_select(); 19 | { 20 | /* required for the SX126X series but not the SX127X series 21 | * 22 | * This must occur after selecting the chip since NSS is 23 | * used to wake from sleep, during which busy pin will be set. 24 | * 25 | * consider adding a timeout to recover from a faulty chip */ 26 | while(read_busy_pin()); 27 | 28 | for(i=0U; i < opcode_size; i++){ 29 | 30 | spi_write(((const uint8_t *)opcode)[i]); 31 | } 32 | 33 | for(i=0U; i < size; i++){ 34 | 35 | ((uint8_t *)data)[i] = spi_read(); 36 | } 37 | } 38 | spi_chip_release(); 39 | 40 | /* this would return false if there was a busy timeout */ 41 | return true; 42 | } 43 | -------------------------------------------------------------------------------- /examples/chip_interface/set_mode_example.c: -------------------------------------------------------------------------------- 1 | #include "ldl_chip.h" 2 | 3 | /* this example is for an SX1276 */ 4 | 5 | void LDL_Chip_reset(bool state) 6 | { 7 | if(state){ 8 | 9 | // drive high 10 | } 11 | else{ 12 | 13 | // hiz 14 | } 15 | } 16 | 17 | /* On more sophisticated hardware you may also need to switch: 18 | * 19 | * - on/off an oscillator 20 | * - rfi circuit 21 | * - rfo circuit 22 | * - boost circuit 23 | * 24 | * */ 25 | void LDL_Chip_setMode(void *self, enum ldl_chip_mode mode) 26 | { 27 | switch(mode){ 28 | case LDL_CHIP_MODE_RESET: 29 | LDL_Chip_reset(true); 30 | break; 31 | case LDL_CHIP_MODE_SLEEP: 32 | LDL_Chip_reset(false); 33 | break; 34 | case LDL_CHIP_MODE_STANDBY: 35 | break; 36 | case LDL_CHIP_MODE_RX: 37 | break; 38 | case LDL_CHIP_MODE_TX_BOOST: 39 | break; 40 | case LDL_CHIP_MODE_TX_RFO: 41 | break; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /examples/chip_interface/write_example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern void spi_chip_select(void); 6 | extern void spi_chip_release(void); 7 | extern void spi_write(uint8_t byte); 8 | extern bool read_busy_pin(void); 9 | 10 | bool LDL_Chip_write(void *self, const void *opcode, size_t opcode_size, const void *data, size_t size) 11 | { 12 | /* unused in this example */ 13 | (void)self; 14 | 15 | size_t i; 16 | 17 | spi_chip_select(); 18 | { 19 | /* required for the SX126X series but not the SX127X series 20 | * 21 | * This must occur after selecting the chip since NSS is 22 | * used to wake from sleep, during which busy pin will be set. 23 | * 24 | * consider adding a timeout to recover from a faulty chip */ 25 | while(read_busy_pin()); 26 | 27 | for(i=0U; i < opcode_size; i++){ 28 | 29 | spi_write(((const uint8_t *)opcode)[i]); 30 | } 31 | 32 | for(i=0U; i < size; i++){ 33 | 34 | spi_write(((const uint8_t *)data)[i]); 35 | } 36 | } 37 | spi_chip_release(); 38 | 39 | /* this would return false if there was a busy timeout */ 40 | return true; 41 | } 42 | -------------------------------------------------------------------------------- /examples/doxygen/.mbedignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /examples/doxygen/bin/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /examples/doxygen/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /examples/doxygen/makefile: -------------------------------------------------------------------------------- 1 | DIR_ROOT := ../.. 2 | 3 | DIR_BUILD := build 4 | DIR_BIN := bin 5 | 6 | SRC := $(notdir $(wildcard $(DIR_ROOT)/src/*.c)) example.c 7 | OBJ := $(SRC:.c=.o) 8 | 9 | VPATH += . 10 | VPATH += $(DIR_ROOT)/src 11 | 12 | INCLUDES += -I. 13 | INCLUDES += -I$(DIR_ROOT)/include 14 | 15 | CFLAGS += $(INCLUDES) 16 | 17 | CFLAGS += -DLDL_ENABLE_SX1272 18 | CFLAGS += -DLDL_ENABLE_SX1276 19 | CFLAGS += -DLDL_ENABLE_EU_863_870 20 | 21 | CLFAGS += -Wall 22 | 23 | example: $(addprefix $(DIR_BUILD)/, $(OBJ)) 24 | # $(CC) $(CFLAGS) $^ -o $@ 25 | 26 | $(DIR_BUILD)/%.o: %.c 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | clean: 30 | @ echo cleaning up objects 31 | @ rm -f $(DIR_BUILD)/* 32 | 33 | .PHONY: example 34 | -------------------------------------------------------------------------------- /examples/mbed/.gitignore: -------------------------------------------------------------------------------- 1 | mbed-os 2 | upload_flash.jlink 3 | .gdbinit 4 | -------------------------------------------------------------------------------- /examples/mbed/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:9 2 | 3 | # the latest mbed requirements 4 | ARG mbed_requirements_url=https://raw.githubusercontent.com/ARMmbed/mbed-os/master/requirements.txt 5 | 6 | RUN dpkg --add-architecture i386 \ 7 | && DEBIAN_FRONTEND=noninteractive apt-get update -y -q \ 8 | && DEBIAN_FRONTEND=noninteractive apt-get upgrade -y -q \ 9 | && DEBIAN_FRONTEND=noninteractive apt-get install -y -q \ 10 | python python-pip \ 11 | git mercurial \ 12 | wget \ 13 | && pip install mbed-cli \ 14 | && wget -O /tmp/mbed-cli-requirements.txt $mbed_requirements_url \ 15 | && pip install -r /tmp/mbed-cli-requirements.txt 16 | 17 | ARG toolchain_name=gcc-arm-none-eabi-9-2020-q2-update 18 | ARG toolchain_url=https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2?revision=05382cca-1721-44e1-ae19-1e7c3dc96118&la=en&hash=D7C9D18FCA2DD9F894FD9F3C3DC9228498FA281A 19 | 20 | # get the toolchain 21 | RUN cd /opt && wget $toolchain_url -O - | tar xj 22 | 23 | ENV GCC_ARM_PATH="/opt/$toolchain_name/bin" 24 | ENV PATH="/opt/$toolchain_name/bin:${PATH}" 25 | 26 | # this doesn't seem to work 27 | #RUN mbed config --global toolchain GCC_ARM 28 | 29 | WORKDIR /mbed 30 | VOLUME /mbed 31 | 32 | ENTRYPOINT [ "mbed" ] 33 | -------------------------------------------------------------------------------- /examples/mbed/bare_metal/.gitignore: -------------------------------------------------------------------------------- 1 | BUILD 2 | mbed-os 3 | lora_device_lib 4 | .mbed 5 | upload_flash.jlink 6 | .gdbinit 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/mbed/bare_metal/lora_device_lib.lib: -------------------------------------------------------------------------------- 1 | https://github.com/cjhdev/lora_device_lib 2 | -------------------------------------------------------------------------------- /examples/mbed/bare_metal/mbed-os.lib: -------------------------------------------------------------------------------- 1 | https://github.com/ARMmbed/mbed-os 2 | -------------------------------------------------------------------------------- /examples/mbed/bare_metal/mbed_app.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": ["bare-metal", "ldl", "mbed-trace"], 3 | "config" : { 4 | 5 | "app_key" : { 6 | "value" : "{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}" 7 | }, 8 | "nwk_key" : { 9 | "value" : "{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}" 10 | }, 11 | "join_eui" : { 12 | "value" : "{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}" 13 | }, 14 | "dev_eui" : { 15 | "value" : "{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}" 16 | } 17 | }, 18 | "target_overrides": { 19 | "*": { 20 | "platform.stdio-baud-rate": 115200, 21 | "platform.default-serial-baud-rate": 115200, 22 | "target.c_lib": "small", 23 | "mbed-trace.enable": 1, 24 | "mbed-trace.max-level" : "TRACE_LEVEL_DEBUG", 25 | "ldl.enable-verbose-debug" : null, 26 | "ldl.enable-radio-debug" : null 27 | }, 28 | "DISCO_L072CZ_LRWAN1" : { 29 | 30 | "ldl.disable-sf12" : null 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/mbed/bare_metal/readme.md: -------------------------------------------------------------------------------- 1 | LDL MBED Wrapper in Bare Metal Profile 2 | ====================================== 3 | 4 | This example runs shows how to run LDL::MAC on MBED with the bare metal 5 | profile. 6 | 7 | ## Changing the Region 8 | 9 | Region is specified as argument to LDL::Device.start(). 10 | 11 | ## Deep Sleep 12 | 13 | Note that MBED will only drop into deep sleep for the "release" profile. 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/mbed/readme.md: -------------------------------------------------------------------------------- 1 | MBED Examples 2 | ============= 3 | 4 | There are two example applications; one for bare-metal, one for RTOS. 5 | These examples should compile for more targets and radios than I have 6 | access to or an interest in testing. 7 | 8 | The target can be changed as per any MBED project. The radio can be 9 | changed by redefining RADIO macro, or leaving it undefined and uncommenting 10 | the one you want in the source. It's setup so that I can easily check 11 | different permutations of targets and radios. 12 | If you don't want to use default radio hardware then you may need to 13 | hack up the source a little. 14 | 15 | The bare metal profile is essential for targets with less than 20K of RAM. 16 | 17 | The rtos profile is preferable if you have enough RAM since the 18 | blocking interfaces simplify applications and preemtive scheduling 19 | reduces the chance you will miss downlinks. 20 | 21 | There are two ways to compile the examples. 22 | 23 | ## Import as MBED App Using Preferred Tools 24 | 25 | Treat each app as standalone and follow the usual instructions 26 | for importing these into your preferred environment. Define RADIO or 27 | uncomment the definition in source. 28 | 29 | ## Compile in Place using Docker 30 | 31 | Docker is used to: 32 | 33 | - hold mbed-cli and a toolchain 34 | - mount different parts of the project repository where mbed-cli expects them 35 | 36 | This is the method used to maintain the wrapper and examples. 37 | The makefile in this directory can be used to setup the container and build 38 | the examples. 39 | 40 | ### Checkout mbed-os 41 | 42 | ``` 43 | make get_mbed 44 | ``` 45 | 46 | ### Build a Container 47 | 48 | ``` 49 | make build_container 50 | ``` 51 | 52 | You can check it works: 53 | 54 | ``` 55 | make test_container 56 | ``` 57 | 58 | ### Compile 59 | 60 | Compile for with predefined settings referenced by APP variable. This 61 | should be the basename of a file in [targets](targets) directory. 62 | 63 | e.g. 64 | 65 | ``` 66 | make compile APP=rtos_wl55 67 | ``` 68 | ``` 69 | make compile APP=bm_wl55 70 | ``` 71 | ``` 72 | make compile APP=bm_lrwan1 73 | ``` 74 | 75 | ### Clean 76 | 77 | ``` 78 | make clean APP=bare_metal 79 | ``` 80 | 81 | ### Flash 82 | 83 | ``` 84 | make flash APP=rtos_wl55 85 | ``` 86 | Define APP same as you would with compile. 87 | 88 | ### GDB 89 | 90 | ``` 91 | make gdb APP=rtos_wl55 92 | ``` 93 | Define APP same as you would with compile. 94 | 95 | ### GDB Server 96 | 97 | ``` 98 | make gdb_server APP=rtos_wl55 99 | ``` 100 | Define APP same as you would with compile. 101 | 102 | 103 | -------------------------------------------------------------------------------- /examples/mbed/rtos/.gitignore: -------------------------------------------------------------------------------- 1 | BUILD 2 | mbed-os 3 | lora_device_lib 4 | .mbed 5 | upload_flash.jlink 6 | .gdbinit 7 | -------------------------------------------------------------------------------- /examples/mbed/rtos/lora_device_lib.lib: -------------------------------------------------------------------------------- 1 | https://github.com/cjhdev/lora_device_lib 2 | -------------------------------------------------------------------------------- /examples/mbed/rtos/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mbed_ldl.h" 2 | 3 | #include "hw/sx1272mb2xas.h" 4 | #include "hw/sx126xmb2xas.h" 5 | #include "hw/nucleo_wl55jc.h" 6 | 7 | const uint8_t app_key[] = MBED_CONF_APP_APP_KEY; 8 | const uint8_t nwk_key[] = MBED_CONF_APP_NWK_KEY; 9 | const uint8_t dev_eui[] = MBED_CONF_APP_DEV_EUI; 10 | const uint8_t join_eui[] = MBED_CONF_APP_JOIN_EUI; 11 | 12 | void handle_rx(uint8_t port, const void *data, uint8_t size) 13 | { 14 | } 15 | 16 | void handle_link_status(uint8_t margin, uint8_t gwcount) 17 | { 18 | } 19 | 20 | void handle_device_time(uint32_t seconds, uint8_t fractions) 21 | { 22 | } 23 | 24 | int main() 25 | { 26 | uint32_t entropy; 27 | const char msg[] = "hello world"; 28 | 29 | mbed_trace_init(); 30 | 31 | #ifndef RADIO 32 | //#define RADIO LDL::HW::SX1272MB2XAS 33 | //#define RADIO LDL::HW::SX126XMB2XAS 34 | #define RADIO LDL::HW::NucleoWL55JC 35 | #endif 36 | 37 | static RADIO radio; 38 | 39 | static LDL::DefaultSM sm(app_key, nwk_key); 40 | static LDL::DefaultStore store(dev_eui, join_eui); 41 | static LDL::Device device(store, sm, radio); 42 | 43 | device.set_rx_cb(callback(handle_rx)); 44 | device.set_link_status_cb(callback(handle_link_status)); 45 | device.set_device_time_cb(callback(handle_device_time)); 46 | 47 | device.start(LDL_EU_863_870); 48 | 49 | if(device.entropy(entropy) == LDL_STATUS_OK){ 50 | 51 | srand(entropy); 52 | } 53 | 54 | device.otaa(); 55 | 56 | for(;;){ 57 | 58 | device.unconfirmed(1, msg, strlen(msg)); 59 | 60 | ThisThread::sleep_for(10s); 61 | } 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /examples/mbed/rtos/mbed_app.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "config" : { 4 | 5 | "app_key" : { 6 | "value" : "{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}" 7 | }, 8 | "nwk_key" : { 9 | "value" : "{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01}" 10 | }, 11 | "join_eui" : { 12 | "value" : "{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02}" 13 | }, 14 | "dev_eui" : { 15 | "value" : "{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03}" 16 | } 17 | }, 18 | "target_overrides": { 19 | "*": { 20 | "platform.stdio-baud-rate": 115200, 21 | "platform.default-serial-baud-rate": 115200, 22 | "mbed-trace.enable": 1, 23 | "mbed-trace.max-level" : "TRACE_LEVEL_DEBUG", 24 | "ldl.enable-verbose-debug" : null, 25 | "ldl.enable-radio-debug" : null 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/mbed/rtos/readme.md: -------------------------------------------------------------------------------- 1 | LDL MBED Wrapper in RTOS Profile 2 | ================================ 3 | 4 | This example runs shows how to run LDL::Device on MBED with the RTOS 5 | profile. 6 | 7 | This will probably only work on targets with >20K of RAM. 8 | 9 | ## Changing the Region 10 | 11 | Region is specified as argument to LDL::Device.start(). 12 | 13 | ## Deep Sleep 14 | 15 | Note that MBED will only drop into deep sleep for the "release" profile. 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/mbed/targets/bm_lrwan1.mk: -------------------------------------------------------------------------------- 1 | DEVICE := DISCO_L072CZ_LRWAN1 2 | JLINK_DEVICE := STM32L072CZ 3 | RADIO := LDL::HW::CMWX1ZZABZ 4 | 5 | DIR_APP := $(shell pwd)/bare_metal 6 | -------------------------------------------------------------------------------- /examples/mbed/targets/bm_wl55.mk: -------------------------------------------------------------------------------- 1 | DEVICE := NUCLEO_WL55JC 2 | JLINK_DEVICE := STM32WL55JC 3 | RADIO := LDL::HW::NucleoWL55JC 4 | 5 | DIR_APP := $(shell pwd)/bare_metal 6 | -------------------------------------------------------------------------------- /examples/mbed/targets/readme.md: -------------------------------------------------------------------------------- 1 | What is this? 2 | ============= 3 | 4 | These are makefiles that I include via the TARGET variable in the main 5 | mbed makefile. 6 | -------------------------------------------------------------------------------- /examples/mbed/targets/rtos_sx126x.mk: -------------------------------------------------------------------------------- 1 | DEVICE := NUCLEO_F429ZI 2 | JLINK_DEVICE := STM32F429ZI 3 | RADIO := LDL::HW::SX126XMB2XAS 4 | 5 | DIR_APP := $(shell pwd)/rtos 6 | -------------------------------------------------------------------------------- /examples/mbed/targets/rtos_sx1272.mk: -------------------------------------------------------------------------------- 1 | DEVICE := NUCLEO_F429ZI 2 | JLINK_DEVICE := STM32F429ZI 3 | RADIO := LDL::HW::SX1272MB2XAS 4 | 5 | DIR_APP := $(shell pwd)/rtos 6 | -------------------------------------------------------------------------------- /examples/mbed/targets/rtos_wl55.mk: -------------------------------------------------------------------------------- 1 | DEVICE := NUCLEO_WL55JC 2 | JLINK_DEVICE := STM32WL55JC 3 | RADIO := LDL::HW::NucleoWL55JC 4 | 5 | DIR_APP := $(shell pwd)/rtos 6 | -------------------------------------------------------------------------------- /examples/ruby/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'ldl', path: "../.." 4 | -------------------------------------------------------------------------------- /examples/ruby/example.rb: -------------------------------------------------------------------------------- 1 | require 'ldl' 2 | require 'securerandom' 3 | 4 | include LDL 5 | 6 | logger = Logger.new(STDOUT) 7 | logger.formatter = LDL::LOG_FORMATTER 8 | 9 | opts = { 10 | logger: logger, 11 | dev_eui: [0,0,0,0,0,0,0,3].pack("C*"), 12 | join_eui: SecureRandom.bytes(8), 13 | nwk_key: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1].pack("C*"), 14 | gw_eui: [0,0,0,0,0,0,0,1].pack("C*"), 15 | host: 'localhost', 16 | port: 1700, 17 | otaa_dither: 0 18 | } 19 | 20 | Scenario.run(**opts) do |scenario| 21 | 22 | puts scenario.device.entropy 23 | 24 | scenario.device.otaa 25 | 26 | scenario.device.unconfirmed "hello world" 27 | 28 | scenario.device.confirmed "hello world" 29 | 30 | end 31 | -------------------------------------------------------------------------------- /examples/ruby/readme.md: -------------------------------------------------------------------------------- 1 | An example of how to use the Ruby wrapper. 2 | -------------------------------------------------------------------------------- /include/ldl_aes.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2019-2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef LDL_AES_H 23 | #define LDL_AES_H 24 | 25 | /** @file */ 26 | 27 | /** 28 | * @defgroup ldl_crypto Default Cryptography 29 | * 30 | * The implementations for these interfaces are used by the default 31 | * @ref ldl_tsm. They are documented here to assist integrators that 32 | * choose to reimplement @ref ldl_tsm. 33 | * 34 | * These implementations are provided for the purpose of evaluating LDL 35 | * and no effort has been made to ensure they are hardened against 36 | * attacks. 37 | * 38 | * @{ 39 | * */ 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | #include 46 | 47 | /** AES state */ 48 | struct ldl_aes_ctx { 49 | 50 | uint8_t k[240U]; 51 | uint8_t r; 52 | }; 53 | 54 | /** Initialise AES block cipher 55 | * 56 | * @param[in] ctx 57 | * @param[in] key pointer to 16 byte key 58 | * 59 | * */ 60 | void LDL_AES_init(struct ldl_aes_ctx *ctx, const void *key); 61 | 62 | /** Encrypt a block of data 63 | * 64 | * @param[in] ctx state previously initialised by LDL_AES_init() 65 | * @param[in] s pointer to 16 byte block of data (any alignment) 66 | * 67 | * */ 68 | void LDL_AES_encrypt(const struct ldl_aes_ctx *ctx, void *s); 69 | 70 | /** Decrypt a block of data 71 | * 72 | * @param[in] ctx state previously initialised by LDL_AES_init() 73 | * @param[in] s pointer to 16 byte block of data (any alignment) 74 | * 75 | * */ 76 | void LDL_AES_decrypt(const struct ldl_aes_ctx *ctx, void *s); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | /** @} */ 83 | #endif 84 | -------------------------------------------------------------------------------- /include/ldl_cmac.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2019-2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef LDL_CMAC_H 23 | #define LDL_CMAC_H 24 | 25 | /** @file */ 26 | 27 | /** 28 | * @addtogroup ldl_crypto 29 | * 30 | * @{ 31 | * */ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | #include 39 | 40 | struct ldl_aes_ctx; 41 | 42 | /** CMAC state */ 43 | struct ldl_cmac_ctx { 44 | 45 | const struct ldl_aes_ctx *aes_ctx; 46 | uint8_t m[16U]; 47 | uint8_t x[16U]; 48 | uint8_t size; 49 | }; 50 | 51 | /** Initialise CMAC state 52 | * 53 | * @param[in] ctx 54 | * @param[in] aes_ctx block cipher state 55 | * 56 | * */ 57 | void LDL_CMAC_init(struct ldl_cmac_ctx *ctx, const struct ldl_aes_ctx *aes_ctx); 58 | 59 | /** Update CMAC state 60 | * 61 | * @param[in] ctx 62 | * @param[in] data 63 | * @param[in] len 64 | * 65 | * */ 66 | void LDL_CMAC_update(struct ldl_cmac_ctx *ctx, const void *data, uint8_t len); 67 | 68 | /** Produce CMAC output from current state 69 | * 70 | * @param[in] ctx 71 | * @param[out] out 72 | * @param[in] outMax 73 | * 74 | * */ 75 | void LDL_CMAC_finish(const struct ldl_cmac_ctx *ctx, void *out, uint8_t outMax); 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | /** @} */ 82 | #endif 83 | -------------------------------------------------------------------------------- /include/ldl_ctr.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2019-2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef LDL_CTR_H 23 | #define LDL_CTR_H 24 | 25 | /** @file */ 26 | 27 | /** 28 | * @addtogroup ldl_crypto 29 | * 30 | * @{ 31 | * */ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #include 38 | 39 | struct ldl_aes_ctx; 40 | 41 | /** Counter mode encryption 42 | * 43 | * @param[in] ctx #ldl_aes_ctx 44 | * @param[in] iv 16 byte initial value 45 | * @param[in] in input buffer to encrypt 46 | * @param[out] out output buffer (can be same as in) 47 | * @param[in] len size of input 48 | * 49 | * */ 50 | void LDL_CTR_encrypt(struct ldl_aes_ctx *ctx, const void *iv, const void *in, void *out, uint8_t len); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | /** @} */ 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /include/ldl_internal.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef LDL_INTERNAL_H 23 | #define LDL_INTERNAL_H 24 | 25 | #include 26 | 27 | #include "ldl_platform.h" 28 | 29 | /* these macros are used to cast literals to a specific width 30 | * 31 | * It's pedantic but PCLINT in MISRA 2012 mode complains a lot about widths 32 | * 33 | * */ 34 | #define U64(X) ((uint64_t)(X)) 35 | #define U32(X) ((uint32_t)(X)) 36 | #define U16(X) ((uint16_t)(X)) 37 | #define S16(X) ((int16_t)(X)) 38 | #define U8(X) ((uint8_t)(X)) 39 | 40 | #if defined(LDL_ENABLE_L2_1_1) 41 | #define SESS_VERSION(sess) sess.version 42 | #else 43 | #define SESS_VERSION(sess) (0U) 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /include/ldl_mac_internal.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2021 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef LDL_MAC_INTERNAL_H 23 | #define LDL_MAC_INTERNAL_H 24 | 25 | #include "ldl_platform.h" 26 | #include 27 | #include 28 | 29 | struct ldl_mac; 30 | 31 | enum ldl_timer_inst { 32 | 33 | LDL_TIMER_WAITA, /* general use + RX1 slot timing */ 34 | LDL_TIMER_WAITB, /* RX2 slot timing */ 35 | LDL_TIMER_BAND, /* tracks time used to decrement down counters */ 36 | #ifdef LDL_ENABLE_CLASS_B 37 | LDL_TIMER_BEACON, /* beacon tracking */ 38 | #endif 39 | LDL_TIMER_MAX 40 | }; 41 | 42 | 43 | bool LDL_MAC_addChannel(struct ldl_mac *self, uint8_t chIndex, uint32_t freq, uint8_t minRate, uint8_t maxRate); 44 | void LDL_MAC_removeChannel(struct ldl_mac *self, uint8_t chIndex); 45 | bool LDL_MAC_maskChannel(struct ldl_mac *self, uint8_t chIndex); 46 | bool LDL_MAC_unmaskChannel(struct ldl_mac *self, uint8_t chIndex); 47 | 48 | void LDL_MAC_timerSet(struct ldl_mac *self, enum ldl_timer_inst timer, uint32_t timeout); 49 | void LDL_MAC_timerAppend(struct ldl_mac *self, enum ldl_timer_inst timer, uint32_t timeout); 50 | bool LDL_MAC_timerCheck(struct ldl_mac *self, enum ldl_timer_inst timer, uint32_t *lag); 51 | uint32_t LDL_MAC_timerTicksSince(struct ldl_mac *self, enum ldl_timer_inst timer); 52 | void LDL_MAC_timerClear(struct ldl_mac *self, enum ldl_timer_inst timer); 53 | uint32_t LDL_MAC_timerTicksUntilNext(const struct ldl_mac *self); 54 | uint32_t LDL_MAC_timerTicksUntil(const struct ldl_mac *self, enum ldl_timer_inst timer, uint32_t *lag); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /include/ldl_ops.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2019-2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef LDL_OPS_H 23 | #define LDL_OPS_H 24 | 25 | /* "operations" 26 | * 27 | * For lack of a better name, this connects the mac to the security module 28 | * and frame codec. 29 | * 30 | * It also provides some handy interfaces for testing that the MIC 31 | * and encryption works as expected. 32 | * 33 | * For our sanity these functions depend on state in ldl_mac but 34 | * they should never change it directly. 35 | * 36 | * */ 37 | 38 | #include 39 | #include 40 | 41 | struct ldl_mac; 42 | struct ldl_frame_data; 43 | struct ldl_frame_down; 44 | struct ldl_frame_join_request; 45 | struct ldl_system_identity; 46 | 47 | /* derive all session keys and write to ldl_sm */ 48 | void LDL_OPS_deriveKeys(struct ldl_mac *self); 49 | void LDL_OPS_deriveJoinKeys(struct ldl_mac *self); 50 | 51 | /* decode and verify a frame (depends on ldl_mac state but does not modify directly) */ 52 | bool LDL_OPS_receiveFrame(struct ldl_mac *self, struct ldl_frame_down *f, uint8_t *in, uint8_t len); 53 | 54 | /* encode a frame (depends on ldl_mac state but does not modify directly) */ 55 | uint8_t LDL_OPS_prepareData(struct ldl_mac *self, const struct ldl_frame_data *f, uint8_t *out, uint8_t max); 56 | uint8_t LDL_OPS_prepareJoinRequest(struct ldl_mac *self, const struct ldl_frame_join_request *f, uint8_t *out, uint8_t max); 57 | 58 | /* apply MIC to a data frame */ 59 | void LDL_OPS_micDataFrame(struct ldl_mac *self, void *buffer, uint8_t size); 60 | 61 | /* derive expected 32 bit downcounter from 16 least significant bits and update the copy in ldl_mac */ 62 | void LDL_OPS_syncDownCounter(struct ldl_mac *self, uint8_t port, uint16_t counter); 63 | 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /include/ldl_radio_defs.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2019-2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef LDL_RADIO_DEFS_H 23 | #define LDL_RADIO_DEFS_H 24 | 25 | /** @file */ 26 | 27 | /** 28 | * @addtogroup ldl_radio 29 | * 30 | * @{ 31 | * 32 | * */ 33 | 34 | /** Spreading Factor */ 35 | enum ldl_spreading_factor { 36 | LDL_SF_7 = 7, /**< 128 chips/symbol */ 37 | LDL_SF_8, /**< 256 chips/symbol */ 38 | LDL_SF_9, /**< 512 chips/symbol */ 39 | LDL_SF_10, /**< 1024 chips/symbol */ 40 | LDL_SF_11, /**< 2048 chips/symbol */ 41 | LDL_SF_12, /**< 4096 chips/symbol */ 42 | }; 43 | 44 | /** signal bandwidth */ 45 | enum ldl_signal_bandwidth { 46 | LDL_BW_125 = 0, /**< 125 KHz */ 47 | LDL_BW_250, /**< 250 KHz */ 48 | LDL_BW_500, /**< 500 KHz */ 49 | }; 50 | 51 | enum ldl_coding_rate { 52 | LDL_CR_5 = 1, 53 | LDL_CR_6, 54 | LDL_CR_7, 55 | LDL_CR_8, 56 | }; 57 | 58 | /** @} */ 59 | #endif 60 | -------------------------------------------------------------------------------- /include/ldl_sm.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2019-2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef LDL_SM_H 23 | #define LDL_SM_H 24 | 25 | /** @file */ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /**@addtogroup ldl_tsm 32 | * @{ 33 | * */ 34 | 35 | #include "ldl_platform.h" 36 | #include "ldl_sm_internal.h" 37 | 38 | #include 39 | 40 | #define LDL_KEY_SIZE 16U 41 | 42 | struct ldl_key { 43 | 44 | uint8_t value[LDL_KEY_SIZE]; 45 | }; 46 | 47 | /** default in-memory security module state */ 48 | struct ldl_sm { 49 | #if defined(LDL_ENABLE_L2_1_1) 50 | struct ldl_key keys[8U]; 51 | #else 52 | struct ldl_key keys[3U]; 53 | #endif 54 | }; 55 | 56 | #if defined(LDL_ENABLE_L2_1_1) 57 | /** 58 | * Initialise Default Security Module with root keys 59 | * 60 | * @param[in] self #ldl_sm 61 | * @param[in] appKey pointer to 16 byte field 62 | * @param[in] nwkKey pointer to 16 byte field 63 | * 64 | * */ 65 | void LDL_SM_init(struct ldl_sm *self, const void *appKey, const void *nwkKey); 66 | #else 67 | /** 68 | * Initialise Default Security Module with root key 69 | * 70 | * @param[in] self #ldl_sm 71 | * @param[in] appKey pointer to 16 byte field 72 | * 73 | * */ 74 | void LDL_SM_init(struct ldl_sm *self, const void *appKey); 75 | #endif 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | /** @} */ 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /ldl.gemspec: -------------------------------------------------------------------------------- 1 | require File.expand_path("../wrappers/ruby/lib/ldl/version.rb", __FILE__) 2 | require 'time' 3 | 4 | Gem::Specification.new do |s| 5 | 6 | s.name = "ldl" 7 | s.version = LDL::VERSION 8 | s.date = Date.today.to_s 9 | s.summary = "A ruby wrapper for ldl" 10 | s.author = "Cameron Harper" 11 | s.email = "contact@cjh.id.au" 12 | 13 | s.files = Dir.glob("src/**/*.c") 14 | s.files += Dir.glob("src/**/*.h") 15 | s.files += Dir.glob("wrappers/ruby/ext/**/*.{c,h,rb}") 16 | s.files += Dir.glob("wrappers/ruby/lib/**/*.rb") 17 | 18 | s.extensions = ["wrappers/ruby/ext/ldl/ext_ldl/extconf.rb"] 19 | 20 | s.license = 'MIT' 21 | 22 | s.add_development_dependency 'rake-compiler' 23 | s.add_development_dependency 'rake' 24 | s.add_development_dependency 'minitest' 25 | s.add_runtime_dependency 'pry' 26 | 27 | s.required_ruby_version = '>= 2.0' 28 | 29 | s.require_paths += ['wrappers/ruby/lib'] 30 | 31 | end 32 | -------------------------------------------------------------------------------- /pclint/environment/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !*.mak 4 | -------------------------------------------------------------------------------- /pclint/makefile: -------------------------------------------------------------------------------- 1 | DIR_ROOT := .. 2 | DIR_ENVIRONMENT := environment 3 | DIR_SETTINGS := settings 4 | DIR_REPORT := report 5 | 6 | PCLINT_LIB := /usr/local/lib/pclint 7 | PCLINT_BIN := /usr/local/bin/pclint 8 | 9 | CC := gcc 10 | GXX := g++ 11 | 12 | SRC := $(wildcard $(DIR_ROOT)/src/*.c) 13 | 14 | DEFINES += -DLDL_ENABLE_US_902_928 15 | DEFINES += -DLDL_ENABLE_AU_915_928 16 | DEFINES += -DLDL_ENABLE_EU_863_870 17 | DEFINES += -DLDL_ENABLE_EU_433 18 | 19 | DEFINES += -DLDL_ENABLE_SX1272 20 | DEFINES += -DLDL_ENABLE_SX1276 21 | DEFINES += -DLDL_ENABLE_SX1261 22 | DEFINES += -DLDL_ENABLE_SX1262 23 | 24 | DEFINES += -DLDL_L2_VERSION=LDL_L2_VERSION_1_1 25 | 26 | # radio debug stuff isn't for production so don't check it 27 | #DEFINES += -DLDL_ENABLE_RADIO_DEBUG 28 | 29 | DEFINES += -DLDL_TRACE 30 | 31 | INCLUDES += -I$(DIR_SETTINGS) 32 | INCLUDES += -I$(DIR_ENVIRONMENT) 33 | INCLUDES += -I$(DIR_ROOT)/include 34 | 35 | # keep going after errors 36 | RULES += '-zero' 37 | 38 | # use latest misra rules 39 | RULES += au-misra3.lnt 40 | 41 | # toolchain config 42 | RULES += co-gcc.lnt 43 | 44 | # n pass algorithm 45 | RULES += '-passes(2)' 46 | 47 | # no line breaks, 4 character indent 48 | RULES += '-width(0,4)' 49 | 50 | # suppress noise around use of stdbool 51 | RULES += '-esym(970,_Bool)' 52 | 53 | # errors are contained to files they appear in 54 | RULES += '-restore_at_end' 55 | 56 | # our headers are not library headers 57 | RULES += '-libdir($(DIR_ROOT)/include)' 58 | 59 | # unit checkout since this is a library 60 | RULES += '-u' 61 | 62 | # verbose 63 | RULES += '-vfo' 64 | 65 | .PHONY: install mandatory required advisory $(DIR_REPORT)/report.txt 66 | 67 | all: mandatory required advisory 68 | 69 | # run co-gcc.mak to gather toolchain settings in the environment folder 70 | install: 71 | cd $(DIR_ENVIRONMENT) && make -f co-gcc.mak clean 72 | cd $(DIR_ENVIRONMENT) && make -f co-gcc.mak GCC_BIN=$(CC) GXX_BIN=$(GXX) CFLAGS=$(CFLAGS) CXXFLAGS=$(CXXFLAGS) CPPFLAGS=$(CPPFLAGS) COMMON_FLAGS=$(COMMON_FLAGS) 73 | 74 | $(DIR_REPORT)/report.txt: $(SRC) 75 | $(PCLINT_BIN) '-os($@)' ++b $(DEFINES) $(INCLUDES) $(RULES) $^ 76 | 77 | mandatory: $(DIR_REPORT)/report.txt 78 | @ echo "$@: `cat $^ | grep -c $@` instances" 79 | @ cat $^ | grep -s $@ || true 80 | 81 | required: $(DIR_REPORT)/report.txt 82 | @ echo "$@: `cat $^ | grep -c $@` instances" 83 | @ cat $^ | grep $@ || true 84 | 85 | advisory: $(DIR_REPORT)/report.txt 86 | @ echo "$@: `cat $^ | grep -c $@` instances" 87 | @ cat $^ | grep $@ || true 88 | 89 | clean: 90 | rm -f $(DIR_REPORT)/report.txt 91 | -------------------------------------------------------------------------------- /pclint/readme.md: -------------------------------------------------------------------------------- 1 | PCLINT Configuration 2 | ==================== 3 | 4 | This folder contains the configuration used to lint lora_device_lib to MISRA 2012. 5 | 6 | ## Prerequisites 7 | 8 | - Linux (I use something ubuntu-like) 9 | - System GCC 10 | - The executable `pclint` somewhere in search path 11 | - I use a shell wrapper around lint-nt.exe running with wine 12 | 13 | ## Process 14 | 15 | - `make install` will find the various toolchain includes and cache the locations 16 | - `make all` will produce report.txt and print the following: 17 | - `make mandatory` print a count and summary of all MISRA *mandatory* deviations 18 | - `make required` print a count and summary of all MISRA *required* deviations 19 | - `make advisory` print a count and summary of all MISRA *advisory* deviations 20 | 21 | ## Suppression Policy 22 | 23 | ### Mandatory 24 | 25 | - Re-implemented 26 | 27 | ### Required 28 | 29 | - Re-implemented where convenient, or, 30 | - Suppressed within code with a justification 31 | 32 | ### Advisory 33 | 34 | - Re-implemented, or, 35 | - Ignored 36 | 37 | ## Rules 38 | 39 | - The rules are defined in the makefile 40 | - Order is important 41 | 42 | ## Issues 43 | 44 | - It's a mystery as to how to suppress toolchain warnings (-wlib(0) does nothing) 45 | - I'm not sure the correct order between `au-misra3.lnt` and `co-gcc.lnt` 46 | - I am using the order that produces fewer warnings about the toolchain 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /pclint/report/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /rakefile: -------------------------------------------------------------------------------- 1 | require 'rake/testtask' 2 | require 'rake/extensiontask' 3 | require 'fileutils' 4 | 5 | task :compile => [:clean] 6 | 7 | Rake::ExtensionTask.new do |ext| 8 | ext.name = "ext_ldl" 9 | ext.ext_dir = "wrappers/ruby/ext/ldl/ext_ldl" 10 | ext.lib_dir = "wrappers/ruby/lib/ldl" 11 | end 12 | 13 | Rake::TestTask.new do |t| 14 | t.name = :test 15 | t.libs << "wrappers/ruby/lib" 16 | t.test_files = FileList["wrappers/ruby/test/**/*_test.rb"] 17 | end 18 | 19 | task :default => :test 20 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | LDL: A LoRaWAN Device Library 2 | ============================= 3 | 4 | [![Build Status](https://travis-ci.org/cjhdev/lora_device_lib.svg?branch=master)](https://travis-ci.org/cjhdev/lora_device_lib) 5 | 6 | LDL is a [LoRaWAN](https://en.wikipedia.org/wiki/LoRa#LoRaWAN) implementation for devices. 7 | 8 | Use one of the [releases](https://github.com/cjhdev/lora_device_lib/releases) 9 | for best results and read [history.md](history.md) if updating from an old version. 10 | 11 | ## Examples 12 | 13 | - [MBED rtos profile](examples/mbed/rtos) 14 | - [MBED bare-metal profile](examples/mbed/bare_metal) 15 | - [generic mainloop](examples/doxygen/example.c) 16 | - [generic chip interface](examples/chip_interface) 17 | - [ruby virtual hardware](examples/ruby) 18 | 19 | ## Features 20 | 21 | - Small memory footprint 22 | - L2 Support 23 | - 1.0.3 (recommended) 24 | - 1.0.4 (recommended) 25 | - 1.1 26 | - Class A 27 | - OTAA 28 | - ADR 29 | - Region Support (RP002-1.0.1) 30 | - EU_868_870 31 | - EU_433 32 | - US_902_928 33 | - AU_915_928 34 | - Radio Drivers 35 | - SX1272 36 | - SX1276 37 | - SX1261 38 | - SX1262 39 | - STM32WL55 40 | - Linted to MISRA 2012 41 | 42 | ## Limitations 43 | 44 | - Class B and C not supported 45 | - FSK modulation not supported 46 | - ABP not supported 47 | - 1.1 Rejoin not supported 48 | - **Experimental** 49 | 50 | ## Documentation 51 | 52 | - [porting guide](porting.md) 53 | - [interface documentation](https://ldl.readthedocs.io/en/latest/) 54 | - [history](history.md) 55 | - [design goals](design_goals.md) 56 | - [todo list](todo.md) 57 | - [contribution guidelines](contributing.md) 58 | 59 | ## See Also 60 | 61 | - [LoRaMAC-Node](https://github.com/Lora-net/LoRaMac-node) 62 | 63 | ## License 64 | 65 | MIT 66 | -------------------------------------------------------------------------------- /test/bin/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /test/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /test/debug_include.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_INCLUDE_H 2 | #define DEBUG_INCLUDE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define LDL_ERROR(...) do{fprintf(stderr, "ERROR: %s: ", __FUNCTION__);fprintf(stderr, __VA_ARGS__);fprintf(stderr, "\n");}while(0); 9 | #define LDL_DEBUG(...) do{fprintf(stderr, "DEBUG: %s: ", __FUNCTION__);fprintf(stderr, __VA_ARGS__);fprintf(stderr, "\n");}while(0); 10 | #define LDL_INFO(...) do{fprintf(stderr, "INFO: %s: ", __FUNCTION__);fprintf(stderr, __VA_ARGS__);fprintf(stderr, "\n");}while(0); 11 | 12 | void print_hex(FILE *fd, const uint8_t *data, size_t size); 13 | extern FILE * trace_desc; 14 | 15 | #define LDL_TRACE_BEGIN() fprintf(trace_desc, "TRACE: %s: ", __FUNCTION__); 16 | #define LDL_TRACE_PART(...) fprintf(trace_desc, __VA_ARGS__); 17 | #define LDL_TRACE_HEX(PTR, LEN) print_hex(trace_desc, PTR, LEN); 18 | #define LDL_TRACE_FINAL() fprintf(trace_desc, "\n"); 19 | 20 | #define LDL_ASSERT(X) assert((X)); 21 | #define LDL_PEDANTIC(X) LDL_ASSERT(X) 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /test/mock_ldl_system.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "cmocka.h" 7 | 8 | #include "ldl_system.h" 9 | #include "mock_ldl_system.h" 10 | 11 | #include 12 | 13 | void mock_lora_system_init(struct mock_system_param *self) 14 | { 15 | (void)memset(self, 0, sizeof(*self)); 16 | } 17 | 18 | uint32_t system_time = 0U; 19 | 20 | uint32_t LDL_System_ticks(void *app) 21 | { 22 | (void)app; 23 | 24 | return system_time; 25 | } 26 | 27 | uint32_t LDL_System_rand(void *app) 28 | { 29 | (void)app; 30 | 31 | return mock(); 32 | } 33 | 34 | uint32_t LDL_System_getBatteryLevel(void *receiver) 35 | { 36 | struct mock_system_param *self = (struct mock_system_param *)receiver; 37 | return self->battery_level; 38 | } 39 | 40 | FILE * trace_desc; 41 | 42 | void print_hex(FILE * fd, const uint8_t *data, size_t size) 43 | { 44 | size_t i; 45 | 46 | for(i=0U; i < size; i++){ 47 | 48 | fprintf(fd, "%02X", data[i]); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/mock_ldl_system.h: -------------------------------------------------------------------------------- 1 | #ifndef MOCK_LORA_SYSTEM_H 2 | #define MOCK_LORA_SYSTEM_H 3 | 4 | #include "ldl_system.h" 5 | #include "ldl_mac.h" 6 | 7 | struct mock_system_param { 8 | 9 | uint8_t battery_level; 10 | 11 | uint16_t upCounter; 12 | uint16_t downCounter; 13 | }; 14 | 15 | void mock_lora_system_init(struct mock_system_param *self); 16 | 17 | uint32_t LDL_System_ticks(void *app); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /test/tc_aes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "cmocka.h" 6 | 7 | #include "ldl_aes.h" 8 | 9 | #include 10 | 11 | static void test_LDL_AES_init(void **user) 12 | { 13 | (void)user; 14 | 15 | struct ldl_aes_ctx aes; 16 | static const uint8_t key[] = {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}; 17 | 18 | LDL_AES_init(&aes, key); 19 | } 20 | 21 | static void test_LDL_AES_encrypt(void **user) 22 | { 23 | (void)user; 24 | 25 | static const uint8_t key[] = {0x10,0xa5,0x88,0x69,0xd7,0x4b,0xe5,0xa3,0x74,0xcf,0x86,0x7c,0xfb,0x47,0x38,0x59}; 26 | static const uint8_t pt[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 27 | static const uint8_t ct[] = {0x6d,0x25,0x1e,0x69,0x44,0xb0,0x51,0xe0,0x4e,0xaa,0x6f,0xb4,0xdb,0xf7,0x84,0x65}; 28 | 29 | struct ldl_aes_ctx aes; 30 | uint8_t out[16U]; 31 | 32 | memcpy(out, pt, sizeof(out)); 33 | LDL_AES_init(&aes, key); 34 | LDL_AES_encrypt(&aes, out); 35 | 36 | assert_memory_equal(ct, out, sizeof(ct)); 37 | } 38 | 39 | int main(void) 40 | { 41 | const struct CMUnitTest tests[] = { 42 | cmocka_unit_test(test_LDL_AES_init), 43 | cmocka_unit_test(test_LDL_AES_encrypt) 44 | }; 45 | 46 | return cmocka_run_group_tests(tests, NULL, NULL); 47 | } 48 | -------------------------------------------------------------------------------- /test/tc_dummy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "cmocka.h" 6 | 7 | #include 8 | 9 | static void test_dummy(void **user) 10 | { 11 | (void)user; 12 | } 13 | 14 | int main(void) 15 | { 16 | const struct CMUnitTest tests[] = { 17 | cmocka_unit_test(test_dummy) 18 | }; 19 | 20 | return cmocka_run_group_tests(tests, NULL, NULL); 21 | } 22 | -------------------------------------------------------------------------------- /test/tc_mac_commands.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "cmocka.h" 6 | #include "ldl_mac_commands.h" 7 | #include "ldl_stream.h" 8 | 9 | static void test_putLinkCheckReq(void **user) 10 | { 11 | (void)user; 12 | 13 | uint8_t buffer[50U]; 14 | struct ldl_stream s; 15 | LDL_Stream_init(&s, buffer, sizeof(buffer)); 16 | 17 | uint8_t expected[] = "\x02"; 18 | 19 | LDL_MAC_putLinkCheckReq(&s); 20 | 21 | assert_false(LDL_Stream_error(&s)); 22 | 23 | assert_int_equal(sizeof(expected)-1U, LDL_Stream_tell(&s)); 24 | assert_memory_equal(expected, buffer, LDL_Stream_tell(&s)); 25 | } 26 | 27 | int main(void) 28 | { 29 | const struct CMUnitTest tests[] = { 30 | cmocka_unit_test(test_putLinkCheckReq), 31 | }; 32 | 33 | return cmocka_run_group_tests(tests, NULL, NULL); 34 | } 35 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | Todo 2 | ==== 3 | 4 | - Implement the LoRaWAN conformance test application 5 | - The test app should be "built-in" and run from LDL_MAC_process() 6 | - The test app should be included in the build if LDL_ENABLE_TEST_MODE is defined 7 | - The test app should be started and stopped from a LDL_MAC_* interface 8 | 9 | - LoRaWAN conformance test 10 | - need to put LDL through the test 11 | 12 | - Class B 13 | - plan for how this feature can integrate with existing patterns 14 | - implement mode 15 | - implement tooling to prove the feature works 16 | 17 | - Class C 18 | - plan for how this feature can integrate with existing patterns 19 | - implement mode 20 | - implement tooling to prove the feature works 21 | 22 | - Add support for additional regions 23 | - CN_779 24 | - CN_470_510 25 | - AS_923 26 | - KR_920_923 27 | - IN_865_867 28 | - RU_864_870 29 | 30 | - Radio driver improvements 31 | - add adjustment for current trim 32 | - add adjustment for PA ramp time 33 | - add FSK mode 34 | - add continuous wave mode 35 | - add support for LR1110 36 | - MAC/Radio integration needs a calibration state to avoid blocking 37 | on radio start at TX when TCXO is used 38 | -------------------------------------------------------------------------------- /vendor/cmocka/.clang_complete: -------------------------------------------------------------------------------- 1 | -Iinclude 2 | -Iobj 3 | -------------------------------------------------------------------------------- /vendor/cmocka/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *~$ 3 | tags 4 | cscope.* 5 | .ycm_extra_conf.pyc 6 | /build 7 | /obj* 8 | -------------------------------------------------------------------------------- /vendor/cmocka/AUTHORS: -------------------------------------------------------------------------------- 1 | opensource@google.com 2 | Andreas Schneider 3 | Jakub Hrozek 4 | -------------------------------------------------------------------------------- /vendor/cmocka/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(cmocka C) 2 | 3 | # Required cmake version 4 | cmake_minimum_required(VERSION 2.6.0) 5 | 6 | # global needed variables 7 | set(APPLICATION_NAME ${PROJECT_NAME}) 8 | 9 | set(APPLICATION_VERSION_MAJOR "1") 10 | set(APPLICATION_VERSION_MINOR "1") 11 | set(APPLICATION_VERSION_PATCH "0") 12 | 13 | set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}") 14 | 15 | # SOVERSION scheme: CURRENT.AGE.REVISION 16 | # If there was an incompatible interface change: 17 | # Increment CURRENT. Set AGE and REVISION to 0 18 | # If there was a compatible interface change: 19 | # Increment AGE. Set REVISION to 0 20 | # If the source code was changed, but there were no interface changes: 21 | # Increment REVISION. 22 | set(LIBRARY_VERSION "0.4.0") 23 | set(LIBRARY_SOVERSION "0") 24 | 25 | # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked 26 | set(CMAKE_MODULE_PATH 27 | ${CMAKE_SOURCE_DIR}/cmake/Modules 28 | ) 29 | 30 | # add definitions 31 | include(DefineCMakeDefaults) 32 | include(DefinePlatformDefaults) 33 | include(DefineCompilerFlags) 34 | include(DefineInstallationPaths) 35 | include(DefineOptions.cmake) 36 | include(CPackConfig.cmake) 37 | include(CheckSymbolExists) 38 | 39 | # disallow in-source build 40 | include(MacroEnsureOutOfSourceBuild) 41 | macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.") 42 | 43 | # config.h checks 44 | include(ConfigureChecks.cmake) 45 | configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) 46 | 47 | # MinGW DLL Naming Workaround 48 | if (MINGW) 49 | set(CMAKE_SHARED_LIBRARY_PREFIX "") 50 | endif (MINGW) 51 | 52 | # check subdirectories 53 | add_subdirectory(doc) 54 | add_subdirectory(include) 55 | add_subdirectory(src) 56 | 57 | if (UNIT_TESTING) 58 | include(AddCMockaTest) 59 | add_subdirectory(tests) 60 | endif (UNIT_TESTING) 61 | 62 | add_subdirectory(example) 63 | 64 | # pkg-config file 65 | configure_file(cmocka.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmocka.pc) 66 | install( 67 | FILES 68 | ${CMAKE_CURRENT_BINARY_DIR}/cmocka.pc 69 | DESTINATION 70 | ${LIB_INSTALL_DIR}/pkgconfig 71 | COMPONENT 72 | pkgconfig 73 | ) 74 | 75 | # cmake config files 76 | set(CMOCKA_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) 77 | 78 | configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY) 79 | configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY) 80 | install( 81 | FILES 82 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake 83 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake 84 | DESTINATION 85 | ${CMAKE_INSTALL_DIR}/${PROJECT_NAME} 86 | COMPONENT 87 | devel 88 | ) 89 | -------------------------------------------------------------------------------- /vendor/cmocka/CPackConfig.cmake: -------------------------------------------------------------------------------- 1 | # For help take a look at: 2 | # http://www.cmake.org/Wiki/CMake:CPackConfiguration 3 | 4 | ### general settings 5 | set(CPACK_PACKAGE_NAME ${APPLICATION_NAME}) 6 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Unit testing framework for C with mock objects") 7 | set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README") 8 | set(CPACK_PACKAGE_VENDOR "Andreas Schneider") 9 | set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) 10 | set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING") 11 | 12 | 13 | ### versions 14 | set(CPACK_PACKAGE_VERSION_MAJOR "${APPLICATION_VERSION_MAJOR}") 15 | set(CPACK_PACKAGE_VERSION_MINOR "${APPLICATION_VERSION_MINOR}") 16 | set(CPACK_PACKAGE_VERSION_PATCH "${APPLICATION_VERSION_PATCH}") 17 | set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") 18 | 19 | 20 | ### source generator 21 | set(CPACK_SOURCE_GENERATOR "TGZ") 22 | set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/obj*;tags;cscope.*;.ycm_extra_conf.pyc") 23 | set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") 24 | 25 | if (WIN32) 26 | set(CPACK_GENERATOR "ZIP") 27 | 28 | ### nsis generator 29 | find_package(NSIS) 30 | if (NSIS_MAKE) 31 | set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS") 32 | set(CPACK_NSIS_DISPLAY_NAME "CMocka") 33 | set(CPACK_NSIS_COMPRESSOR "/SOLID zlib") 34 | set(CPACK_NSIS_MENU_LINKS "http://cmocka.org/" "cmocka homepage") 35 | endif (NSIS_MAKE) 36 | endif (WIN32) 37 | 38 | set(CPACK_PACKAGE_INSTALL_DIRECTORY "cmocka") 39 | 40 | set(CPACK_PACKAGE_FILE_NAME ${APPLICATION_NAME}-${CPACK_PACKAGE_VERSION}) 41 | 42 | set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries") 43 | set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers") 44 | set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION 45 | "Libraries used to build programs which use cmocka") 46 | set(CPACK_COMPONENT_HEADERS_DESCRIPTION 47 | "C/C++ header files for use with cmocka") 48 | set(CPACK_COMPONENT_HEADERS_DEPENDS libraries) 49 | #set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime") 50 | set(CPACK_COMPONENT_LIBRARIES_GROUP "Development") 51 | set(CPACK_COMPONENT_HEADERS_GROUP "Development") 52 | 53 | include(CPack) 54 | -------------------------------------------------------------------------------- /vendor/cmocka/CTestConfig.cmake: -------------------------------------------------------------------------------- 1 | set(UPDATE_TYPE "true") 2 | 3 | set(CTEST_PROJECT_NAME "cmocka") 4 | set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") 5 | 6 | set(CTEST_DROP_METHOD "https") 7 | set(CTEST_DROP_SITE "mock.cryptomilk.org") 8 | set(CTEST_DROP_LOCATION "/submit.php?project=${CTEST_PROJECT_NAME}") 9 | set(CTEST_DROP_SITE_CDASH TRUE) 10 | 11 | -------------------------------------------------------------------------------- /vendor/cmocka/DefineOptions.cmake: -------------------------------------------------------------------------------- 1 | option(WITH_STATIC_LIB "Build with a static library" OFF) 2 | option(WITH_CMOCKERY_SUPPORT "Install a cmockery header" OFF) 3 | option(UNIT_TESTING "Build with unit testing" OFF) 4 | 5 | if (UNIT_TESTING) 6 | set(WITH_STATIC_LIB ON) 7 | endif() 8 | -------------------------------------------------------------------------------- /vendor/cmocka/NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cjhdev/lora_device_lib/e017b222d1ef3cb21b982d19cb7a5c0f3dfe95cb/vendor/cmocka/NEWS -------------------------------------------------------------------------------- /vendor/cmocka/README: -------------------------------------------------------------------------------- 1 | CMOCKA 2 | ======= 3 | 4 | cmocka is a fork for Google's cmockery unit testing framework to fix bugs and 5 | support it in future. 6 | See https://code.google.com/p/cmockery/ 7 | 8 | For information about how to use the cmocka unit testing framework see 9 | doc/index.html. 10 | 11 | COMPILING 12 | --------- 13 | To compile the cmocka library and example applications run, create a build dir, 14 | and in the build dir call 'cmake /path/to/cmocka' followed by 'make'. On 15 | Windows you can use the cmake gui. More details can be found in the INSTALL file. 16 | -------------------------------------------------------------------------------- /vendor/cmocka/cmake/Modules/AddCMockaTest.cmake: -------------------------------------------------------------------------------- 1 | # - ADD_CMOCKA_TEST(test_name test_source linklib1 ... linklibN) 2 | 3 | # Copyright (c) 2007 Daniel Gollub 4 | # Copyright (c) 2007-2010 Andreas Schneider 5 | # 6 | # Redistribution and use is allowed according to the terms of the BSD license. 7 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 8 | 9 | enable_testing() 10 | include(CTest) 11 | 12 | if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW) 13 | set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags") 14 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") 15 | set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") 16 | set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags") 17 | endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW) 18 | 19 | function (ADD_CMOCKA_TEST _testName _testSource) 20 | add_executable(${_testName} ${_testSource}) 21 | target_link_libraries(${_testName} ${ARGN}) 22 | add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName}) 23 | endfunction (ADD_CMOCKA_TEST) 24 | -------------------------------------------------------------------------------- /vendor/cmocka/cmake/Modules/COPYING-CMAKE-SCRIPTS: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions 3 | are met: 4 | 5 | 1. Redistributions of source code must retain the copyright 6 | notice, this list of conditions and the following disclaimer. 7 | 2. Redistributions in binary form must reproduce the copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | 3. The name of the author may not be used to endorse or promote products 11 | derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /vendor/cmocka/cmake/Modules/CheckCCompilerFlagSSP.cmake: -------------------------------------------------------------------------------- 1 | # - Check whether the C compiler supports a given flag in the 2 | # context of a stack checking compiler option. 3 | 4 | # CHECK_C_COMPILER_FLAG_SSP(FLAG VARIABLE) 5 | # 6 | # FLAG - the compiler flag 7 | # VARIABLE - variable to store the result 8 | # 9 | # This actually calls check_c_source_compiles. 10 | # See help for CheckCSourceCompiles for a listing of variables 11 | # that can modify the build. 12 | 13 | # Copyright (c) 2006, Alexander Neundorf, 14 | # 15 | # Redistribution and use is allowed according to the terms of the BSD license. 16 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 17 | 18 | 19 | include(CheckCSourceCompiles) 20 | 21 | function(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT) 22 | set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") 23 | set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") 24 | check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT}) 25 | set(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") 26 | endfunction(CHECK_C_COMPILER_FLAG_SSP) 27 | -------------------------------------------------------------------------------- /vendor/cmocka/cmake/Modules/DefineCMakeDefaults.cmake: -------------------------------------------------------------------------------- 1 | # Always include srcdir and builddir in include path 2 | # This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in 3 | # about every subdir 4 | # since cmake 2.4.0 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | 7 | # Put the include dirs which are in the source or build tree 8 | # before all other include dirs, so the headers in the sources 9 | # are prefered over the already installed ones 10 | # since cmake 2.4.1 11 | set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) 12 | 13 | # Use colored output 14 | # since cmake 2.4.0 15 | set(CMAKE_COLOR_MAKEFILE ON) 16 | 17 | # Define the generic version of the libraries here 18 | set(GENERIC_LIB_VERSION "0.1.0") 19 | set(GENERIC_LIB_SOVERSION "0") 20 | 21 | # Set the default build type to release with debug info 22 | if (NOT CMAKE_BUILD_TYPE) 23 | set(CMAKE_BUILD_TYPE RelWithDebInfo 24 | CACHE STRING 25 | "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." 26 | ) 27 | endif (NOT CMAKE_BUILD_TYPE) 28 | 29 | # Create the compile command database for clang by default 30 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 31 | 32 | if (APPLE) 33 | set(CMAKE_MACOSX_RPATH ON) 34 | set(CMAKE_SKIP_BUILD_RPATH FALSE) 35 | set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 36 | endif(APPLE) 37 | -------------------------------------------------------------------------------- /vendor/cmocka/cmake/Modules/DefinePlatformDefaults.cmake: -------------------------------------------------------------------------------- 1 | # Set system vars 2 | 3 | if (CMAKE_SYSTEM_NAME MATCHES "Linux") 4 | set(LINUX TRUE) 5 | endif(CMAKE_SYSTEM_NAME MATCHES "Linux") 6 | 7 | if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") 8 | set(FREEBSD TRUE) 9 | endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") 10 | 11 | if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") 12 | set(OPENBSD TRUE) 13 | endif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") 14 | 15 | if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") 16 | set(NETBSD TRUE) 17 | endif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") 18 | 19 | if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") 20 | set(SOLARIS TRUE) 21 | endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") 22 | -------------------------------------------------------------------------------- /vendor/cmocka/cmake/Modules/FindNSIS.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find NSIS 2 | # Once done this will define 3 | # 4 | # NSIS_FOUND - system has NSIS 5 | # NSIS_MAKE - NSIS creator executable 6 | # 7 | #============================================================================= 8 | # Copyright (c) 2010-2013 Andreas Schneider 9 | # 10 | # Distributed under the OSI-approved BSD License (the "License"); 11 | # see accompanying file Copyright.txt for details. 12 | # 13 | # This software is distributed WITHOUT ANY WARRANTY; without even the 14 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | # See the License for more information. 16 | #============================================================================= 17 | # 18 | 19 | if (WIN32) 20 | set(_NSIS_ROOT_HINTS 21 | "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS;Default]") 22 | 23 | set(_NSIS_ROOT_PATHS 24 | $ENV{PROGRAMFILES}/NSIS) 25 | 26 | find_path(NSIS_ROOT_PATH 27 | NAMES 28 | Include/Library.nsh 29 | HINTS 30 | ${_NSIS_ROOT_HINTS} 31 | PATHS 32 | ${_NSIS_ROOT_PATHS} 33 | ) 34 | mark_as_advanced(NSIS_ROOT_PATH) 35 | endif (WIN32) 36 | 37 | find_program(NSIS_MAKE 38 | NAMES 39 | makensis 40 | PATHS 41 | ${NSIS_ROOT_PATH} 42 | ) 43 | 44 | include(FindPackageHandleStandardArgs) 45 | find_package_handle_standard_args(NSIS DEFAULT_MSG NSIS_MAKE) 46 | 47 | if (NSIS_MAKE) 48 | set(NSIS_FOUND TRUE) 49 | endif (NSIS_MAKE) 50 | 51 | mark_as_advanced(NSIS_MAKE) 52 | -------------------------------------------------------------------------------- /vendor/cmocka/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake: -------------------------------------------------------------------------------- 1 | # - MACRO_ENSURE_OUT_OF_SOURCE_BUILD() 2 | # MACRO_ENSURE_OUT_OF_SOURCE_BUILD() 3 | 4 | # Copyright (c) 2006, Alexander Neundorf, 5 | # 6 | # Redistribution and use is allowed according to the terms of the BSD license. 7 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 8 | 9 | macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage) 10 | 11 | string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource) 12 | if (_insource) 13 | message(SEND_ERROR "${_errorMessage}") 14 | message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.") 15 | endif (_insource) 16 | 17 | endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD) 18 | -------------------------------------------------------------------------------- /vendor/cmocka/cmocka-build-tree-settings.cmake.in: -------------------------------------------------------------------------------- 1 | set(CMOCKA_INLUDE_DIR @PROJECT_SOURCE_DIR@/include) 2 | -------------------------------------------------------------------------------- /vendor/cmocka/cmocka-config-version.cmake.in: -------------------------------------------------------------------------------- 1 | set(PACKAGE_VERSION @APPLICATION_VERSION@) 2 | 3 | # Check whether the requested PACKAGE_FIND_VERSION is compatible 4 | if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") 5 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 6 | else() 7 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 8 | if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") 9 | set(PACKAGE_VERSION_EXACT TRUE) 10 | endif() 11 | endif() 12 | -------------------------------------------------------------------------------- /vendor/cmocka/cmocka-config.cmake.in: -------------------------------------------------------------------------------- 1 | get_filename_component(CMOCKA_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 2 | 3 | if (EXISTS "${CMOCKA_CMAKE_DIR}/CMakeCache.txt") 4 | # In build tree 5 | include(${CMOCKA_CMAKE_DIR}/cmocka-build-tree-settings.cmake) 6 | else() 7 | set(CMOCKA_INCLUDE_DIR @INCLUDE_INSTALL_DIR@) 8 | endif() 9 | 10 | set(CMOCKA_LIBRARY @LIB_INSTALL_DIR@/@CMOCKA_LIBRARY_NAME@) 11 | set(CMOCKA_LIBRARIES @LIB_INSTALL_DIR@/@CMOCKA_LIBRARY_NAME@) 12 | -------------------------------------------------------------------------------- /vendor/cmocka/cmocka.pc.cmake: -------------------------------------------------------------------------------- 1 | Name: ${APPLICATION_NAME} 2 | Description: The cmocka unit testing library 3 | Version: ${APPLICATION_VERSION} 4 | Libs: -L${LIB_INSTALL_DIR} -lcmocka 5 | Cflags: -I${INCLUDE_INSTALL_DIR} 6 | 7 | -------------------------------------------------------------------------------- /vendor/cmocka/coverity/README: -------------------------------------------------------------------------------- 1 | coverity_assert_model.c: 2 | 3 | This file is a Coverity Modeling file for projects using CMocka for unit 4 | testing. The assert functiions could create false positives, to avoid that you 5 | can load this modeling file in the Coverity web interface. 6 | 7 | coverity_internal_model.c: 8 | 9 | This file is for the CMocka source code itself. 10 | -------------------------------------------------------------------------------- /vendor/cmocka/coverity/coverity_assert_model.c: -------------------------------------------------------------------------------- 1 | #define LargestIntegralType unsigned long long 2 | 3 | void _assert_true(const LargestIntegralType result, 4 | const char* const expression, 5 | const char * const file, const int line) 6 | { 7 | __coverity_panic__(); 8 | } 9 | 10 | void _assert_int_equal( 11 | const LargestIntegralType a, const LargestIntegralType b, 12 | const char * const file, const int line) 13 | { 14 | __coverity_panic__(); 15 | } 16 | 17 | void _assert_int_not_equal( 18 | const LargestIntegralType a, const LargestIntegralType b, 19 | const char * const file, const int line) 20 | { 21 | __coverity_panic__(); 22 | } 23 | 24 | void _assert_return_code(const LargestIntegralType result, 25 | size_t rlen, 26 | const LargestIntegralType error, 27 | const char * const expression, 28 | const char * const file, 29 | const int line) 30 | { 31 | __coverity_panic__(); 32 | } 33 | 34 | void _assert_string_equal(const char * const a, const char * const b, 35 | const char * const file, const int line) 36 | { 37 | __coverity_panic__(); 38 | } 39 | 40 | void _assert_string_not_equal(const char * const a, const char * const b, 41 | const char *file, const int line) 42 | { 43 | __coverity_panic__(); 44 | } 45 | 46 | void _assert_memory_equal(const void * const a, const void * const b, 47 | const size_t size, const char* const file, 48 | const int line) 49 | { 50 | __coverity_panic__(); 51 | } 52 | 53 | void _assert_memory_not_equal(const void * const a, const void * const b, 54 | const size_t size, const char* const file, 55 | const int line) 56 | { 57 | __coverity_panic__(); 58 | } 59 | 60 | void _assert_in_range( 61 | const LargestIntegralType value, const LargestIntegralType minimum, 62 | const LargestIntegralType maximum, const char* const file, const int line) 63 | { 64 | __coverity_panic__(); 65 | } 66 | 67 | void _assert_not_in_range( 68 | const LargestIntegralType value, const LargestIntegralType minimum, 69 | const LargestIntegralType maximum, const char* const file, const int line) 70 | { 71 | __coverity_panic__(); 72 | } 73 | 74 | void _assert_in_set( 75 | const LargestIntegralType value, const LargestIntegralType values[], 76 | const size_t number_of_values, const char* const file, const int line) 77 | { 78 | __coverity_panic__(); 79 | } 80 | 81 | void _assert_not_in_set( 82 | const LargestIntegralType value, const LargestIntegralType values[], 83 | const size_t number_of_values, const char* const file, const int line) 84 | { 85 | __coverity_panic__(); 86 | } 87 | 88 | -------------------------------------------------------------------------------- /vendor/cmocka/coverity/coverity_internal_model.c: -------------------------------------------------------------------------------- 1 | /* Functions to help coverity do static analysis on cmocka */ 2 | void exit_test(const int quit_application) 3 | { 4 | __coverity_panic__(); 5 | } 6 | -------------------------------------------------------------------------------- /vendor/cmocka/doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Build the documentation 3 | # 4 | include(UseDoxygen OPTIONAL) 5 | 6 | -------------------------------------------------------------------------------- /vendor/cmocka/example/allocate_module.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #ifdef HAVE_CONFIG_H 17 | #include "config.h" 18 | #endif 19 | #ifdef HAVE_MALLOC_H 20 | #include 21 | #endif 22 | #include 23 | #include 24 | 25 | #ifdef UNIT_TESTING 26 | extern void* _test_malloc(const size_t size, const char* file, const int line); 27 | extern void* _test_calloc(const size_t number_of_elements, const size_t size, 28 | const char* file, const int line); 29 | extern void _test_free(void* const ptr, const char* file, const int line); 30 | 31 | #define malloc(size) _test_malloc(size, __FILE__, __LINE__) 32 | #define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) 33 | #define free(ptr) _test_free(ptr, __FILE__, __LINE__) 34 | #endif // UNIT_TESTING 35 | 36 | void leak_memory(void); 37 | void buffer_overflow(void); 38 | void buffer_underflow(void); 39 | 40 | void leak_memory(void) { 41 | int * const temporary = (int*)malloc(sizeof(int)); 42 | *temporary = 0; 43 | } 44 | 45 | void buffer_overflow(void) { 46 | char * const memory = (char*)malloc(sizeof(int)); 47 | memory[sizeof(int)] = '!'; 48 | free(memory); 49 | } 50 | 51 | void buffer_underflow(void) { 52 | char * const memory = (char*)malloc(sizeof(int)); 53 | memory[-1] = '!'; 54 | free(memory); 55 | } 56 | -------------------------------------------------------------------------------- /vendor/cmocka/example/allocate_module_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | extern void leak_memory(void); 22 | extern void buffer_overflow(void); 23 | extern void buffer_underflow(void); 24 | 25 | /* Test case that fails as leak_memory() leaks a dynamically allocated block. */ 26 | static void leak_memory_test(void **state) { 27 | (void) state; /* unused */ 28 | 29 | leak_memory(); 30 | } 31 | 32 | /* Test case that fails as buffer_overflow() corrupts an allocated block. */ 33 | static void buffer_overflow_test(void **state) { 34 | (void) state; /* unused */ 35 | 36 | buffer_overflow(); 37 | } 38 | 39 | /* Test case that fails as buffer_underflow() corrupts an allocated block. */ 40 | static void buffer_underflow_test(void **state) { 41 | (void) state; /* unused */ 42 | 43 | buffer_underflow(); 44 | } 45 | 46 | int main(void) { 47 | const struct CMUnitTest tests[] = { 48 | cmocka_unit_test(leak_memory_test), 49 | cmocka_unit_test(buffer_overflow_test), 50 | cmocka_unit_test(buffer_underflow_test), 51 | }; 52 | return cmocka_run_group_tests(tests, NULL, NULL); 53 | } 54 | -------------------------------------------------------------------------------- /vendor/cmocka/example/assert_macro.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 18 | #include "assert_macro.h" 19 | 20 | static const char* status_code_strings[] = { 21 | "Address not found", 22 | "Connection dropped", 23 | "Connection timed out", 24 | }; 25 | 26 | const char* get_status_code_string(const unsigned int status_code) { 27 | return status_code_strings[status_code]; 28 | } 29 | 30 | unsigned int string_to_status_code(const char* const status_code_string) { 31 | unsigned int i; 32 | for (i = 0; i < sizeof(status_code_strings) / 33 | sizeof(status_code_strings[0]); i++) { 34 | if (strcmp(status_code_strings[i], status_code_string) == 0) { 35 | return i; 36 | } 37 | } 38 | return ~0U; 39 | } 40 | -------------------------------------------------------------------------------- /vendor/cmocka/example/assert_macro.h: -------------------------------------------------------------------------------- 1 | const char* get_status_code_string(const unsigned int status_code); 2 | unsigned int string_to_status_code(const char* const status_code_string); 3 | -------------------------------------------------------------------------------- /vendor/cmocka/example/assert_macro_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert_macro.h" 22 | 23 | /* This test will fail since the string returned by get_status_code_string(0) 24 | * doesn't match "Connection timed out". */ 25 | static void get_status_code_string_test(void **state) { 26 | (void) state; /* unused */ 27 | 28 | assert_string_equal(get_status_code_string(0), "Address not found"); 29 | assert_string_equal(get_status_code_string(1), "Connection timed out"); 30 | } 31 | 32 | /* This test will fail since the status code of "Connection timed out" isn't 1 */ 33 | static void string_to_status_code_test(void **state) { 34 | (void) state; /* unused */ 35 | 36 | assert_int_equal(string_to_status_code("Address not found"), 0); 37 | assert_int_equal(string_to_status_code("Connection timed out"), 1); 38 | } 39 | 40 | int main(void) { 41 | const struct CMUnitTest tests[] = { 42 | cmocka_unit_test(get_status_code_string_test), 43 | cmocka_unit_test(string_to_status_code_test), 44 | }; 45 | return cmocka_run_group_tests(tests, NULL, NULL); 46 | } 47 | -------------------------------------------------------------------------------- /vendor/cmocka/example/assert_module.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #include 17 | 18 | #include "assert_module.h" 19 | 20 | /* If unit testing is enabled override assert with mock_assert(). */ 21 | #ifdef UNIT_TESTING 22 | extern void mock_assert(const int result, const char* const expression, 23 | const char * const file, const int line); 24 | #undef assert 25 | #define assert(expression) \ 26 | mock_assert(((expression) ? 1 : 0), #expression, __FILE__, __LINE__); 27 | #endif /* UNIT_TESTING */ 28 | 29 | void increment_value(int * const value) { 30 | assert(value); 31 | (*value) ++; 32 | } 33 | 34 | void decrement_value(int * const value) { 35 | if (value) { 36 | (*value) --; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/cmocka/example/assert_module.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | void increment_value(int * const value); 18 | void decrement_value(int * const value); 19 | -------------------------------------------------------------------------------- /vendor/cmocka/example/assert_module_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert_module.h" 22 | 23 | extern void increment_value(int * const value); 24 | 25 | /* This test case will fail but the assert is caught by run_tests() and the 26 | * next test is executed. */ 27 | static void increment_value_fail(void **state) { 28 | (void) state; 29 | 30 | increment_value(NULL); 31 | } 32 | 33 | /* This test case succeeds since increment_value() asserts on the NULL 34 | * pointer. */ 35 | static void increment_value_assert(void **state) { 36 | (void) state; 37 | 38 | expect_assert_failure(increment_value(NULL)); 39 | } 40 | 41 | /* This test case fails since decrement_value() doesn't assert on a NULL 42 | * pointer. */ 43 | static void decrement_value_fail(void **state) { 44 | (void) state; 45 | 46 | expect_assert_failure(decrement_value(NULL)); 47 | } 48 | 49 | int main(void) { 50 | const struct CMUnitTest tests[] = { 51 | cmocka_unit_test(increment_value_fail), 52 | cmocka_unit_test(increment_value_assert), 53 | cmocka_unit_test(decrement_value_fail), 54 | }; 55 | return cmocka_run_group_tests(tests, NULL, NULL); 56 | } 57 | -------------------------------------------------------------------------------- /vendor/cmocka/example/chef_wrap/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(cmocka-wrap-examples C) 2 | 3 | include_directories( 4 | ${CMAKE_BINARY_DIR} 5 | ${CMAKE_CURRENT_SOURCE_DIR} 6 | ${CMOCKA_PUBLIC_INCLUDE_DIRS} 7 | ) 8 | 9 | add_executable(waiter_test_wrap waiter_test_wrap.c chef.c) 10 | target_link_libraries(waiter_test_wrap ${CMOCKA_SHARED_LIBRARY}) 11 | 12 | add_test(waiter_test_wrap ${CMAKE_CURRENT_BINARY_DIR}/waiter_test_wrap) 13 | 14 | set_target_properties(waiter_test_wrap 15 | PROPERTIES 16 | LINK_FLAGS "-Wl,--wrap=chef_cook" 17 | ) 18 | if (WIN32 OR MINGW OR CYGWIN) 19 | set_tests_properties(waiter_test_wrap PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") 20 | endif (WIN32 OR MINGW OR CYGWIN) 21 | -------------------------------------------------------------------------------- /vendor/cmocka/example/chef_wrap/chef.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 (c) Andreas Schneider 3 | * Jakub Hrozek 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 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "chef.h" 28 | 29 | 30 | /* This is the real chef, just not implemented yet, currently it always 31 | * returns ENOSYS 32 | */ 33 | int chef_cook(const char *order, char **dish_out) 34 | { 35 | if (order == NULL || dish_out == NULL) return EINVAL; 36 | 37 | return -ENOSYS; 38 | } 39 | 40 | /* Print chef return codes as string */ 41 | const char *chef_strerror(int error) 42 | { 43 | switch (error) { 44 | case 0: 45 | return "Success"; 46 | case -1: 47 | return "Unknown dish"; 48 | case -2: 49 | return "Not enough ingredients for the dish"; 50 | } 51 | 52 | return "Unknown error!"; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /vendor/cmocka/example/chef_wrap/chef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 (c) Andreas Schneider 3 | * Jakub Hrozek 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 | */ 17 | 18 | int chef_cook(const char *order, char **dish_out); 19 | const char *chef_strerror(int error); 20 | -------------------------------------------------------------------------------- /vendor/cmocka/example/chef_wrap/waiter_test_wrap.h: -------------------------------------------------------------------------------- 1 | 2 | int __wrap_chef_cook(const char *order, char **dish_out); 3 | -------------------------------------------------------------------------------- /vendor/cmocka/example/customer_database.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #include 17 | #include 18 | #include 19 | #ifdef _WIN32 20 | #define snprintf _snprintf 21 | #endif /* _WIN32 */ 22 | 23 | DatabaseConnection* connect_to_customer_database(void); 24 | unsigned int get_customer_id_by_name( 25 | DatabaseConnection * const connection, 26 | const char * const customer_name); 27 | 28 | /* Connect to the database containing customer information. */ 29 | DatabaseConnection* connect_to_customer_database(void) { 30 | return connect_to_database("customers.abcd.org", 321); 31 | } 32 | 33 | /* Find the ID of a customer by his/her name returning a value > 0 if 34 | * successful, 0 otherwise. */ 35 | unsigned int get_customer_id_by_name( 36 | DatabaseConnection * const connection, 37 | const char * const customer_name) { 38 | char query_string[256]; 39 | int number_of_results; 40 | void **results; 41 | snprintf(query_string, sizeof(query_string), 42 | "SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name); 43 | number_of_results = connection->query_database(connection, query_string, 44 | &results); 45 | 46 | if (number_of_results != 1) { 47 | return -1; 48 | } 49 | 50 | return (unsigned int)*((int *)results); 51 | } 52 | -------------------------------------------------------------------------------- /vendor/cmocka/example/database.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | typedef struct DatabaseConnection DatabaseConnection; 17 | 18 | /* Function that takes an SQL query string and sets results to an array of 19 | * pointers with the result of the query. The value returned specifies the 20 | * number of items in the returned array of results. The returned array of 21 | * results are statically allocated and should not be deallocated using free() 22 | */ 23 | typedef unsigned int (*QueryDatabase)( 24 | DatabaseConnection* const connection, const char * const query_string, 25 | void *** const results); 26 | 27 | /* Connection to a database. */ 28 | struct DatabaseConnection { 29 | const char *url; 30 | unsigned int port; 31 | QueryDatabase query_database; 32 | }; 33 | 34 | /* Connect to a database. */ 35 | DatabaseConnection* connect_to_database(const char * const url, 36 | const unsigned int port); 37 | 38 | -------------------------------------------------------------------------------- /vendor/cmocka/example/key_value.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #include 17 | #include 18 | #include 19 | 20 | #include "key_value.h" 21 | 22 | static KeyValue *key_values = NULL; 23 | static unsigned int number_of_key_values = 0; 24 | 25 | void set_key_values(KeyValue * const new_key_values, 26 | const unsigned int new_number_of_key_values) { 27 | key_values = new_key_values; 28 | number_of_key_values = new_number_of_key_values; 29 | } 30 | 31 | /* Compare two key members of KeyValue structures. */ 32 | static int key_value_compare_keys(const void *a, const void *b) { 33 | return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key; 34 | } 35 | 36 | /* Search an array of key value pairs for the item with the specified value. */ 37 | KeyValue* find_item_by_value(const char * const value) { 38 | unsigned int i; 39 | for (i = 0; i < number_of_key_values; i++) { 40 | if (strcmp(key_values[i].value, value) == 0) { 41 | return &key_values[i]; 42 | } 43 | } 44 | return NULL; 45 | } 46 | 47 | /* Sort an array of key value pairs by key. */ 48 | void sort_items_by_key(void) { 49 | qsort(key_values, number_of_key_values, sizeof(*key_values), 50 | key_value_compare_keys); 51 | } 52 | -------------------------------------------------------------------------------- /vendor/cmocka/example/key_value.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | typedef struct KeyValue { 18 | unsigned int key; 19 | const char* value; 20 | } KeyValue; 21 | 22 | void set_key_values(KeyValue * const new_key_values, 23 | const unsigned int new_number_of_key_values); 24 | 25 | KeyValue* find_item_by_value(const char * const value); 26 | 27 | void sort_items_by_key(void); 28 | -------------------------------------------------------------------------------- /vendor/cmocka/example/key_value_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "key_value.h" 23 | 24 | static KeyValue key_values[] = { 25 | { 10, "this" }, 26 | { 52, "test" }, 27 | { 20, "a" }, 28 | { 13, "is" }, 29 | }; 30 | 31 | static int create_key_values(void **state) { 32 | KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values)); 33 | memcpy(items, key_values, sizeof(key_values)); 34 | *state = (void*)items; 35 | set_key_values(items, sizeof(key_values) / sizeof(key_values[0])); 36 | 37 | return 0; 38 | } 39 | 40 | static int destroy_key_values(void **state) { 41 | test_free(*state); 42 | set_key_values(NULL, 0); 43 | 44 | return 0; 45 | } 46 | 47 | static void test_find_item_by_value(void **state) { 48 | unsigned int i; 49 | 50 | (void) state; /* unused */ 51 | 52 | for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 53 | KeyValue * const found = find_item_by_value(key_values[i].value); 54 | assert_true(found != NULL); 55 | assert_int_equal(found->key, key_values[i].key); 56 | assert_string_equal(found->value, key_values[i].value); 57 | } 58 | } 59 | 60 | static void test_sort_items_by_key(void **state) { 61 | unsigned int i; 62 | KeyValue * const kv = *state; 63 | sort_items_by_key(); 64 | for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) { 65 | assert_true(kv[i - 1].key < kv[i].key); 66 | } 67 | } 68 | 69 | int main(void) { 70 | const struct CMUnitTest tests[] = { 71 | cmocka_unit_test_setup_teardown(test_find_item_by_value, 72 | create_key_values, destroy_key_values), 73 | cmocka_unit_test_setup_teardown(test_sort_items_by_key, 74 | create_key_values, destroy_key_values), 75 | }; 76 | return cmocka_run_group_tests(tests, NULL, NULL); 77 | } 78 | -------------------------------------------------------------------------------- /vendor/cmocka/example/product_database.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | #include 17 | 18 | DatabaseConnection* connect_to_product_database(void); 19 | 20 | /* Connect to the database containing customer information. */ 21 | DatabaseConnection* connect_to_product_database(void) { 22 | return connect_to_database("products.abcd.org", 322); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /vendor/cmocka/example/simple_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* A test case that does nothing and succeeds. */ 7 | static void null_test_success(void **state) { 8 | (void) state; /* unused */ 9 | } 10 | 11 | int main(void) { 12 | const struct CMUnitTest tests[] = { 13 | cmocka_unit_test(null_test_success), 14 | }; 15 | 16 | return cmocka_run_group_tests(tests, NULL, NULL); 17 | } 18 | -------------------------------------------------------------------------------- /vendor/cmocka/include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(cmocka-headers C) 2 | 3 | set(cmocka_HDRS 4 | cmocka.h 5 | cmocka_pbc.h 6 | ) 7 | 8 | install( 9 | FILES 10 | ${cmocka_HDRS} 11 | DESTINATION 12 | ${INCLUDE_INSTALL_DIR} 13 | COMPONENT 14 | headers 15 | ) 16 | 17 | if (WITH_CMOCKERY_SUPPORT) 18 | install( 19 | FILES 20 | cmockery/cmockery.h 21 | cmockery/pbc.h 22 | DESTINATION 23 | ${INCLUDE_INSTALL_DIR}/cmockery 24 | COMPONENT 25 | headers 26 | ) 27 | endif() 28 | -------------------------------------------------------------------------------- /vendor/cmocka/include/cmocka_pbc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Luis Pabon, Jr. 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 | * Programming by Contract is a programming methodology 19 | * which binds the caller and the function called to a 20 | * contract. The contract is represented using Hoare Triple: 21 | * {P} C {Q} 22 | * where {P} is the precondition before executing command C, 23 | * and {Q} is the postcondition. 24 | * 25 | * See also: 26 | * http://en.wikipedia.org/wiki/Design_by_contract 27 | * http://en.wikipedia.org/wiki/Hoare_logic 28 | * http://dlang.org/dbc.html 29 | */ 30 | #ifndef CMOCKA_PBC_H_ 31 | #define CMOCKA_PBC_H_ 32 | 33 | #if defined(UNIT_TESTING) || defined (DEBUG) 34 | 35 | #include 36 | 37 | /* 38 | * Checks caller responsibility against contract 39 | */ 40 | #define REQUIRE(cond) assert(cond) 41 | 42 | /* 43 | * Checks function reponsability against contract. 44 | */ 45 | #define ENSURE(cond) assert(cond) 46 | 47 | /* 48 | * While REQUIRE and ENSURE apply to functions, INVARIANT 49 | * applies to classes/structs. It ensures that intances 50 | * of the class/struct are consistent. In other words, 51 | * that the instance has not been corrupted. 52 | */ 53 | #define INVARIANT(invariant_fnc) do{ (invariant_fnc) } while (0); 54 | 55 | #else 56 | #define REQUIRE(cond) do { } while (0); 57 | #define ENSURE(cond) do { } while (0); 58 | #define INVARIANT(invariant_fnc) do{ } while (0); 59 | 60 | #endif /* defined(UNIT_TESTING) || defined (DEBUG) */ 61 | #endif /* CMOCKA_PBC_H_ */ 62 | 63 | -------------------------------------------------------------------------------- /vendor/cmocka/include/cmockery/cmockery.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /vendor/cmocka/include/cmockery/pbc.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /vendor/cmocka/src/cmocka.def: -------------------------------------------------------------------------------- 1 | LIBRARY cmocka 2 | EXPORTS 3 | _assert_in_range 4 | _assert_in_set 5 | _assert_int_equal 6 | _assert_int_not_equal 7 | _assert_memory_equal 8 | _assert_memory_not_equal 9 | _assert_not_in_range 10 | _assert_not_in_set 11 | _assert_return_code 12 | _assert_string_equal 13 | _assert_string_not_equal 14 | _assert_true 15 | _check_expected 16 | _cmocka_run_group_tests 17 | _expect_any 18 | _expect_check 19 | _expect_function_call 20 | _expect_in_range 21 | _expect_in_set 22 | _expect_memory 23 | _expect_not_in_range 24 | _expect_not_in_set 25 | _expect_not_memory 26 | _expect_not_string 27 | _expect_not_value 28 | _expect_string 29 | _expect_value 30 | _fail 31 | _function_called 32 | _mock 33 | _run_test 34 | _run_tests 35 | _skip 36 | _test_calloc 37 | _test_free 38 | _test_malloc 39 | _test_realloc 40 | _will_return 41 | cmocka_set_message_output 42 | global_expect_assert_env 43 | global_expecting_assert 44 | global_last_failed_assert 45 | mock_assert 46 | print_error 47 | print_message 48 | vprint_error 49 | vprint_message 50 | -------------------------------------------------------------------------------- /vendor/cmocka/test_ordering_fail.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static void mock_test_a_called(void) 10 | { 11 | function_called(); 12 | } 13 | 14 | static void mock_test_b_called(void) 15 | { 16 | function_called(); 17 | } 18 | 19 | static void mock_test_c_called(void) 20 | { 21 | function_called(); 22 | } 23 | 24 | static void test_does_fail_for_unexpected_call(void **state) 25 | { 26 | (void)state; 27 | expect_function_call(mock_test_a_called); 28 | expect_function_call(mock_test_a_called); 29 | 30 | mock_test_a_called(); 31 | mock_test_a_called(); 32 | mock_test_a_called(); 33 | } 34 | 35 | static void test_does_fail_for_unmade_expected_call(void **state) 36 | { 37 | (void)state; 38 | expect_function_call(mock_test_a_called); 39 | expect_function_call(mock_test_a_called); 40 | 41 | mock_test_a_called(); 42 | } 43 | 44 | static void test_ordering_fails_out_of_order(void **state) 45 | { 46 | (void)state; 47 | expect_function_call(mock_test_a_called); 48 | expect_function_call(mock_test_b_called); 49 | expect_function_call(mock_test_a_called); 50 | 51 | mock_test_b_called(); 52 | } 53 | 54 | static void test_ordering_fails_out_of_order_for_at_least_once_calls(void **state) 55 | { 56 | (void)state; 57 | expect_function_call_any(mock_test_a_called); 58 | ignore_function_calls(mock_test_b_called); 59 | 60 | mock_test_b_called(); 61 | mock_test_c_called(); 62 | } 63 | 64 | /* Primarily used to test error message */ 65 | static void test_fails_out_of_order_if_no_calls_found_on_any(void **state) 66 | { 67 | (void)state; 68 | expect_function_call_any(mock_test_a_called); 69 | ignore_function_calls(mock_test_b_called); 70 | 71 | mock_test_a_called(); 72 | mock_test_c_called(); 73 | } 74 | 75 | static void test_fails_if_zero_count_used(void **state) 76 | { 77 | (void)state; 78 | expect_function_calls(mock_test_a_called, 0); 79 | 80 | mock_test_a_called(); 81 | } 82 | 83 | int main(void) { 84 | const struct CMUnitTest tests[] = { 85 | cmocka_unit_test(test_does_fail_for_unexpected_call) 86 | ,cmocka_unit_test(test_does_fail_for_unmade_expected_call) 87 | ,cmocka_unit_test(test_does_fail_for_unmade_expected_call) 88 | ,cmocka_unit_test(test_ordering_fails_out_of_order) 89 | ,cmocka_unit_test(test_ordering_fails_out_of_order_for_at_least_once_calls) 90 | ,cmocka_unit_test(test_fails_out_of_order_if_no_calls_found_on_any) 91 | ,cmocka_unit_test(test_fails_if_zero_count_used) 92 | }; 93 | 94 | return cmocka_run_group_tests(tests, NULL, NULL); 95 | } 96 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/ctest-default.cmake: -------------------------------------------------------------------------------- 1 | ## The directory to run ctest in. 2 | set(CTEST_DIRECTORY "$ENV{HOME}/workspace/tmp/dashboards/cmocka") 3 | 4 | ## The hostname of the machine 5 | set(CTEST_SITE "host.cmocka.org") 6 | ## The buildname 7 | set(CTEST_BUILD_NAME "Linux_GCC_x86_64_default") 8 | 9 | ## The Makefile generator to use 10 | set(CTEST_CMAKE_GENERATOR "Unix Makefiles") 11 | 12 | ## The Build configuration to use. 13 | set(CTEST_BUILD_CONFIGURATION "Debug") 14 | 15 | ## The build options for the project 16 | set(CTEST_BUILD_OPTIONS "-DUNIT_TESTING=ON -DWITH_CMOCKERY_SUPPORT=ON") 17 | 18 | #set(CTEST_CUSTOM_MEMCHECK_IGNORE torture_rand) 19 | 20 | ## The Model to set: Nightly, Continous, Experimental 21 | set(CTEST_MODEL "Experimental") 22 | 23 | ## The URL to the git repository 24 | set(CTEST_GIT_REPOSITORY "git://git.cryptomilk.org/projects/cmocka.git") 25 | 26 | ## The branch 27 | #set(CTEST_GIT_BRANCH "--branch v0-5") 28 | 29 | ## Wether to enable memory checking. 30 | set(WITH_MEMCHECK FALSE) 31 | 32 | ## Wether to enable code coverage. 33 | set(WITH_COVERAGE FALSE) 34 | 35 | ####################################################################### 36 | 37 | if (WITH_COVERAGE AND NOT WIN32) 38 | set(CTEST_BUILD_CONFIGURATION "Profiling") 39 | endif (WITH_COVERAGE AND NOT WIN32) 40 | 41 | set(CTEST_SOURCE_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/source") 42 | set(CTEST_BINARY_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/build") 43 | 44 | set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/valgrind.supp) 45 | 46 | find_program(CTEST_GIT_COMMAND NAMES git) 47 | find_program(CTEST_COVERAGE_COMMAND NAMES gcov) 48 | find_program(CTEST_MEMORYCHECK_COMMAND NAMES valgrind) 49 | 50 | if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}") 51 | set(CTEST_CHECKOUT_COMMAND "${CTEST_GIT_COMMAND} clone ${CTEST_GIT_BRANCH} ${CTEST_GIT_REPOSITORY} ${CTEST_SOURCE_DIRECTORY}") 52 | endif() 53 | 54 | set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}") 55 | 56 | set(CTEST_CONFIGURE_COMMAND "${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}") 57 | set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} ${CTEST_BUILD_OPTIONS}") 58 | set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} \"-G${CTEST_CMAKE_GENERATOR}\"") 59 | set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} \"${CTEST_SOURCE_DIRECTORY}\"") 60 | 61 | ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) 62 | 63 | ctest_start(${CTEST_MODEL} TRACK ${CTEST_MODEL}) 64 | ctest_update(SOURCE ${CTEST_SOURCE_DIRECTORY}) 65 | ctest_configure(BUILD ${CTEST_BINARY_DIRECTORY}) 66 | ctest_build(BUILD ${CTEST_BINARY_DIRECTORY}) 67 | ctest_test(BUILD ${CTEST_BINARY_DIRECTORY}) 68 | if (WITH_MEMCHECK AND CTEST_COVERAGE_COMMAND) 69 | ctest_coverage(BUILD ${CTEST_BINARY_DIRECTORY}) 70 | endif (WITH_MEMCHECK AND CTEST_COVERAGE_COMMAND) 71 | if (WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) 72 | ctest_memcheck(BUILD ${CTEST_BINARY_DIRECTORY}) 73 | endif (WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) 74 | ctest_submit() 75 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_alloc.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | static void torture_test_malloc(void **state) 14 | { 15 | char *str; 16 | size_t str_len; 17 | size_t len; 18 | 19 | (void)state; /* unsused */ 20 | 21 | str_len = 12; 22 | str = (char *)test_malloc(str_len); 23 | assert_non_null(str); 24 | 25 | len = snprintf(str, str_len, "test string"); 26 | assert_int_equal(len, 11); 27 | 28 | len = strlen(str); 29 | assert_int_equal(len, 11); 30 | 31 | test_free(str); 32 | } 33 | 34 | static void torture_test_realloc(void **state) 35 | { 36 | char *str; 37 | char *tmp; 38 | size_t str_len; 39 | size_t len; 40 | 41 | (void)state; /* unsused */ 42 | 43 | str_len = 16; 44 | str = (char *)test_malloc(str_len); 45 | assert_non_null(str); 46 | 47 | len = snprintf(str, str_len, "test string 123"); 48 | assert_int_equal(len, 15); 49 | 50 | len = strlen(str); 51 | assert_int_equal(len, 15); 52 | 53 | str_len = 20; 54 | tmp = test_realloc(str, str_len); 55 | assert_non_null(tmp); 56 | 57 | str = tmp; 58 | len = strlen(str); 59 | assert_string_equal(tmp, "test string 123"); 60 | 61 | snprintf(str + len, str_len - len, "4567"); 62 | assert_string_equal(tmp, "test string 1234567"); 63 | 64 | test_free(str); 65 | } 66 | 67 | static void torture_test_realloc_set0(void **state) 68 | { 69 | char *str; 70 | size_t str_len; 71 | 72 | (void)state; /* unsused */ 73 | 74 | str_len = 16; 75 | str = (char *)test_malloc(str_len); 76 | assert_non_null(str); 77 | 78 | /* realloc(ptr, 0) is like a free() */ 79 | str = (char *)test_realloc(str, 0); 80 | assert_null(str); 81 | } 82 | 83 | int main(void) { 84 | const struct CMUnitTest alloc_tests[] = { 85 | cmocka_unit_test(torture_test_malloc), 86 | cmocka_unit_test(torture_test_realloc), 87 | cmocka_unit_test(torture_test_realloc_set0), 88 | }; 89 | 90 | return cmocka_run_group_tests(alloc_tests, NULL, NULL); 91 | } 92 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_assert_macros.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #ifdef HAVE_UNISTD_H 13 | #include 14 | #endif 15 | #include 16 | 17 | /************************************** 18 | *** assert_return_code 19 | **************************************/ 20 | static void test_assert_return_code(void **state) 21 | { 22 | struct stat sb; 23 | int rc; 24 | 25 | (void)state; /* unused */ 26 | 27 | rc = stat(".", &sb); 28 | assert_return_code(rc, 0); 29 | 30 | #ifndef _MSC_VER 31 | assert_true(S_ISDIR(sb.st_mode)); 32 | #endif 33 | } 34 | 35 | int main(void) { 36 | const struct CMUnitTest tests[] = { 37 | cmocka_unit_test(test_assert_return_code), 38 | }; 39 | 40 | return cmocka_run_group_tests(tests, NULL, NULL); 41 | } 42 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_assert_macros_fail.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #ifdef HAVE_UNISTD_H 13 | #include 14 | #endif 15 | #ifdef HAVE_IO_H 16 | #include 17 | #endif 18 | #include 19 | 20 | /************************************** 21 | *** assert_return_code 22 | **************************************/ 23 | static void test_assert_return_code_fail(void **state) 24 | { 25 | int fd; 26 | 27 | (void)state; /* unused */ 28 | 29 | fd = open("this_file_doesnt_exist.cmocka", 0); 30 | assert_return_code(fd, errno); 31 | 32 | if (fd >= 0) { 33 | close(fd); 34 | } 35 | } 36 | 37 | int main(void) { 38 | const struct CMUnitTest tests[] = { 39 | cmocka_unit_test(test_assert_return_code_fail), 40 | }; 41 | 42 | return cmocka_run_group_tests(tests, NULL, NULL); 43 | } 44 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_basics.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 | /* Use the unit test allocators */ 18 | #define UNIT_TESTING 1 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | static int setup(void **state) { 26 | int *answer = malloc(sizeof(int)); 27 | 28 | assert_non_null(answer); 29 | *answer = 42; 30 | 31 | *state = answer; 32 | 33 | return 0; 34 | } 35 | 36 | static int teardown(void **state) { 37 | free(*state); 38 | 39 | return 0; 40 | } 41 | 42 | /* A test case that does nothing and succeeds. */ 43 | static void null_test_success(void **state) { 44 | (void) state; 45 | } 46 | 47 | /* A test case that does check if an int is equal. */ 48 | static void int_test_success(void **state) { 49 | int *answer = *state; 50 | 51 | assert_int_equal(*answer, 42); 52 | } 53 | 54 | 55 | int main(void) { 56 | const struct CMUnitTest tests[] = { 57 | cmocka_unit_test(null_test_success), 58 | cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), 59 | }; 60 | 61 | return cmocka_run_group_tests(tests, NULL, NULL); 62 | } 63 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_cmockery.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 18 | #include 19 | #include 20 | #include 21 | 22 | /* A test case that does nothing and succeeds. */ 23 | static void null_test_success(void **state) { 24 | (void) state; /* unused */ 25 | } 26 | 27 | int main(void) { 28 | const UnitTest tests[] = { 29 | unit_test(null_test_success), 30 | }; 31 | return run_tests(tests); 32 | } 33 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_exception_handler.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | struct test_segv { 9 | int x; 10 | int y; 11 | }; 12 | 13 | static void test_segfault_recovery(void **state) 14 | { 15 | struct test_segv *s = NULL; 16 | 17 | (void) state; /* unused */ 18 | 19 | s->x = 1; 20 | } 21 | 22 | int main(void) { 23 | const struct CMUnitTest tests[] = { 24 | cmocka_unit_test(test_segfault_recovery), 25 | cmocka_unit_test(test_segfault_recovery), 26 | cmocka_unit_test(test_segfault_recovery), 27 | }; 28 | 29 | return cmocka_run_group_tests(tests, NULL, NULL); 30 | } 31 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_fixtures.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | static int setup_only(void **state) 9 | { 10 | *state = malloc(1); 11 | 12 | return 0; 13 | } 14 | 15 | static int teardown_only(void **state) 16 | { 17 | free(*state); 18 | 19 | return 0; 20 | } 21 | 22 | static void malloc_setup_test(void **state) 23 | { 24 | assert_non_null(*state); 25 | free(*state); 26 | } 27 | 28 | static void malloc_teardown_test(void **state) 29 | { 30 | *state = malloc(1); 31 | assert_non_null(*state); 32 | } 33 | 34 | static int prestate_setup(void **state) 35 | { 36 | int *val = (int *)*state, *a; 37 | 38 | a = malloc(sizeof(int)); 39 | *a = *val + 1; 40 | *state = a; 41 | 42 | return 0; 43 | } 44 | 45 | static int prestate_teardown(void **state) 46 | { 47 | free(*state); 48 | 49 | return 0; 50 | } 51 | 52 | static void prestate_setup_test(void **state) 53 | { 54 | int *a = (int *)*state; 55 | 56 | assert_non_null(a); 57 | assert_int_equal(*a, 43); 58 | } 59 | 60 | static void prestate_test(void **state) 61 | { 62 | int *a = (int *)*state; 63 | 64 | assert_non_null(a); 65 | assert_int_equal(*a, 42); 66 | } 67 | 68 | int main(void) { 69 | int prestate = 42; 70 | const struct CMUnitTest tests[] = { 71 | cmocka_unit_test_setup(malloc_setup_test, setup_only), 72 | cmocka_unit_test_setup(malloc_setup_test, setup_only), 73 | cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), 74 | cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), 75 | cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), 76 | cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), 77 | cmocka_unit_test_prestate(prestate_test, &prestate), 78 | cmocka_unit_test_prestate_setup_teardown(prestate_setup_test, prestate_setup, prestate_teardown, &prestate), 79 | }; 80 | 81 | return cmocka_run_group_tests(tests, NULL, NULL); 82 | } 83 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_group_fixtures.c: -------------------------------------------------------------------------------- 1 | /* Use the unit test allocators */ 2 | #define UNIT_TESTING 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static int group_setup(void **state) 10 | { 11 | int *answer = malloc(sizeof(int)); 12 | assert_non_null(answer); 13 | *answer = 42; 14 | 15 | *state = answer; 16 | return 0; 17 | } 18 | 19 | static int group_teardown(void **state) 20 | { 21 | int *answer = (int *)*state; 22 | 23 | free(answer); 24 | return 0; 25 | } 26 | 27 | static void test_value_equal(void **state) 28 | { 29 | int a = *((int *)*state); 30 | 31 | assert_int_equal(a, 42); 32 | } 33 | 34 | static void test_value_range(void **state) 35 | { 36 | int a = *((int *)*state); 37 | 38 | assert_in_range(a, 0, 100); 39 | } 40 | 41 | int main(void) { 42 | int prestate = 1337; 43 | const struct CMUnitTest tests[] = { 44 | cmocka_unit_test(test_value_equal), 45 | cmocka_unit_test(test_value_range), 46 | cmocka_unit_test_prestate(test_value_equal, &prestate), 47 | }; 48 | 49 | return cmocka_run_group_tests(tests, group_setup, group_teardown); 50 | } 51 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_group_setup_assert.c: -------------------------------------------------------------------------------- 1 | /* Use the unit test allocators */ 2 | #define UNIT_TESTING 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static int group_setup_failing(void **state) 10 | { 11 | (void) state; /* unused */ 12 | 13 | assert_int_equal(0, 1); 14 | 15 | return 0; 16 | } 17 | 18 | static void test_true(void **state) 19 | { 20 | (void) state; /* unused */ 21 | assert_true(1); 22 | } 23 | 24 | static void test_false(void **state) 25 | { 26 | (void) state; /* unused */ 27 | assert_false(0); 28 | } 29 | 30 | int main(void) { 31 | const struct CMUnitTest tests[] = { 32 | cmocka_unit_test(test_true), 33 | cmocka_unit_test(test_false), 34 | }; 35 | 36 | return cmocka_run_group_tests(tests, group_setup_failing, NULL); 37 | } 38 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_group_setup_fail.c: -------------------------------------------------------------------------------- 1 | /* Use the unit test allocators */ 2 | #define UNIT_TESTING 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static int group_setup_failing(void **state) 10 | { 11 | (void) state; /* unused */ 12 | return 1; /* To indicate the failure */ 13 | } 14 | 15 | static void test_true(void **state) 16 | { 17 | (void) state; /* unused */ 18 | assert_true(1); 19 | } 20 | 21 | static void test_false(void **state) 22 | { 23 | (void) state; /* unused */ 24 | assert_false(0); 25 | } 26 | 27 | int main(void) { 28 | const struct CMUnitTest tests[] = { 29 | cmocka_unit_test(test_true), 30 | cmocka_unit_test(test_false), 31 | }; 32 | 33 | return cmocka_run_group_tests(tests, group_setup_failing, NULL); 34 | } 35 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_groups.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 David Schneider 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 | /* Use the unit test allocators */ 18 | #define UNIT_TESTING 1 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | static int setup(void **state) { 26 | int *answer = malloc(sizeof(int)); 27 | 28 | assert_non_null(answer); 29 | *answer = 42; 30 | 31 | *state = answer; 32 | 33 | return 0; 34 | } 35 | 36 | static int teardown(void **state) { 37 | free(*state); 38 | 39 | return 0; 40 | } 41 | 42 | /* A test case that does nothing and succeeds. */ 43 | static void null_test_success(void **state) { 44 | (void) state; 45 | } 46 | 47 | /* A test case that does check if an int is equal. */ 48 | static void int_test_success(void **state) { 49 | int *answer = *state; 50 | 51 | assert_int_equal(*answer, 42); 52 | } 53 | 54 | 55 | int main(void) { 56 | const struct CMUnitTest test_group1[] = { 57 | cmocka_unit_test(null_test_success), 58 | }; 59 | 60 | const struct CMUnitTest test_group2[] = { 61 | cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), 62 | }; 63 | 64 | int result = 0; 65 | result += cmocka_run_group_tests(test_group1, NULL, NULL); 66 | result += cmocka_run_group_tests(test_group2, NULL, NULL); 67 | 68 | return result; 69 | } 70 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_ordering_fail.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static void mock_test_a_called(void) 10 | { 11 | function_called(); 12 | } 13 | 14 | static void mock_test_b_called(void) 15 | { 16 | function_called(); 17 | } 18 | 19 | static void mock_test_c_called(void) 20 | { 21 | function_called(); 22 | } 23 | 24 | static void test_does_fail_for_unexpected_call(void **state) 25 | { 26 | (void)state; 27 | expect_function_call(mock_test_a_called); 28 | expect_function_call(mock_test_a_called); 29 | 30 | mock_test_a_called(); 31 | mock_test_a_called(); 32 | mock_test_a_called(); 33 | } 34 | 35 | static void test_does_fail_for_unmade_expected_call(void **state) 36 | { 37 | (void)state; 38 | expect_function_call(mock_test_a_called); 39 | expect_function_call(mock_test_a_called); 40 | 41 | mock_test_a_called(); 42 | } 43 | 44 | static void test_ordering_fails_out_of_order(void **state) 45 | { 46 | (void)state; 47 | expect_function_call(mock_test_a_called); 48 | expect_function_call(mock_test_b_called); 49 | expect_function_call(mock_test_a_called); 50 | 51 | mock_test_b_called(); 52 | } 53 | 54 | static void test_ordering_fails_out_of_order_for_at_least_once_calls(void **state) 55 | { 56 | (void)state; 57 | expect_function_call_any(mock_test_a_called); 58 | ignore_function_calls(mock_test_b_called); 59 | 60 | mock_test_b_called(); 61 | mock_test_c_called(); 62 | } 63 | 64 | /* Primarily used to test error message */ 65 | static void test_fails_out_of_order_if_no_calls_found_on_any(void **state) 66 | { 67 | (void)state; 68 | expect_function_call_any(mock_test_a_called); 69 | ignore_function_calls(mock_test_b_called); 70 | 71 | mock_test_a_called(); 72 | mock_test_c_called(); 73 | } 74 | 75 | static void test_fails_if_zero_count_used(void **state) 76 | { 77 | (void)state; 78 | expect_function_calls(mock_test_a_called, 0); 79 | 80 | mock_test_a_called(); 81 | } 82 | 83 | int main(void) { 84 | const struct CMUnitTest tests[] = { 85 | cmocka_unit_test(test_does_fail_for_unexpected_call) 86 | ,cmocka_unit_test(test_does_fail_for_unmade_expected_call) 87 | ,cmocka_unit_test(test_does_fail_for_unmade_expected_call) 88 | ,cmocka_unit_test(test_ordering_fails_out_of_order) 89 | ,cmocka_unit_test(test_ordering_fails_out_of_order_for_at_least_once_calls) 90 | ,cmocka_unit_test(test_fails_out_of_order_if_no_calls_found_on_any) 91 | ,cmocka_unit_test(test_fails_if_zero_count_used) 92 | }; 93 | 94 | return cmocka_run_group_tests(tests, NULL, NULL); 95 | } 96 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_returns.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | int mock_function(void); 12 | void mock_function_call_times(size_t times, int expectedValue); 13 | 14 | int mock_function(void) 15 | { 16 | return (int) mock(); 17 | } 18 | 19 | void mock_function_call_times(size_t times, int expectedValue) 20 | { 21 | size_t i; 22 | for (i = 0u; i < times; ++i) 23 | { 24 | assert_int_equal(expectedValue, mock_function()); 25 | } 26 | } 27 | 28 | static void test_will_return_maybe_for_no_calls(void **state) 29 | { 30 | (void) state; 31 | 32 | will_return_maybe(mock_function, 32); 33 | } 34 | 35 | static void test_will_return_maybe_for_one_mock_call(void **state) 36 | { 37 | int value; 38 | 39 | (void) state; 40 | 41 | value = rand(); 42 | will_return_maybe(mock_function, value); 43 | mock_function_call_times(1u, value); 44 | } 45 | 46 | static void test_will_return_maybe_for_more_than_one_call(void **state) 47 | { 48 | int value; 49 | size_t numberOfCalls; 50 | (void)state; 51 | 52 | value = rand(); 53 | numberOfCalls = (size_t) ((rand()) % 20 + 2); 54 | will_return_maybe(mock_function, value); 55 | mock_function_call_times(numberOfCalls, value); 56 | } 57 | 58 | int main(int argc, char **argv) { 59 | const struct CMUnitTest alloc_tests[] = { 60 | cmocka_unit_test(test_will_return_maybe_for_no_calls) 61 | ,cmocka_unit_test(test_will_return_maybe_for_one_mock_call) 62 | ,cmocka_unit_test(test_will_return_maybe_for_more_than_one_call) 63 | }; 64 | 65 | (void)argc; 66 | (void)argv; 67 | 68 | return cmocka_run_group_tests(alloc_tests, NULL, NULL); 69 | } 70 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_returns_fail.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | int mock_function(void); 12 | void mock_function_call_times(size_t times, int expectedValue); 13 | 14 | int mock_function(void) 15 | { 16 | return (int) mock(); 17 | } 18 | 19 | void mock_function_call_times(size_t times, int expectedValue) 20 | { 21 | size_t i; 22 | for (i = 0u; i < times; ++i) 23 | { 24 | assert_int_equal(expectedValue, mock_function()); 25 | } 26 | } 27 | 28 | static void test_will_return_fails_for_no_calls(void **state) 29 | { 30 | (void) state; 31 | 32 | will_return(mock_function, 32); 33 | } 34 | 35 | static void test_will_return_count_fails_for_unreturned_items(void **state) 36 | { 37 | int value; 38 | size_t numberOfCalls; 39 | 40 | (void) state; 41 | 42 | value = rand(); 43 | numberOfCalls = (size_t) ((rand()) % 20 + 2); 44 | 45 | will_return_count(mock_function, value, numberOfCalls); 46 | mock_function_call_times(numberOfCalls - 1u, value); 47 | } 48 | 49 | static void test_will_return_always_fails_for_no_calls(void **state) 50 | { 51 | int value; 52 | 53 | (void) state; 54 | 55 | value = rand(); 56 | 57 | will_return_always(mock_function, value); 58 | } 59 | 60 | static int teardown(void **state) { 61 | free(*state); 62 | 63 | return 0; 64 | } 65 | 66 | int main(int argc, char **argv) { 67 | const struct CMUnitTest alloc_tests[] = { 68 | cmocka_unit_test_teardown(test_will_return_fails_for_no_calls, teardown) 69 | ,cmocka_unit_test_teardown(test_will_return_count_fails_for_unreturned_items, teardown) 70 | ,cmocka_unit_test_teardown(test_will_return_always_fails_for_no_calls, teardown) 71 | }; 72 | 73 | (void)argc; 74 | (void)argv; 75 | 76 | return cmocka_run_group_tests(alloc_tests, NULL, NULL); 77 | } 78 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_setup_fail.c: -------------------------------------------------------------------------------- 1 | #define UNIT_TESTING 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | static int setup_fail(void **state) { 9 | *state = NULL; 10 | 11 | /* We need to fail in setup */ 12 | return -1; 13 | } 14 | 15 | static void int_test_ignored(void **state) { 16 | /* should not be called */ 17 | assert_non_null(*state); 18 | } 19 | 20 | static int setup_ok(void **state) { 21 | int *answer; 22 | 23 | answer = malloc(sizeof(int)); 24 | if (answer == NULL) { 25 | return -1; 26 | } 27 | *answer = 42; 28 | 29 | *state = answer; 30 | 31 | return 0; 32 | } 33 | 34 | /* A test case that does check if an int is equal. */ 35 | static void int_test_success(void **state) { 36 | int *answer = *state; 37 | 38 | assert_int_equal(*answer, 42); 39 | } 40 | 41 | static int teardown(void **state) { 42 | free(*state); 43 | 44 | return 0; 45 | } 46 | 47 | int main(void) { 48 | const struct CMUnitTest tests[] = { 49 | cmocka_unit_test_setup_teardown(int_test_ignored, setup_fail, teardown), 50 | cmocka_unit_test_setup_teardown(int_test_success, setup_ok, teardown), 51 | }; 52 | 53 | return cmocka_run_group_tests(tests, NULL, NULL); 54 | } 55 | -------------------------------------------------------------------------------- /vendor/cmocka/tests/test_skip.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2008 Google 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 18 | #include 19 | #include 20 | #include 21 | 22 | /* A test case that does check if an int is equal. */ 23 | static void test_check_skip(void **state) { 24 | (void)state; /* unused */ 25 | 26 | skip(); 27 | 28 | assert_true(0); 29 | } 30 | 31 | 32 | int main(void) { 33 | const struct CMUnitTest tests[] = { 34 | cmocka_unit_test(test_check_skip), 35 | }; 36 | 37 | return cmocka_run_group_tests(tests, NULL, NULL); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | 0.5.6 2 | -------------------------------------------------------------------------------- /wrappers/mbed/default_sm.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2021 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #include "default_sm.h" 23 | 24 | using namespace LDL; 25 | 26 | /* constructors *******************************************************/ 27 | 28 | 29 | DefaultSM::DefaultSM(const void *app_key) 30 | { 31 | #if defined(LDL_ENABLE_L2_1_1) 32 | LDL_SM_init(&state, app_key, app_key); 33 | #else 34 | LDL_SM_init(&state, app_key); 35 | #endif 36 | } 37 | 38 | DefaultSM::DefaultSM(const void *app_key, const void *nwk_key) 39 | { 40 | #if defined(LDL_ENABLE_L2_1_1) 41 | LDL_SM_init(&state, app_key, nwk_key); 42 | #else 43 | LDL_SM_init(&state, nwk_key); 44 | #endif 45 | } 46 | 47 | /* protected static ***************************************************/ 48 | 49 | 50 | /* protected **********************************************************/ 51 | 52 | void 53 | DefaultSM::update_session_key(enum ldl_sm_key key_desc, enum ldl_sm_key root_desc, const void *iv) 54 | { 55 | LDL_SM_updateSessionKey(&state, key_desc, root_desc, iv); 56 | } 57 | 58 | uint32_t 59 | DefaultSM::mic(enum ldl_sm_key desc, const void *hdr, uint8_t hdrLen, const void *data, uint8_t dataLen) 60 | { 61 | return LDL_SM_mic(&state, desc, hdr, hdrLen, data, dataLen); 62 | } 63 | 64 | void 65 | DefaultSM::ecb(enum ldl_sm_key desc, void *b) 66 | { 67 | LDL_SM_ecb(&state, desc, b); 68 | } 69 | 70 | void 71 | DefaultSM::ctr(enum ldl_sm_key desc, const void *iv, void *data, uint8_t len) 72 | { 73 | LDL_SM_ctr(&state, desc, iv, data, len); 74 | } 75 | 76 | -------------------------------------------------------------------------------- /wrappers/mbed/default_sm.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef MBED_LDL_DEFAULT_SM_H 23 | #define MBED_LDL_DEFAULT_SM_H 24 | 25 | #include "sm.h" 26 | 27 | namespace LDL { 28 | 29 | /** 30 | * A default Security Module suitable for demo apps. 31 | * 32 | * Uses the default LDL cryptographic implementation and takes 33 | * pointers to the root keys on construction. 34 | * 35 | * */ 36 | class DefaultSM : public SM { 37 | 38 | protected: 39 | 40 | struct ldl_sm state; 41 | 42 | void update_session_key(enum ldl_sm_key key_desc, enum ldl_sm_key root_desc, const void *iv); 43 | uint32_t mic(enum ldl_sm_key desc, const void *hdr, uint8_t hdrLen, const void *data, uint8_t dataLen); 44 | void ecb(enum ldl_sm_key desc, void *b); 45 | void ctr(enum ldl_sm_key desc, const void *iv, void *data, uint8_t len); 46 | 47 | public: 48 | 49 | DefaultSM(const void *app_key); 50 | DefaultSM(const void *app_key, const void *nwk_key); 51 | }; 52 | 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /wrappers/mbed/hw/readme.md: -------------------------------------------------------------------------------- 1 | Plug-and-Play Hardware Variants 2 | =============================== 3 | 4 | In this directory there are radio classes that implement pin mappings 5 | and special IO handling for commonly available hardware variants. 6 | 7 | - MBED enabled shields 8 | - SX1272MB2XAS 9 | - SX1261MB2XAS 10 | - SX1262MB2XAS 11 | - CMWX1ZZABZ: works in any design that uses this module 12 | -------------------------------------------------------------------------------- /wrappers/mbed/mbed_ldl.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef MBED_LDL_H 23 | #define MBED_LDL_H 24 | 25 | #include "mac.h" 26 | #include "_device.h" 27 | 28 | #include "default_store.h" 29 | #include "default_sm.h" 30 | 31 | #include "sx1272.h" 32 | #include "sx1276.h" 33 | #include "sx126x.h" 34 | #include "wl55.h" 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /wrappers/mbed/mbed_ldl_port.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "mbed.h" 4 | 5 | #include "mbed_ldl_port.h" 6 | 7 | #ifdef MBED_CONF_LDL_ENABLE_VERBOSE_DEBUG 8 | static char buffer[1024]; 9 | static size_t pos; 10 | #endif 11 | 12 | static Mutex mutex; 13 | 14 | void my_trace_begin(void) 15 | { 16 | #ifdef MBED_CONF_LDL_ENABLE_VERBOSE_DEBUG 17 | my_trace_lock(); 18 | buffer[0] = 0; 19 | pos = 0U; 20 | #endif 21 | } 22 | 23 | void my_trace_lock(void) 24 | { 25 | mutex.lock(); 26 | } 27 | 28 | void my_trace_unlock(void) 29 | { 30 | mutex.unlock(); 31 | } 32 | 33 | void my_trace_part(const char *fmt, ...) 34 | { 35 | #ifdef MBED_CONF_LDL_ENABLE_VERBOSE_DEBUG 36 | va_list args; 37 | va_start(args, fmt); 38 | int retval; 39 | 40 | retval = vsnprintf(&buffer[pos], sizeof(buffer)-pos, fmt, args); 41 | 42 | va_end(args); 43 | 44 | pos += (retval > 0) ? retval : 0U; 45 | #endif 46 | } 47 | 48 | void my_trace_hex(const uint8_t *ptr, size_t len) 49 | { 50 | #ifdef MBED_CONF_LDL_ENABLE_VERBOSE_DEBUG 51 | int retval; 52 | size_t i; 53 | 54 | for(i=0U; i < len; i++){ 55 | 56 | /* printf fmt wasn't doing this for me */ 57 | retval = snprintf(&buffer[pos], sizeof(buffer)-pos, "%X%X", 58 | ptr[i] >> 4, 59 | ptr[i] 60 | ); 61 | 62 | pos += (retval > 0) ? retval : 0U; 63 | } 64 | #endif 65 | } 66 | 67 | void my_trace_bitstring(const uint8_t *ptr, size_t len) 68 | { 69 | #ifdef MBED_CONF_LDL_ENABLE_VERBOSE_DEBUG 70 | int retval; 71 | size_t i; 72 | 73 | for(i=0U; i < len; i++){ 74 | 75 | retval = snprintf(&buffer[pos], sizeof(buffer)-pos, "%u%u%u%u%u%u%u%u", 76 | (ptr[i] >> 7) & 1U, 77 | (ptr[i] >> 6) & 1U, 78 | (ptr[i] >> 5) & 1U, 79 | (ptr[i] >> 4) & 1U, 80 | (ptr[i] >> 3) & 1U, 81 | (ptr[i] >> 2) & 1U, 82 | (ptr[i] >> 1) & 1U, 83 | ptr[i] & 1 84 | ); 85 | 86 | pos += (retval > 0) ? retval : 0U; 87 | } 88 | #endif 89 | } 90 | 91 | void my_trace_end(void) 92 | { 93 | #ifdef MBED_CONF_LDL_ENABLE_VERBOSE_DEBUG 94 | if(pos > 0){ 95 | 96 | tr_debug(buffer); 97 | } 98 | my_trace_unlock(); 99 | #endif 100 | } 101 | -------------------------------------------------------------------------------- /wrappers/mbed/mbed_ldl_port.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef MBED_LDL_PORT_H 23 | #define MBED_LDL_PORT_H 24 | 25 | #include "mbed_assert.h" 26 | #include "mbed_trace.h" 27 | #include "mbed_critical.h" 28 | 29 | #define TRACE_GROUP "LDL" 30 | 31 | #define LDL_ASSERT(X) MBED_ASSERT(X); 32 | 33 | #define LDL_INFO(FMT, ...) my_trace_lock();tr_info(FMT, ##__VA_ARGS__);my_trace_unlock(); 34 | 35 | #define LDL_DEBUG(FMT, ...) my_trace_lock();tr_debug(FMT, ##__VA_ARGS__);my_trace_unlock(); 36 | 37 | #define LDL_ERROR(FMT, ...) my_trace_lock();tr_error(FMT, ##__VA_ARGS__);my_trace_unlock(); 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | void my_trace_lock(void); 44 | void my_trace_unlock(void); 45 | 46 | void my_trace_begin(void); 47 | void my_trace_part(const char *fmt, ...); 48 | void my_trace_hex(const uint8_t *ptr, size_t len); 49 | void my_trace_bitstring(const uint8_t *ptr, size_t len); 50 | void my_trace_end(void); 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #define LDL_TRACE_BEGIN() my_trace_begin(); 57 | #define LDL_TRACE_PART(...) my_trace_part(__VA_ARGS__); 58 | #define LDL_TRACE_HEX(PTR, LEN) my_trace_hex(PTR, LEN); 59 | #define LDL_TRACE_BIT_STRING(PTR, LEN) my_trace_bitstring(PTR, LEN); 60 | #define LDL_TRACE_FINAL() my_trace_end(); 61 | 62 | #define LDL_SYSTEM_ENTER_CRITICAL(APP) core_util_critical_section_enter(); 63 | #define LDL_SYSTEM_LEAVE_CRITICAL(APP) core_util_critical_section_exit(); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /wrappers/mbed/radio.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #include "radio.h" 23 | #include "ldl_system.h" 24 | #include "ldl_radio.h" 25 | 26 | using namespace LDL; 27 | 28 | /* constructors *******************************************************/ 29 | 30 | /* static protected ***************************************************/ 31 | 32 | Radio * 33 | Radio::to_radio(void *self) 34 | { 35 | return static_cast(self); 36 | } 37 | 38 | void 39 | Radio::_interrupt_handler(struct ldl_mac *self) 40 | { 41 | if(to_radio(self)->event_cb){ 42 | 43 | to_radio(self)->event_cb(); 44 | } 45 | } 46 | 47 | /* protected **********************************************************/ 48 | 49 | 50 | /* public *************************************************************/ 51 | 52 | void 53 | Radio::set_event_handler(Callback handler) 54 | { 55 | event_cb = handler; 56 | } 57 | 58 | Radio * 59 | Radio::get_state() 60 | { 61 | return this; 62 | } 63 | -------------------------------------------------------------------------------- /wrappers/mbed/radio.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef MBED_LDL_RADIO_H 23 | #define MBED_LDL_RADIO_H 24 | 25 | #include "mbed.h" 26 | #include "ldl_radio.h" 27 | #include "ldl_system.h" 28 | 29 | namespace LDL { 30 | 31 | /** 32 | * Radio driver base class 33 | * 34 | * Users should instantiate one of the subclasses named for the 35 | * transciever or module they wish to drive. 36 | * 37 | * */ 38 | class Radio { 39 | 40 | protected: 41 | 42 | static Radio *to_radio(void *self); 43 | 44 | Callback event_cb; 45 | 46 | static void _interrupt_handler(struct ldl_mac *self); 47 | 48 | public: 49 | 50 | void set_event_handler(Callback handler); 51 | 52 | virtual Radio *get_state(); 53 | virtual const struct ldl_radio_interface *get_interface() = 0; 54 | }; 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /wrappers/mbed/sm.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #include "sm.h" 23 | 24 | using namespace LDL; 25 | 26 | const struct ldl_sm_interface SM::interface = { 27 | .update_session_key = SM::_update_session_key, 28 | .mic = SM::_mic, 29 | .ecb = SM::_ecb, 30 | .ctr = SM::_ctr 31 | }; 32 | 33 | /* constructors *******************************************************/ 34 | 35 | /* protected static ***************************************************/ 36 | 37 | SM * 38 | SM::to_obj(void *self) 39 | { 40 | return static_cast(self); 41 | } 42 | 43 | void 44 | SM::_update_session_key(struct ldl_sm *self, enum ldl_sm_key key_desc, enum ldl_sm_key root_desc, const void *iv) 45 | { 46 | to_obj(self)->update_session_key(key_desc, root_desc, iv); 47 | } 48 | 49 | uint32_t 50 | SM::_mic(struct ldl_sm *self, enum ldl_sm_key desc, const void *hdr, uint8_t hdrLen, const void *data, uint8_t dataLen) 51 | { 52 | return to_obj(self)->mic(desc, hdr, hdrLen, data, dataLen); 53 | } 54 | 55 | void 56 | SM::_ecb(struct ldl_sm *self, enum ldl_sm_key desc, void *b) 57 | { 58 | to_obj(self)->ecb(desc, b); 59 | } 60 | 61 | void 62 | SM::_ctr(struct ldl_sm *self, enum ldl_sm_key desc, const void *iv, void *data, uint8_t len) 63 | { 64 | to_obj(self)->ctr(desc, iv, data, len); 65 | } 66 | 67 | /* protected **********************************************************/ 68 | -------------------------------------------------------------------------------- /wrappers/mbed/sm.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef MBED_LDL_SM_H 23 | #define MBED_LDL_SM_H 24 | 25 | #include "mbed.h" 26 | #include "ldl_sm_internal.h" 27 | #include "ldl_sm.h" 28 | 29 | namespace LDL { 30 | 31 | /** Abstract Security Module 32 | * 33 | * Security Modules will likely differ in terms of: 34 | * 35 | * - which cryptographic implementations they use 36 | * - how they store the root keys 37 | * - how they handle the keys 38 | * 39 | * The session keys never need to be persisted in non-volatile memory 40 | * since LDL will always re-derive from from the root keys and restored 41 | * non-secret state. 42 | * 43 | * */ 44 | class SM { 45 | 46 | protected: 47 | 48 | static SM *to_obj(void *self); 49 | 50 | static void _update_session_key(struct ldl_sm *self, enum ldl_sm_key key_desc, enum ldl_sm_key root_desc, const void *iv); 51 | static uint32_t _mic(struct ldl_sm *self, enum ldl_sm_key desc, const void *hdr, uint8_t hdrLen, const void *data, uint8_t dataLen); 52 | static void _ecb(struct ldl_sm *self, enum ldl_sm_key desc, void *b); 53 | static void _ctr(struct ldl_sm *self, enum ldl_sm_key desc, const void *iv, void *data, uint8_t len); 54 | 55 | virtual void update_session_key(enum ldl_sm_key key_desc, enum ldl_sm_key root_desc, const void *iv) = 0; 56 | virtual uint32_t mic(enum ldl_sm_key desc, const void *hdr, uint8_t hdrLen, const void *data, uint8_t dataLen) = 0; 57 | virtual void ecb(enum ldl_sm_key desc, void *b) = 0; 58 | virtual void ctr(enum ldl_sm_key desc, const void *iv, void *data, uint8_t len) = 0; 59 | 60 | public: 61 | 62 | static const struct ldl_sm_interface interface; 63 | }; 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /wrappers/mbed/sx126x.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef MBED_LDL_SX126X_H 23 | #define MBED_LDL_SX126X_H 24 | 25 | #include "spi_radio.h" 26 | 27 | namespace LDL { 28 | 29 | class SX126X : public SPIRadio { 30 | 31 | protected: 32 | 33 | DigitalInOut reset; 34 | InterruptIn dio1; 35 | 36 | Callback chip_mode_cb; 37 | 38 | static void _chip_set_mode(void *self, enum ldl_chip_mode mode); 39 | void chip_set_mode(enum ldl_chip_mode mode); 40 | 41 | void dio1_handler(); 42 | 43 | 44 | public: 45 | 46 | SX126X( 47 | enum ldl_radio_type type, 48 | SPI& spi, 49 | PinName nss, 50 | PinName reset, 51 | PinName busy, 52 | PinName dio1, 53 | PinName dio2, 54 | PinName dio3, 55 | int16_t tx_gain = 200, 56 | enum ldl_sx126x_regulator regulator = LDL_SX126X_REGULATOR_LDO, 57 | enum ldl_sx126x_txen txen = LDL_SX126X_TXEN_ENABLED, 58 | enum ldl_sx126x_voltage voltage = LDL_SX126X_VOLTAGE_1V6, 59 | enum ldl_radio_xtal xtal = LDL_RADIO_XTAL_CRYSTAL, 60 | Callback chip_mode_cb = nullptr 61 | ); 62 | }; 63 | 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /wrappers/mbed/sx127x.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Cameron Harper 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | * this software and associated documentation files (the "Software"), to deal in 5 | * the Software without restriction, including without limitation the rights to 6 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | * the Software, and to permit persons to whom the Software is furnished to do so, 8 | * subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * */ 21 | 22 | #ifndef MBED_LDL_SX127X_H 23 | #define MBED_LDL_SX127X_H 24 | 25 | #include "spi_radio.h" 26 | 27 | namespace LDL { 28 | 29 | class SX127X : public SPIRadio { 30 | 31 | protected: 32 | 33 | DigitalInOut reset; 34 | InterruptIn dio0; 35 | InterruptIn dio1; 36 | 37 | Callback chip_mode_cb; 38 | 39 | static void _chip_set_mode(void *self, enum ldl_chip_mode mode); 40 | void chip_set_mode(enum ldl_chip_mode mode); 41 | 42 | void dio0_handler(); 43 | void dio1_handler(); 44 | 45 | public: 46 | 47 | SX127X( 48 | enum ldl_radio_type type, 49 | SPI& spi, 50 | PinName nss, 51 | PinName reset, 52 | PinName dio0, 53 | PinName dio1, 54 | PinName dio2 = NC, 55 | PinName dio3 = NC, 56 | PinName dio4 = NC, 57 | PinName dio5 = NC, 58 | enum ldl_sx127x_pa pa = LDL_SX127X_PA_RFO, 59 | int16_t tx_gain = 200, 60 | enum ldl_radio_xtal xtal = LDL_RADIO_XTAL_CRYSTAL, 61 | Callback = nullptr 62 | ); 63 | }; 64 | 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /wrappers/ruby/ext/ldl/ext_ldl/ext_ldl.c: -------------------------------------------------------------------------------- 1 | #include "ext_ldl.h" 2 | #include "ext_mac.h" 3 | #include "ext_radio.h" 4 | #include "ext_sm.h" 5 | 6 | VALUE cLDL; 7 | 8 | void Init_ext_ldl(void) 9 | { 10 | cLDL = rb_define_module("LDL"); 11 | 12 | ext_mac_init(); 13 | ext_radio_init(); 14 | ext_sm_init(); 15 | } 16 | -------------------------------------------------------------------------------- /wrappers/ruby/ext/ldl/ext_ldl/ext_ldl.h: -------------------------------------------------------------------------------- 1 | #ifndef EXT_LDL_H 2 | #define EXT_LDL_H 3 | 4 | #include 5 | 6 | extern VALUE cLDL; 7 | 8 | void Init_ext_ldl(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /wrappers/ruby/ext/ldl/ext_ldl/ext_mac.h: -------------------------------------------------------------------------------- 1 | #ifndef EXT_MAC_H 2 | #define EXT_MAC_H 3 | 4 | void ext_mac_init(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /wrappers/ruby/ext/ldl/ext_ldl/ext_radio.h: -------------------------------------------------------------------------------- 1 | #ifndef EXT_RADIO_H 2 | #define EXT_RADIO_H 3 | 4 | #include "ldl_radio.h" 5 | 6 | extern const struct ldl_radio_interface ext_radio_interface; 7 | 8 | void ext_radio_init(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /wrappers/ruby/ext/ldl/ext_ldl/ext_sm.h: -------------------------------------------------------------------------------- 1 | #ifndef EXT_SM_H 2 | #define EXT_SM_H 3 | 4 | #include "ldl_sm_internal.h" 5 | 6 | extern const struct ldl_sm_interface ext_sm_interface; 7 | 8 | void ext_sm_init(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /wrappers/ruby/ext/ldl/ext_ldl/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | 3 | # get from this file back to project root 4 | #project_root = File.join(File.dirname(__FILE__), "..","..","..","..") 5 | project_root = File.expand_path(File.join(File.dirname(__FILE__), "..","..","..","..","..")) 6 | 7 | $srcs = Dir[File.join(__dir__, "*.c")] 8 | $srcs += Dir[File.join(project_root, "src", "*.c")] 9 | 10 | $VPATH << File.join(project_root, "src") 11 | 12 | $INCFLAGS << " -I#{File.join(project_root, "include")}" 13 | 14 | $defs << " -DLDL_TARGET_INCLUDE=\\\"platform.h\\\"" 15 | 16 | CONFIG["debugflags"] = "-ggdb3" 17 | CONFIG["optflags"] = "-O0" 18 | 19 | create_makefile('ldl/ext_ldl') 20 | -------------------------------------------------------------------------------- /wrappers/ruby/ext/ldl/ext_ldl/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUG_H 2 | #define DEBUG_H 3 | 4 | #include "ext_ldl.h" 5 | 6 | #define LDL_L2_VERSION LDL_L2_VERSION_1_1 7 | 8 | #define LDL_ENABLE_AU_915_928 9 | #define LDL_ENABLE_US_902_928 10 | #define LDL_ENABLE_EU_433 11 | #define LDL_ENABLE_EU_863_870 12 | 13 | #define LDL_ENABLE_OTAA_DITHER 14 | 15 | #define LDL_ENABLE_TEST_MODE 16 | 17 | void LDL_System_enterCriticalSection(void *app); 18 | void LDL_System_leaveCriticalSection(void *app); 19 | 20 | #define LDL_SYSTEM_ENTER_CRITICAL(APP) LDL_System_enterCriticalSection(APP); 21 | #define LDL_SYSTEM_LEAVE_CRITICAL(APP) LDL_System_leaveCriticalSection(APP); 22 | 23 | #define LDL_PARAM_TPS 1000000 24 | #define LDL_PARAM_ADVANCE 0 25 | #define LDL_PARAM_A 0 26 | #define LDL_PARAM_B 0 27 | 28 | #include "ldl_system.h" 29 | 30 | #define LDL_ERROR(FMT, ...) \ 31 | do{\ 32 | VALUE msg = rb_sprintf("LDL::ExtMac: %s: " FMT, __FUNCTION__, ##__VA_ARGS__);\ 33 | rb_funcall(rb_const_get(cLDL, rb_intern("Scenario")), rb_intern("log_error"), 1, msg);\ 34 | }while(0); 35 | 36 | #define LDL_DEBUG(FMT, ...) \ 37 | do{\ 38 | VALUE msg = rb_sprintf("LDL::ExtMac: %s: " FMT, __FUNCTION__, ##__VA_ARGS__);\ 39 | rb_funcall(rb_const_get(cLDL, rb_intern("Scenario")), rb_intern("log_debug"), 1, msg);\ 40 | }while(0); 41 | 42 | #define LDL_INFO(FMT, ...) \ 43 | do{\ 44 | VALUE msg = rb_sprintf("LDL::ExtMac: %s: " FMT, __FUNCTION__, ##__VA_ARGS__);\ 45 | rb_funcall(rb_const_get(cLDL, rb_intern("Scenario")), rb_intern("log_info"), 1, msg);\ 46 | }while(0); 47 | 48 | /* LDL_ASSERT will raise a LDL::LoraAssert */ 49 | #define LDL_ASSERT(X) \ 50 | if(!(X)){\ 51 | VALUE args[] = {\ 52 | rb_funcall(rb_cFile, rb_intern("basename"), 1, rb_str_new_cstr(__FILE__)),\ 53 | UINT2NUM(__LINE__),\ 54 | rb_str_new_cstr(__FUNCTION__),\ 55 | rb_str_new_cstr(#X)\ 56 | };\ 57 | VALUE msg = rb_str_format(sizeof(args)/sizeof(*args), args, rb_str_new_cstr("%s: %u: %s(): assertion failed: %s"));\ 58 | VALUE ex = rb_funcall(rb_const_get(rb_const_get(rb_cObject, rb_intern("LDL")), rb_intern("LoraAssert")), rb_intern("new"), 1, msg);\ 59 | rb_funcall(rb_mKernel, rb_intern("raise"), 1, ex);\ 60 | } 61 | 62 | /* LDL_PEDANTIC will expand to LDL_ASSERT */ 63 | #define LDL_PEDANTIC(X) LDL_ASSERT(X) 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl.rb: -------------------------------------------------------------------------------- 1 | require 'ldl/composite_logger' 2 | require 'ldl/logger_methods' 3 | 4 | require 'small_event' 5 | require 'timeout_queue' 6 | 7 | include SmallEvent 8 | 9 | require 'ldl/eui' 10 | require 'ldl/key' 11 | 12 | require 'ldl/radio_model' 13 | require 'ldl/location' 14 | require 'ldl/lora_assert' 15 | require 'ldl/lora_error' 16 | require 'ldl/radio' 17 | require 'ldl/error' 18 | require 'ldl/mac' 19 | require 'ldl/clock' 20 | require 'ldl/semtech' 21 | require 'ldl/gateway' 22 | require 'ldl/device' 23 | require 'ldl/frame_logger' 24 | require 'ldl/scenario' 25 | 26 | require 'ldl/ext_ldl' 27 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/composite_logger.rb: -------------------------------------------------------------------------------- 1 | require 'logger' 2 | 3 | module LDL 4 | 5 | class CompositeLogger 6 | 7 | def initialize 8 | @loggers = [] 9 | end 10 | 11 | def <<(logger) 12 | @loggers << logger 13 | self 14 | end 15 | 16 | def error(*args, &block) 17 | @loggers.each do |logger| 18 | logger.error(*args, &block) 19 | end 20 | self 21 | end 22 | 23 | def info(*args, &block) 24 | @loggers.each do |logger| 25 | logger.info(*args, &block) 26 | end 27 | self 28 | end 29 | 30 | def debug(*args, &block) 31 | @loggers.each do |logger| 32 | logger.debug(*args, &block) 33 | end 34 | self 35 | end 36 | 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/device.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | module LDL 4 | 5 | class Device 6 | 7 | extend Forwardable 8 | 9 | include LoggerMethods 10 | 11 | attr_reader :mac, :sm, :radio 12 | 13 | def_delegators :@mac, 14 | :dev_eui, 15 | :join_eui, 16 | :otaa, 17 | :unconfirmed, 18 | :confirmed, 19 | :ready, 20 | :joined, 21 | :forget, 22 | :power, 23 | :power=, 24 | :rate, 25 | :rate=, 26 | :op, 27 | :state, 28 | :max_dcycle, 29 | :max_dcycle=, 30 | :name, 31 | :start, 32 | :stop, 33 | :entropy, 34 | :region, 35 | :adr=, 36 | :adr, 37 | :unlimited_duty_cycle=, 38 | :on_rx, 39 | :on_device_time, 40 | :on_link_status, 41 | :dev_addr, 42 | :net_id, 43 | :join_nonce, 44 | :next_dev_nonce, 45 | :session 46 | 47 | def_delegators :@sm, 48 | :nwk_key, 49 | :app_key, 50 | :keys 51 | 52 | def_delegators :@radio, 53 | :reliability=, 54 | :rx_log, 55 | :tx_log 56 | 57 | def initialize(broker, clock, **opts) 58 | 59 | opts[:dev_eui] ||= SecureRandom.bytes(8) 60 | opts[:join_eui] ||= SecureRandom.bytes(8) 61 | opts[:nwk_key] ||= SecureRandom.bytes(16) 62 | opts[:app_key] ||= SecureRandom.bytes(16) 63 | 64 | @clock = clock 65 | @broker = broker 66 | 67 | @radio = Radio.new(broker, clock, **opts) 68 | @sm = SM.new(broker, clock, **opts) 69 | @mac = MAC.new(broker, clock, sm, radio, **opts) 70 | 71 | end 72 | 73 | end 74 | 75 | end 76 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/error.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | # used to indicate the state is not right (e.g. you cannot personalise a joined device) 4 | class StateError < StandardError 5 | end 6 | 7 | # timeout condition while waiting for join confirmation 8 | class JoinTimeout < StandardError 9 | end 10 | 11 | # timeout condition while waiting for confirmed send confirmation 12 | class DataTimeout < StandardError 13 | end 14 | 15 | # requested operation failed for radio error 16 | class OpError < StandardError 17 | end 18 | 19 | # requested operation was cancelled 20 | class OpCancelled < StandardError 21 | end 22 | 23 | # generic run-time error... 24 | class Error < StandardError 25 | end 26 | 27 | class Errno < StandardError; end 28 | 29 | class ErrNoChannel < Errno; end 30 | class ErrSize < Errno; end 31 | class ErrRate < Errno; end 32 | class ErrPort < Errno; end 33 | class ErrBusy < Errno; end 34 | class ErrNotJoined < Errno; end 35 | class ErrPower < Errno; end 36 | class ErrMACPriority < Errno; end 37 | class ErrDevNonce < Errno; end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/frame_logger.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | module LDL 4 | 5 | class FrameLogger 6 | 7 | def get 8 | with_mutex do 9 | @buffer.dup 10 | end 11 | end 12 | 13 | def initialize(**opts) 14 | @buffer = [] 15 | @limit = opts[:limit]||1000 16 | @mutex = Mutex.new 17 | end 18 | 19 | def log(m) 20 | with_mutex do 21 | item = { 22 | time: Clock.ticks_to_f(m[:time]), 23 | end_time: Clock.ticks_to_f(m[:time] + m[:air_time]), 24 | ticks: m[:ticks], 25 | freq: m[:freq], 26 | sf: m[:sf], 27 | bw: m[:bw], 28 | data: m[:data], 29 | air_time: Clock.ticks_to_f(m[:air_time]), 30 | rssi: m[:rssi], 31 | snr: m[:snr], 32 | power: m[:power] 33 | } 34 | @buffer.push(item) 35 | @buffer.shift if @buffer.size > @limit 36 | nil 37 | end 38 | end 39 | 40 | def with_mutex 41 | @mutex.synchronize do 42 | yield 43 | end 44 | end 45 | 46 | private :with_mutex 47 | 48 | end 49 | 50 | end 51 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/key.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | class Key 4 | 5 | attr_reader :value 6 | 7 | def bytes 8 | value 9 | end 10 | 11 | NIBBLE = "[0-9a-fA-F]" 12 | OCTET = "(#{NIBBLE}#{NIBBLE})" 13 | DELIM4 = OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET + OCTET 14 | 15 | def initialize(value) 16 | raise TypeError unless value.kind_of? String 17 | if value.size == 16 18 | @value = value 19 | elsif match = Regexp.new(DELIM4).match(value) 20 | integerArray = [] 21 | match.captures.each do |c| 22 | integerArray << c.to_i(16) 23 | end 24 | @value = integerArray.pack("c*") 25 | else 26 | raise ArgumentError 27 | end 28 | 29 | end 30 | 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/location.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | Location = Struct.new(:x,:y) 4 | 5 | end 6 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/logger_methods.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | LOG_FORMATTER = Proc.new do |severity, datetime, progname, msg| 4 | "#{severity.ljust(5)} [#{datetime.strftime("%Y-%m-%d %H:%M:%S")}] #{progname}#{progname ? ": " : ""}#{msg}\n" 5 | end 6 | 7 | module LoggerMethods 8 | 9 | NULL_LOGGER = Logger.new(IO::NULL) 10 | NULL_LOGGER.level = Logger::WARN 11 | 12 | def _do_hdr(hdr) 13 | if hdr 14 | "#{log_header}: #{hdr}" 15 | else 16 | log_header 17 | end 18 | end 19 | 20 | def log_info(hdr=nil, &block) 21 | @logger.info(_do_hdr(hdr), &block) if log_is_enabled 22 | end 23 | 24 | def log_error(hdr=nil, &block) 25 | @logger.debug(_do_hdr(hdr), &block) if log_is_enabled 26 | end 27 | 28 | def log_debug(hdr=nil, &block) 29 | @logger.debug(_do_hdr(hdr), &block) if log_is_enabled 30 | end 31 | 32 | def log_header 33 | @log_header||=self.class.name 34 | end 35 | 36 | def log_header=(hdr) 37 | @log_header = hdr 38 | end 39 | 40 | def enable_log 41 | @log_is_enabled = true 42 | end 43 | 44 | def disable_log 45 | @log_is_enabled = false 46 | end 47 | 48 | def log_is_enabled 49 | @log_is_enabled ||= false 50 | end 51 | 52 | end 53 | 54 | end 55 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/lora_assert.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | class LoraAssert < StandardError 4 | end 5 | 6 | end 7 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/lora_error.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | class Error < StandardError 4 | end 5 | 6 | end 7 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/radio_model.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | module RadioModel 4 | 5 | include Math 6 | 7 | SNR_LIMIT = { 8 | 7 => -7.5, 9 | 8 => -10.0, 10 | 9 => -12.5, 11 | 10 => -15.0, 12 | 11 => -17.5, 13 | 12 => -20.0, 14 | } 15 | 16 | attr_writer :noise_figure 17 | 18 | def noise_figure 19 | @noise_figure ||= 6.0 20 | end 21 | 22 | attr_writer :path_loss 23 | 24 | def path_loss 25 | @path_loss ||= 50.0 26 | end 27 | 28 | attr_writer :noise_floor 29 | 30 | def noise_floor 31 | @noise_floor ||= -120.0 32 | end 33 | 34 | def sensitivity(bw, sf) 35 | -174.0 + 10.0*log10(bw.to_f) + self.noise_figure + SNR_LIMIT[sf] 36 | end 37 | 38 | def link_budget(tx_power, bw, sf) 39 | tx_power - self.sensitivity(bw, sf) 40 | end 41 | 42 | def snr(tx_power) 43 | self.rssi(tx_power) - self.noise_floor 44 | end 45 | 46 | def rssi(tx_power) 47 | tx_power - self.path_loss 48 | end 49 | 50 | def rf_detected?(tx_power, bw, sf) 51 | (self.link_budget(tx_power, bw, sf) > self.path_loss) 52 | end 53 | 54 | def reliability=(setting) 55 | @reliability = setting 56 | end 57 | 58 | def reliability 59 | if @reliability.nil? 60 | 1.0 61 | else 62 | if @reliability.kind_of? Array 63 | setting = @reliability.shift||1.0 64 | else 65 | setting = @reliability 66 | end 67 | if setting.kind_of? Range 68 | rand(setting) 69 | elsif setting.nil? 70 | 1.0 71 | else 72 | setting 73 | end 74 | end 75 | end 76 | 77 | end 78 | 79 | end 80 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/scenario.rb: -------------------------------------------------------------------------------- 1 | require 'securerandom' 2 | 3 | module LDL 4 | 5 | class Scenario 6 | 7 | attr_reader :region, :gw, :device, :broker, :clock, :logger 8 | 9 | def self.log_info(msg) 10 | @logger.info{msg} if @logger 11 | end 12 | 13 | def self.log_debug(msg) 14 | @logger.debug{msg} if @logger 15 | end 16 | 17 | def self.log_error(msg) 18 | @logger.error{msg} if @logger 19 | end 20 | 21 | def self.logger=(logger) 22 | @logger = logger 23 | end 24 | 25 | def self.run(**opts) 26 | 27 | inst = self.new(**opts) 28 | inst.start 29 | yield(inst) if block_given? 30 | inst.stop 31 | 32 | end 33 | 34 | # @param opts [Hash] 35 | # 36 | # @option opts [Symbol] :region 37 | # @option opts [String] :gw_eui 38 | # @option opts [String] :join_eui 39 | # @option opts [String] :dev_eui 40 | # @option opts [String] :nwk_key 41 | # @option opts [String] :app_key 42 | # @option opts [String] :lorawan_version 43 | # @option opts [String] :budget_margin 44 | # 45 | def initialize(**opts) 46 | 47 | @logger = opts[:logger]||LoggerMethods::NULL_LOGGER 48 | 49 | self.class.logger = @logger 50 | 51 | @broker = Broker.new 52 | @clock = Clock.new(logger: logger) 53 | 54 | @gw = Gateway.new(broker, clock, **opts.merge(logger: logger)) 55 | 56 | @device = Device.new(broker, clock, **opts.merge(logger: logger)) 57 | 58 | end 59 | 60 | def region 61 | @device.region 62 | end 63 | 64 | def ticks 65 | @clock.ticks 66 | end 67 | 68 | def start 69 | clock.start 70 | device.start 71 | gw.start 72 | self 73 | end 74 | 75 | def stop 76 | gw.stop 77 | device.stop 78 | clock.stop 79 | self 80 | end 81 | 82 | end 83 | 84 | end 85 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/semtech.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | # This module contains an implementation of the Semtech packet 4 | # forwarder protocol. 5 | # 6 | module Semtech 7 | 8 | @token = rand(0..0xffff) 9 | 10 | # @return a message "token" 11 | def self.token 12 | result = @token % 0xffff 13 | @token = @token.next 14 | result 15 | end 16 | 17 | end 18 | 19 | end 20 | 21 | require_relative 'semtech/message' 22 | require_relative 'semtech/push_data' 23 | require_relative 'semtech/push_ack' 24 | require_relative 'semtech/pull_data' 25 | require_relative 'semtech/pull_ack' 26 | require_relative 'semtech/pull_resp' 27 | require_relative 'semtech/tx_ack' 28 | 29 | require_relative 'semtech/status_packet' 30 | require_relative 'semtech/rx_packet' 31 | require_relative 'semtech/tx_packet' 32 | require_relative 'semtech/tx_packet_ack' 33 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/semtech/message.rb: -------------------------------------------------------------------------------- 1 | module LDL::Semtech 2 | 3 | class Message 4 | 5 | VERSION = 2 6 | 7 | 8 | PUSH_DATA = 0 9 | PUSH_ACK = 1 10 | PULL_DATA = 2 11 | PULL_RESP = 3 12 | PULL_ACK = 4 13 | TX_ACK = 5 14 | 15 | @subclasses = [] 16 | @type = nil 17 | 18 | def self.type 19 | @type 20 | end 21 | 22 | def self.inherited(subclass) 23 | @subclasses << subclass 24 | end 25 | 26 | def self.decode(msg) 27 | 28 | iter = msg.unpack("CS>C").each 29 | 30 | version = iter.next 31 | iter.next 32 | type = iter.next 33 | 34 | if version != Message::VERSION 35 | raise ArgumentError.new "unknown protocol version" 36 | end 37 | 38 | if klass = @subclasses.detect{|m|m.type == type} 39 | klass.decode(msg) 40 | else 41 | raise ArgumentError.new "unknown message type" 42 | end 43 | 44 | end 45 | 46 | attr_reader :token 47 | 48 | def initialize(**params) 49 | if params[:token] 50 | raise TypeError unless params[:token].kind_of? Integer 51 | raise ArgumentError unless Range.new(0, 0xffff).include? params[:token] 52 | @token = params[:token] 53 | else 54 | @token = LDL::Semtech.token 55 | end 56 | end 57 | 58 | def encode 59 | [VERSION, token, self.class.type].pack("CS>C") 60 | end 61 | 62 | end 63 | 64 | end 65 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/semtech/pull_ack.rb: -------------------------------------------------------------------------------- 1 | module LDL::Semtech 2 | 3 | class PullAck < Message 4 | 5 | @type = PULL_ACK 6 | 7 | def self.decode(msg) 8 | 9 | iter = msg.unpack("CS>C").each 10 | 11 | version = iter.next 12 | token = iter.next 13 | type = iter.next 14 | 15 | if version != Message::VERSION 16 | raise ArgumentError.new "unknown protocol version" 17 | end 18 | 19 | if type != self.type 20 | raise ArgumentError.new "expecting message type #{self.type}" 21 | end 22 | 23 | self.new( 24 | version: version, 25 | token: token 26 | ) 27 | end 28 | 29 | end 30 | 31 | end 32 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/semtech/pull_data.rb: -------------------------------------------------------------------------------- 1 | module LDL::Semtech 2 | 3 | class PullData < Message 4 | 5 | @type = PULL_DATA 6 | 7 | def self.decode(msg) 8 | 9 | iter = msg.unpack("CS>Ca8").each 10 | 11 | version = iter.next 12 | token = iter.next 13 | type = iter.next 14 | eui = iter.next 15 | 16 | if version != Message::VERSION 17 | raise ArgumentError.new "unknown protocol version" 18 | end 19 | 20 | if type != self.type 21 | raise ArgumentError.new "expecting message type #{self.type}" 22 | end 23 | 24 | self.new( 25 | version: version, 26 | token: token, 27 | eui: LDL::EUI.new(eui), 28 | ) 29 | end 30 | 31 | attr_reader :eui 32 | 33 | def initialize(**params) 34 | 35 | super(**params) 36 | 37 | if params.has_key? :eui 38 | @eui = LDL::EUI.new(params[:eui]) 39 | else 40 | @eui = LDL::EUI.new("00-00-00-00-00-00-00-00") 41 | end 42 | 43 | end 44 | 45 | def encode 46 | [super, eui.bytes].pack("a*a*") 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/semtech/pull_resp.rb: -------------------------------------------------------------------------------- 1 | module LDL::Semtech 2 | 3 | class PullResp < Message 4 | 5 | @type = PULL_RESP 6 | 7 | def self.decode(msg) 8 | 9 | iter = msg.unpack("CS>Ca*").each 10 | 11 | version = iter.next 12 | token = iter.next 13 | type = iter.next 14 | txpk = nil 15 | 16 | if version != Message::VERSION 17 | raise ArgumentError.new "unknown protocol version" 18 | end 19 | 20 | if type != self.type 21 | raise ArgumentError.new "expecting message type #{self.type}" 22 | end 23 | 24 | begin 25 | 26 | root = JSON.parse(iter.next) 27 | 28 | if not root.kind_of? Hash 29 | raise ArgumentError.new "expecting root JSON to be an object" 30 | end 31 | 32 | if not root.has_key? 'txpk' 33 | raise ArgumentError.new "root must contain key 'txpk'" 34 | end 35 | 36 | txpk = TXPacket.from_h(root["txpk"]) 37 | 38 | rescue => e 39 | raise ArgumentError.new "payload is not valid: #{e}" 40 | end 41 | 42 | self.new( 43 | version: version, 44 | token: token, 45 | txpk: txpk 46 | ) 47 | end 48 | 49 | attr_reader :txpk 50 | 51 | def initialize(**params) 52 | 53 | super(**params) 54 | 55 | if params.has_key? :txpk 56 | raise TypeError unless params[:txpk].kind_of? TXPacket 57 | @txpk = params[:txpk] 58 | else 59 | @txpk = TXPacket.new 60 | end 61 | 62 | end 63 | 64 | def encode 65 | [super, {:txpk => txpk}.to_json].pack("a*a*") 66 | end 67 | 68 | end 69 | 70 | end 71 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/semtech/push_ack.rb: -------------------------------------------------------------------------------- 1 | module LDL::Semtech 2 | 3 | class PushAck < Message 4 | 5 | @type = PUSH_ACK 6 | 7 | def self.decode(msg) 8 | 9 | iter = msg.unpack("CS>C").each 10 | 11 | version = iter.next 12 | token = iter.next 13 | type = iter.next 14 | 15 | if version != Message::VERSION 16 | raise ArgumentError.new "unknown protocol version" 17 | end 18 | 19 | if type != self.type 20 | raise ArgumentError.new "expecting message type #{self.type}" 21 | end 22 | 23 | self.new( 24 | version: version, 25 | token: token 26 | ) 27 | 28 | end 29 | 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/semtech/tx_ack.rb: -------------------------------------------------------------------------------- 1 | module LDL::Semtech 2 | 3 | class TXAck < Message 4 | 5 | @type = TX_ACK 6 | 7 | def self.decode(msg) 8 | 9 | iter = msg.unpack("CS>Ca8a*").each 10 | 11 | version = iter.next 12 | token = iter.next 13 | type = iter.next 14 | eui = iter.next 15 | 16 | if version != Message::VERSION 17 | raise ArgumentError.new "unknown protocol version" 18 | end 19 | 20 | if type != self.type 21 | raise ArgumentError.new "expecting message type #{self.type}" 22 | end 23 | 24 | begin 25 | 26 | root = JSON.parse(iter.next) 27 | 28 | if not root.kind_of? Hash 29 | raise ArgumentError.new "expecting root JSON to be an object" 30 | end 31 | 32 | if root["txpk_ack"].nil? 33 | raise ArgumentError.new "root must contain the key 'txpk_ack'" 34 | end 35 | 36 | txpk_ack = TXPacketAck.from_h(root["txpk_ack"]) 37 | 38 | rescue 39 | ArgumentError.new "payload is not valid" 40 | end 41 | 42 | self.new( 43 | version: version, 44 | token: token, 45 | eui: LDL::EUI.new(eui), 46 | txpk_ack: txpk_ack 47 | ) 48 | end 49 | 50 | attr_reader :eui 51 | attr_reader :txpk_ack 52 | 53 | def initialize(**params) 54 | 55 | super(**params) 56 | 57 | if params.has_key? :txpk_ack 58 | raise TypeError unless params[:txpk_ack].kind_of? TXPacketAck 59 | @rxpk_ack = params[:txpk_ack] 60 | else 61 | @txpk_ack = TXPacketAck.new 62 | end 63 | 64 | if params.has_key? :eui 65 | @eui = LDL::EUI.new(params[:eui]) 66 | else 67 | @eui = LDL::EUI.new("00-00-00-00-00-00-00-00") 68 | end 69 | 70 | end 71 | 72 | def encode 73 | [super, eui.bytes, {:txpk_ack => txpk_ack}.to_json].pack("a*a*a*") 74 | end 75 | 76 | end 77 | 78 | end 79 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/semtech/tx_packet_ack.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | module LDL::Semtech 4 | 5 | class TXPacketAck 6 | 7 | =begin 8 | Name | Type | Function 9 | :----:|:------:|------------------------------------------------------------------------------ 10 | error | string | Indication about success or type of failure that occured for downlink request. 11 | 12 | The possible values of "error" field are: 13 | 14 | Value | Definition 15 | :-----------------:|--------------------------------------------------------------------- 16 | NONE | Packet has been programmed for downlink 17 | TOO_LATE | Rejected because it was already too late to program this packet for downlink 18 | TOO_EARLY | Rejected because downlink packet timestamp is too much in advance 19 | COLLISION_PACKET | Rejected because there was already a packet programmed in requested timeframe 20 | COLLISION_BEACON | Rejected because there was already a beacon planned in requested timeframe 21 | TX_FREQ | Rejected because requested frequency is not supported by TX RF chain 22 | TX_POWER | Rejected because requested power is not supported by gateway 23 | GPS_UNLOCKED | Rejected because GPS is unlocked, so GPS timestamp cannot be used 24 | =end 25 | 26 | ERROR = [ 27 | "NONE", 28 | "TOO_LATE", 29 | "COLLISION_PACKET", 30 | "COLLISION_BEACON", 31 | "TX_FREQ", 32 | "TX_POWER", 33 | "GPS_UNLOCKED" 34 | ] 35 | 36 | def self.from_h(msg) 37 | begin 38 | self.new(error: msg["error"]) 39 | rescue 40 | raise ArgumentError 41 | end 42 | end 43 | 44 | attr_reader :error 45 | 46 | def initialize(**param) 47 | if param[:error] 48 | raise TypeError unless param[:error].kind_of? String 49 | raise RangeError unless ERROR.include? param[:error] 50 | @error = param[:error] 51 | else 52 | @error = ERROR.first 53 | end 54 | end 55 | 56 | def to_json(options={}) 57 | { 58 | :error => @error 59 | }.to_json 60 | end 61 | 62 | end 63 | 64 | end 65 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/ldl/version.rb: -------------------------------------------------------------------------------- 1 | module LDL 2 | 3 | VERSION = File.read(File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "version"))).strip.freeze 4 | 5 | end 6 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/small_event/version.rb: -------------------------------------------------------------------------------- 1 | module SmallEvent 2 | 3 | VERSION = "0.1.0" 4 | 5 | end 6 | -------------------------------------------------------------------------------- /wrappers/ruby/lib/timeout_queue/version.rb: -------------------------------------------------------------------------------- 1 | class TimeoutQueue 2 | 3 | VERSION = "0.1.1" 4 | 5 | end 6 | -------------------------------------------------------------------------------- /wrappers/ruby/test/clock_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | require 'timeout' 4 | 5 | describe "ClockTest" do 6 | 7 | let(:clock){ LDL::Clock.new } 8 | let(:q){ Queue.new } 9 | 10 | before do 11 | Thread.abort_on_exception = true 12 | clock.start 13 | end 14 | 15 | after do 16 | clock.stop 17 | Thread.abort_on_exception = false 18 | end 19 | 20 | it "can wait" do 21 | Timeout::timeout(1){ clock.wait 500000 } 22 | end 23 | 24 | it "can return ticks" do 25 | clock.ticks 26 | end 27 | 28 | it "can execute on timeout" do 29 | 30 | clock.call_in(500000) { q.push nil } 31 | 32 | Timeout::timeout(1) { q.pop } 33 | 34 | end 35 | 36 | it "can execute immediately" do 37 | 38 | clock.call { q.push nil } 39 | 40 | Timeout::timeout(1) { q.pop } 41 | 42 | end 43 | 44 | it "can execute multiple timeouts in correct order" do 45 | 46 | clock.call do 47 | 48 | clock.call_in(100000) { q.push 1 } 49 | clock.call_in(50000) { q.push 0 } 50 | clock.call_in(200000) { q.push 3 } 51 | clock.call_in(150000) { q.push 2 } 52 | 53 | end 54 | 55 | result = [] 56 | 57 | Timeout::timeout 1 do 58 | result << q.pop 59 | result << q.pop 60 | result << q.pop 61 | result << q.pop 62 | end 63 | 64 | iter = result.each 65 | 66 | assert_equal 0, iter.next 67 | assert_equal 1, iter.next 68 | assert_equal 2, iter.next 69 | assert_equal 3, iter.next 70 | 71 | end 72 | 73 | end 74 | -------------------------------------------------------------------------------- /wrappers/ruby/test/pull_ack_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestPullAck < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::PullAck.new 10 | end 11 | 12 | def test_encode_default 13 | 14 | out = @state.encode 15 | 16 | iter = out.unpack("CS>C").each 17 | 18 | assert_equal Semtech::Message::VERSION, iter.next 19 | iter.next 20 | 21 | assert_equal @state.class.type, iter.next 22 | 23 | end 24 | 25 | def test_decode_default 26 | 27 | input = @state.encode 28 | 29 | input = "\x02\x00\x00\x04" 30 | 31 | decoded = Semtech::PullAck.decode(input) 32 | 33 | assert_equal 0, decoded.token 34 | 35 | end 36 | 37 | def test_encode_decode 38 | assert_kind_of Semtech::PullAck, Semtech::Message.decode(@state.encode) 39 | end 40 | 41 | end 42 | -------------------------------------------------------------------------------- /wrappers/ruby/test/pull_data_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestPullData < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::PullData.new 10 | end 11 | 12 | def test_encode_default 13 | 14 | out = @state.encode 15 | 16 | iter = out.unpack("CS>Ca8").each 17 | 18 | assert_equal Semtech::Message::VERSION, iter.next 19 | iter.next 20 | 21 | assert_equal @state.class.type, iter.next 22 | 23 | assert_equal "\x00\x00\x00\x00\x00\x00\x00\x00", iter.next 24 | 25 | end 26 | 27 | def test_decode_default 28 | 29 | input = "\x02\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00" 30 | 31 | decoded = Semtech::PullData.decode(input) 32 | 33 | assert_equal 0, decoded.token 34 | 35 | end 36 | 37 | def test_encode_decode 38 | assert_kind_of Semtech::PullData, Semtech::Message.decode(@state.encode) 39 | end 40 | 41 | end 42 | -------------------------------------------------------------------------------- /wrappers/ruby/test/pull_resp_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | 5 | 6 | class TestPullResp < Minitest::Test 7 | 8 | include LDL 9 | 10 | def setup 11 | @state = Semtech::PullResp.new 12 | end 13 | 14 | def test_encode_default 15 | 16 | out = @state.encode 17 | 18 | iter = out.unpack("CS>Ca*").each 19 | 20 | assert_equal Semtech::Message::VERSION, iter.next 21 | iter.next 22 | 23 | assert_equal @state.class.type, iter.next 24 | 25 | JSON.parse iter.next 26 | 27 | end 28 | 29 | def test_decode_default 30 | 31 | input = @state.encode 32 | 33 | input = "\x02\x00\x00\x03#{{:txpk => Semtech::TXPacket.new}.to_json}" 34 | 35 | decoded = Semtech::PullResp.decode(input) 36 | 37 | assert_equal 0, decoded.token 38 | 39 | end 40 | 41 | def test_encode_decode 42 | assert_kind_of Semtech::PullResp, Semtech::Message.decode(@state.encode) 43 | end 44 | 45 | def test_decode_real 46 | input = "\x02\x46\x8E\x03\x7B\x22\x74\x78\x70\x6B\x22\x3A\x7B\x22\x69\x6D\x6D\x65\x22\x3A\x66\x61\x6C\x73\x65\x2C\x22\x74\x6D\x73\x74\x22\x3A\x35\x31\x31\x33\x34\x32\x30\x2C\x22\x66\x72\x65\x71\x22\x3A\x38\x36\x38\x2E\x31\x2C\x22\x72\x66\x63\x68\x22\x3A\x30\x2C\x22\x70\x6F\x77\x65\x22\x3A\x31\x34\x2C\x22\x6D\x6F\x64\x75\x22\x3A\x22\x4C\x4F\x52\x41\x22\x2C\x22\x64\x61\x74\x72\x22\x3A\x22\x53\x46\x37\x42\x57\x31\x32\x35\x22\x2C\x22\x63\x6F\x64\x72\x22\x3A\x22\x34\x2F\x35\x22\x2C\x22\x69\x70\x6F\x6C\x22\x3A\x74\x72\x75\x65\x2C\x22\x73\x69\x7A\x65\x22\x3A\x33\x33\x2C\x22\x6E\x63\x72\x63\x22\x3A\x74\x72\x75\x65\x2C\x22\x64\x61\x74\x61\x22\x3A\x22\x49\x47\x33\x59\x59\x45\x6D\x56\x54\x74\x78\x38\x42\x75\x79\x52\x43\x6D\x79\x36\x6D\x72\x68\x35\x42\x4C\x32\x4E\x6A\x49\x55\x4B\x6F\x6A\x6F\x72\x6B\x39\x43\x4C\x30\x58\x51\x67\x22\x7D\x7D" 47 | Semtech::PullResp.decode(input) 48 | end 49 | 50 | end 51 | -------------------------------------------------------------------------------- /wrappers/ruby/test/push_ack_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestPushAck < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::PushAck.new 10 | end 11 | 12 | def test_encode_default 13 | 14 | out = @state.encode 15 | 16 | iter = out.unpack("CS>C").each 17 | 18 | assert_equal Semtech::Message::VERSION, iter.next 19 | iter.next 20 | 21 | assert_equal @state.class.type, iter.next 22 | 23 | end 24 | 25 | def test_decode_default 26 | 27 | input = @state.encode 28 | 29 | input = "\x02\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00{\"rxpk\":[]}" 30 | 31 | decoded = Semtech::PushAck.decode(input) 32 | 33 | assert_equal 0, decoded.token 34 | 35 | end 36 | 37 | def test_encode_decode 38 | assert_kind_of Semtech::PushAck, Semtech::Message.decode(@state.encode) 39 | end 40 | 41 | end 42 | -------------------------------------------------------------------------------- /wrappers/ruby/test/push_data_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestPushData < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::PushData.new 10 | end 11 | 12 | def test_encode_default 13 | 14 | out = @state.encode 15 | 16 | iter = out.unpack("CS>Ca8a*").each 17 | 18 | assert_equal Semtech::Message::VERSION, iter.next 19 | iter.next 20 | 21 | assert_equal @state.class.type, iter.next 22 | 23 | assert_equal "\x00\x00\x00\x00\x00\x00\x00\x00", iter.next 24 | 25 | assert_equal({"rxpk" => []}, JSON.parse(iter.next)) 26 | 27 | end 28 | 29 | def test_decode_default 30 | 31 | input = "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\"rxpk\":[]}" 32 | 33 | decoded = Semtech::PushData.decode(input) 34 | 35 | assert_equal 0, decoded.token 36 | assert_equal EUI.new("00-00-00-00-00-00-00-00"), decoded.eui 37 | assert_nil decoded.stat 38 | 39 | end 40 | 41 | def test_encode_decode 42 | assert_kind_of Semtech::PushData, Semtech::Message.decode(@state.encode) 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /wrappers/ruby/test/rx_packet_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestRXPacket < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::RXPacket.new 10 | end 11 | 12 | def test_to_json_default 13 | @state.to_json 14 | end 15 | 16 | def test_from_h 17 | input = {} 18 | Semtech::RXPacket.from_h(input) 19 | end 20 | 21 | def test_encode_decode 22 | Semtech::RXPacket.from_h(JSON.parse(@state.to_json)) 23 | end 24 | 25 | end 26 | -------------------------------------------------------------------------------- /wrappers/ruby/test/status_packet_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestStatusPacket < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::StatusPacket.new 10 | end 11 | 12 | def test_to_json_default 13 | @state.to_json 14 | end 15 | 16 | def test_from_h 17 | input = {} 18 | Semtech::StatusPacket.from_h(input) 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /wrappers/ruby/test/tx_ack_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestTXAck < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::TXAck.new 10 | end 11 | 12 | def test_encode_default 13 | 14 | out = @state.encode 15 | 16 | iter = out.unpack("CS>Ca8a*").each 17 | 18 | assert_equal Semtech::Message::VERSION, iter.next 19 | iter.next 20 | 21 | assert_equal @state.class.type, iter.next 22 | 23 | assert_equal "\x00\x00\x00\x00\x00\x00\x00\x00", iter.next 24 | 25 | end 26 | 27 | def test_decode_default 28 | 29 | input = @state.encode 30 | 31 | input = "\x02\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00" 32 | 33 | decoded = Semtech::PullData.decode(input) 34 | 35 | assert_equal 0, decoded.token 36 | 37 | end 38 | 39 | def test_encode_decode 40 | assert_kind_of Semtech::TXAck, Semtech::Message.decode(@state.encode) 41 | end 42 | 43 | end 44 | -------------------------------------------------------------------------------- /wrappers/ruby/test/tx_packet_ack_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestTXPacketAck < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::TXPacketAck.new 10 | end 11 | 12 | def test_to_json_default 13 | @state.to_json 14 | end 15 | 16 | def test_from_h 17 | Semtech::TXPacketAck.from_h({}) 18 | end 19 | 20 | def test_encode_decode 21 | Semtech::TXPacketAck.from_h(JSON.parse(@state.to_json)) 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /wrappers/ruby/test/tx_packet_test.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'ldl' 3 | 4 | class TestTXPacket < Minitest::Test 5 | 6 | include LDL 7 | 8 | def setup 9 | @state = Semtech::TXPacket.new 10 | end 11 | 12 | def test_to_json_default 13 | @state.to_json 14 | end 15 | 16 | def test_from_h 17 | input = {} 18 | Semtech::TXPacket.from_h(input) 19 | end 20 | 21 | def test_encode_decode 22 | Semtech::TXPacket.from_h(JSON.parse(@state.to_json)) 23 | end 24 | 25 | def test_real 26 | input = JSON.parse('{"imme":false,"tmst":5113420,"freq":868.1,"rfch":0,"powe":14,"modu":"LORA","datr":"SF7BW125","codr":"4/5","ipol":true,"size":33,"ncrc":true,"data":"IIerSi1PqFMlnMUFB+dQbXjm0la2BtCQfCU5tKBL3eZN"}') 27 | Semtech::TXPacket.from_h(input) 28 | end 29 | 30 | end 31 | --------------------------------------------------------------------------------