diff --git a/CHANGELOG.md b/CHANGELOG.md index 7560d20..d5be17a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,47 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v4.8.0] 2024-12-20 + +This version is based on feature branch v4.5.0 of the LoRa Basics Modem. + +Detailed Modem API changelog can be found [here](lbm_lib/smtc_modem_api/CHANGELOG.md) +Detailed Modem HAL changelog can be found [here](lbm_lib/smtc_modem_hal/CHANGELOG.md) + +### Added + +* Support both Relay Rx and Relay Tx that follows LoRaWAN® Specification TS011-1.0.1 with compilation flag in app_options.mk +* Duty-cycle event to know when the Time On Air is reached or available +* Test-mode event + +### Changed + +* Enable CSMA by default for lbm_examples +* Update RAL with instantaneous power consumption obtained through BSP +* Implement the RAL BSP instantaneous power consumption getters for supported radio in examples +* [lr11xx-driver] Update lr11xx radio driver to v2.5.2 version ([CHANGELOG.md](lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/CHANGELOG.md)) +* [sx126x-driver] Update sx126x radio driver to v2.3.2 version ([CHANGELOG.md](lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/CHANGELOG.md)) + +### Fixed + +* FSK modulation, SNR and RSSI returned by the stack were not correct in class A/B/C +* LinkADRReq with ADR disabled do not answer the request correctly +* Remote Multicast Setup, time request in loop if no network coverage +* Backoff datarate must revert default channels and keeps as is others +* Fixed channel plan do not handle correctly bad CFlist type +* The modem keep the JoinDatarate distribution after joined if CSMA or LBT detect a possible collision during the first joinReq, or when the user leave before the end of a join and called the join +* TxParamSetupReq EIRP is not applied if a LinkADRReq is not received +* Speed up the certification in class B/C by applying on the fly the new requested periodicity +* LR-FHSS the values returned by `smtc_modem_get_charge()` is based on the center frequency +* LR-FHSS the values returned by `smtc_modem_get_duty_cycle_status()` is based on the center frequency +* Fix supervisor lorawan_manager for multi-stack support +* Issue [#83](https://github.com/Lora-net/SWL2001/issues/83) 2.4GHz is not working for LR1121 with STM32L476RG MCU +* Issue [#69](https://github.com/Lora-net/SWL2001/issues/69) Firmware Management Protocol, no DevUpgradeImageAns when the FW upgrade image is not valid +* Issue [#68](https://github.com/Lora-net/SWL2001/issues/68) aes_encrypt duplicate definition linking error +* Issue [#66](https://github.com/Lora-net/SWL2001/issues/66) Frequent store and forward uplinks if offline +* Issue [#62](https://github.com/Lora-net/SWL2001/issues/62) v4.5.0 relay_tx_check_decode_ack() does not calculate MIC according to TS011-1.0.0 +* Issue [#61](https://github.com/Lora-net/SWL2001/issues/61) Modem charge mAh with different configuration + ## [v4.5.0] 2024-05-06 This version is based on feature branch v4.3.1 of the LoRa Basics Modem. @@ -68,12 +109,12 @@ Detailed Modem API changelog can be found [here](lbm_lib/smtc_modem_api/CHANGELO * [relay] Issue [#28](https://github.com/Lora-net/SWL2001/issues/28) Fix backoff field parse in EndDeviceConfReq * [relay] Fix join request forwarding rules management for relay rx * [relay] Fix sync status for relay tx -* [relay] Fix backoff mecanism for relay tx +* [relay] Fix backoff mechanism for relay tx * [relay] Manage dual value of default channel for relay rx * [relay] Use real device crystal error for relay rx * [relay] WOR : Fix typo in b0 buffer for MIC computation * [relay] WOR : Use frequency step of 100Hz instead of real frequency in MIC -* [relay] WOR ACK : Fix AckUplinkEnc endianess +* [relay] WOR ACK : Fix AckUplinkEnc endianness * [relay] WOR ACK : Fix LoRa polarity * [relay] WOR ACK : Use frequency and datarate of WOR ACK in MIC * [relay] WOR ACK : Use frequency step of 100Hz instead of real frequency in MIC @@ -99,10 +140,10 @@ Detailed Modem HAL changelog can be found [here](lbm_lib/smtc_modem_hal/CHANGELO * Large File Upload (LFU) service and associated makefile option (related with LoRaCloud) * Stream service and associated makefile option (related with LoRaCloud) * Almanac Update service and associated makefile option (related with LoRaCloud) -* [general] Add a new folder `lbm_applications` that contains 3 specific implementation references on sereval MCU +* [general] Add a new folder `lbm_applications` that contains 3 specific implementation references on several MCU * [general] Real Time OS compatibility (add hal function `smtc_modem_hal_user_lbm_irq`) * [lr11xx-crypto] Re-add suspend/resume guard for lr11xx crypto access -* [makefile] Add `DEBUG_OPT` option to choose optimization in caseof DEBUG +* [makefile] Add `DEBUG_OPT` option to choose optimization in case of DEBUG ### Fixed @@ -122,12 +163,12 @@ Detailed Modem HAL changelog can be found [here](lbm_lib/smtc_modem_hal/CHANGELO ### Changed * [general] Change repository organization to ease readability. - Put all LoRa Basics Modem libraray related code in `lbm_lib` folder. + Put all LoRa Basics Modem library related code in `lbm_lib` folder. Rename `utilities` folder into `lbm_examples` for generic Lora Basics Modem examples * [lorawan-package] Change `lorawan_packages` folder organization to use a dedicated folder for each packages instead of fuota_v1 and fuota_V2 * [lr11xx-driver] Update lr11xx radio driver to v2.4.0 version ([CHANGELOG.md](lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/CHANGELOG.md)) -* [sx126x-driver] Update sx126x radio driver to v3.2.1 version ([CHANGELOG.md](lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/CHANGELOG.md)) +* [sx126x-driver] Update sx126x radio driver to v2.3.1 version ([CHANGELOG.md](lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/CHANGELOG.md)) * [sx128x-driver] Update sx128x radio driver to v1.0.0 version ([CHANGELOG.md](lbm_lib/smtc_modem_core/radio_drivers/sx128x_driver/CHANGELOG.md)) * [makefile] Set all LBM features options to `no` by default * [certification-service] Update certification service to support FUOTA certification @@ -138,8 +179,8 @@ This version is based on feature branch v4.1.0 of the LoRa Basics Modem. ### Added -* [lorawan-stack] Add Relay RX feature that follows LoRaWAN® Specification TS011-1.0.0 -* [lorawan-stack] Add Relay TX feature that follows LoRaWAN® Specification TS011-1.0.0 +* [lorawan-stack] Add Relay Rx feature that follows LoRaWAN® Specification TS011-1.0.0 +* [lorawan-stack] Add Relay Tx feature that follows LoRaWAN® Specification TS011-1.0.0 ## [v4.1.0] 2023-07-27 @@ -226,7 +267,7 @@ Detailed Modem HAL changelog can be found [here](smtc_modem_hal/CHANGELOG.md) * [general] Support of LR1121 radio (target: lr1121) * [makefile] Provide a way to change any LBM define values in make command (use `EXTRAFLAGS` ) -* [utilities] Add a porting on NUCLEO-L073 board using LL drivers for minimal flash usage +* [utilities] Add a porting on Nucleo-L073 board using LL drivers for minimal flash usage * [utilities] Add a porting tool in main examples to help during mcu porting ### Changed @@ -309,7 +350,7 @@ Detailed Modem HAL changelog can be found [here](smtc_modem_hal/CHANGELOG.md) * `smtc_modem_hal_get_radio_irq_timestamp_in_100us()` function * In `SMTC_MODEM_EVENT_DOWNDATA` event status: added new class B reception windows, fpending bit status, reception frequency and datarate * Middleware API for geolocation -* Add basic example to provide an easy start point on Nucleo L476 board +* Add basic example to provide an easy start point on Nucleo-L476 board ### Changed diff --git a/README.md b/README.md index 184c3b4..20018bc 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,21 @@ **LoRa Basic Modem** proposes an full implementation of the [TS001-LoRaWAN L2 1.0.4](https://resources.lora-alliance.org/technical-specifications/ts001-1-0-4-lorawan-l2-1-0-4-specification) and [Regional Parameters RP2-1.0.3](https://resources.lora-alliance.org/technical-specifications/rp2-1-0-3-lorawan-regional-parameters) specifications. -**LoRa Basic Modem** embedds also an implementation of all LoRaWAN packages dedicated to Firmware Update Over The Air (FUOTA): +**LoRa Basic Modem** embeds also an implementation of all LoRaWAN packages dedicated to Firmware Update Over The Air (FUOTA): + - Application Layer Clock Synchronization (ALCSync) - Remote Multicast Setup - Fragmented Data Block Transport - Firmware Management Protocol (FMP) - Multi-Package Access (MPA) -**LoRa Basic Modem** offers extended services: +**LoRa Basic Modem** embeds also an implementation the Relay LoRaWAN® Specification TS011-1.0.1 + +- Relay Tx +- Relay Rx + +**LoRa Basic Modem** offers extended services: + - LoRaWAN certification process - Geolocation with LoRa Edge chips - LoRaCloud features such as Stream, Large File Upload, Device Management or Almanac Update @@ -17,7 +24,7 @@ ## Prerequisites The ARM GCC tool chain must be setup under your development environment. -LBM library code has been developped using GNU Arm Embedded Toolchain 10-2020-q4-major 10.2.1 20201103 (release) +LBM library code has been developed using GNU Arm Embedded Toolchain 10-2020-q4-major 10.2.1 20201103 (release) ## LoRa Basics Modem library @@ -31,9 +38,9 @@ Under `lbm_examples` folder, one will find a few examples on how to use the LoRa - Hardware Modem (Implements a hardware modem controlled by a serial interface) - Periodical uplink (joins the network and then sends periodic uplinks and each time the button is pushed) - Porting tests (Allows to verify if the project porting process is correct) -- LCTT certification (to run LoRaWAN certification) +- LCTT certification (to run LoRaWAN certification) -The examples are targeted for the NucleoL476 kit featuring an STM32L476 micro-controller. +The examples are targeted for the Nucleo L476 kit featuring an STM32L476 micro-controller. For further details please refer to `lbm_examples` directory [README](lbm_examples/README.md) file. To build the periodical uplink example targeting the LR1110 Semtech radio the following should be executed on the command line: @@ -43,11 +50,12 @@ make -C lbm_examples full_lr1110 MODEM_APP=PERIODICAL_UPLINK ``` ## Applications + Under `lbm_applications` folder, one will find 3 specific applications that are using LoRa Basics Modem stack. -- A ThreadX Operationg System running on STM32U5 ([lbm_applications/1_thread_x_on_stm32_u5/README.md](lbm_applications/1_thread_x_on_stm32_u5/README.md)) +- A ThreadX Operating System running on STM32U5 ([lbm_applications/1_thread_x_on_stm32_u5/README.md](lbm_applications/1_thread_x_on_stm32_u5/README.md)) - A LBM porting on Nordic NRF52840 ([lbm_applications/2_porting_nrf_52840/README.md](lbm_applications/2_porting_nrf_52840/README.md)) -- A Geolocation application running on Lora Edge ([lbm_applications/3_geolocation_on_lora_edge/README.md](lbm_applications/3_geolocation_on_lora_edge/README.md)) +- A Geolocation application running on Lora Edge ([lbm_applications/3_geolocation_on_lora_edge/README.md](lbm_applications/3_geolocation_on_lora_edge/README.md)) An integration in Zephyr OS is available in another repository, instructions to download this integration and LoRa Basics Modem are available at [LBM_Zephyr](https://github.com/Lora-net/LBM_Zephyr/blob/master/README.md). diff --git a/lbm_applications/1_thread_x_on_stm32_u5/app_makefiles/app_common.mk b/lbm_applications/1_thread_x_on_stm32_u5/app_makefiles/app_common.mk index c85cf85..1fdc124 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/app_makefiles/app_common.mk +++ b/lbm_applications/1_thread_x_on_stm32_u5/app_makefiles/app_common.mk @@ -160,9 +160,31 @@ COMMON_C_DEFS += \ -DMAKEFILE_APP=${MODEM_APP} endif + ifeq ($(MODEM_APP),HW_MODEM) + +# git defines +ifneq (, $(shell which git)) +GIT_VERSION := $(shell git --no-pager describe --tags --always) +GIT_COMMIT := $(shell git rev-parse --verify HEAD) +GIT_DATE := $(firstword $(shell git --no-pager show --date=iso-strict --format="%ad" --name-only)) +BUILD_DATE := $(shell date --iso=seconds) +SHORT_DATE := $(shell date +%Y-%m-%d-%H-%M) + +# If working tree is dirty, append dirty flag +ifneq ($(strip $(shell git status --porcelain 2>/dev/null)),) +GIT_VERSION := $(GIT_VERSION)--dirty +endif +endif + COMMON_C_DEFS += \ - -DHW_MODEM_ENABLED + -DHW_MODEM_ENABLED \ + -DGIT_VERSION=\"$(GIT_VERSION)\" \ + -DGIT_COMMIT=\"$(GIT_COMMIT)\" \ + -DGIT_DATE=\"$(GIT_DATE)\" \ + -DBUILD_DATE=\"$(BUILD_DATE)\" +LBM_BUILD_OPTIONS += REGION=ALL LBM_STREAM=yes LBM_LFU=yes LBM_DEVICE_MANAGEMENT=yes LBM_CLASS_B=yes LBM_CLASS_C=yes LBM_MULTICAST=yes LBM_CSMA=yes +ALLOW_FUOTA=yes endif ifeq ($(APP_TRACE),yes) diff --git a/lbm_applications/1_thread_x_on_stm32_u5/main_examples/cmd_parser.c b/lbm_applications/1_thread_x_on_stm32_u5/main_examples/cmd_parser.c index 77a10af..133dbd3 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/main_examples/cmd_parser.c +++ b/lbm_applications/1_thread_x_on_stm32_u5/main_examples/cmd_parser.c @@ -37,13 +37,17 @@ * --- DEPENDENCIES ------------------------------------------------------------ */ -#include // C99 types -#include // bool type +#include // C99 types +#include // bool type #include "cmd_parser.h" #include "smtc_modem_test_api.h" #include "smtc_modem_api.h" +#if defined(ADD_APP_GEOLOCATION) +#include "smtc_modem_geolocation_api.h" +#include "lr11xx_hal.h" +#endif #include "smtc_modem_hal.h" #include "smtc_hal_dbg_trace.h" @@ -53,10 +57,11 @@ #include "smtc_hal_mcu.h" #include "radio_utilities.h" -#include"app_threadx.h" - -#include //for memset +#include //for memset +#if defined(USE_RELAY_TX) +#include "smtc_modem_relay_api.h" +#endif /* * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- @@ -68,14 +73,13 @@ */ #define STACK_ID 0 -#if defined( STM32L073xx ) +#if defined(STM32L073xx) #define FILE_UPLOAD_MAX_SIZE 4096 #else #define FILE_UPLOAD_MAX_SIZE 8192 #endif -#define MODEM_MAX_INFO_FIELD_SIZE 17 - +#define MODEM_MAX_INFO_FIELD_SIZE 19 /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -87,8 +91,8 @@ typedef enum host_cmd_tab_idx_e { HOST_CMD_TAB_IDX_AVAILABILITY = 0, - HOST_CMD_TAB_IDX_MIN_LENGTH = 1, - HOST_CMD_TAB_IDX_MAX_LENGTH = 2, + HOST_CMD_TAB_IDX_MIN_LENGTH = 1, + HOST_CMD_TAB_IDX_MAX_LENGTH = 2, HOST_CMD_TAB_IDX_COUNT, } host_cmd_tab_idx_t; @@ -114,109 +118,165 @@ typedef enum upload_status_e * --- PRIVATE VARIABLES ------------------------------------------------------- */ -static bool modem_in_test_mode = false; -static smtc_modem_dl_metadata_t last_dl_metadata = { 0 }; +static bool modem_in_test_mode = false; +static smtc_modem_dl_metadata_t last_dl_metadata = {0}; // LFU handling -static uint8_t file_store[FILE_UPLOAD_MAX_SIZE] = { 0 }; -static uint16_t file_size = 0; -static uint16_t upload_current_size = 0; -static upload_status_t upload_status = UPLOAD_NOT_INIT; +static uint8_t file_store[FILE_UPLOAD_MAX_SIZE] = {0}; +static uint16_t file_size = 0; +static uint16_t upload_current_size = 0; +static upload_status_t upload_status = UPLOAD_NOT_INIT; + +#if defined(ADD_APP_GEOLOCATION) && defined(STM32L476xx) +// Geolocation handling +static smtc_modem_gnss_event_data_scan_done_t gnss_scan_data = {0}; +static cmd_serial_rc_code_t gnss_scan_done_rc = CMD_RC_FAIL; +#endif // ADD_APP_GEOLOCATION && STM32L476xx /** * @brief Modem commands tab for availability, min length and max length * */ static const uint8_t host_cmd_tab[CMD_MAX][HOST_CMD_TAB_IDX_COUNT] = { -// [CMD_xxx] = {availability, len_min, len_max} - [CMD_RESET] = { 1, 0, 0 }, - [CMD_SET_REGION] = { 1, 1, 1 }, - [CMD_GET_REGION] = { 1, 0, 0 }, - [CMD_JOIN_NETWORK] = { 1, 0, 0 }, - [CMD_REQUEST_UPLINK] = { 1, 2, 244 }, - [CMD_GET_EVENT] = { 1, 0, 0 }, - [CMD_GET_DOWNLINK_DATA] = { 1, 0, 0 }, - [CMD_GET_DOWNLINK_METADATA] = { 1, 0, 0 }, - [CMD_GET_JOIN_EUI] = { 1, 0, 0 }, - [CMD_SET_JOIN_EUI] = { 1, 8, 8 }, - [CMD_GET_DEV_EUI] = { 1, 0, 0 }, - [CMD_SET_DEV_EUI] = { 1, 8, 8 }, - [CMD_SET_NWKKEY] = { 1, 16, 16 }, - [CMD_GET_PIN] = { 1, 0, 0 }, - [CMD_GET_CHIP_EUI] = { 1, 0, 0 }, - [CMD_DERIVE_KEYS] = { 1, 0, 0 }, - [CMD_GET_MODEM_VERSION] = { 1, 0, 0 }, - [CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER] = { 1, 0, 0 }, - [CMD_SET_CERTIFICATION_MODE] = { 1, 1, 1 }, - [CMD_EMERGENCY_UPLINK] = { 1, 2, 244 }, - [CMD_REQUEST_EMPTY_UPLINK] = { 1, 3, 3 }, - [CMD_LEAVE_NETWORK] = { 1, 0, 0 }, - [CMD_ALARM_START_TIMER] = { 1, 4, 4 }, - [CMD_ALARM_CLEAR_TIMER] = { 1, 0, 0 }, - [CMD_ALARM_GET_REMAINING_TIME] = { 1, 0, 0 }, - [CMD_GET_NEXT_TX_MAX_PAYLOAD] = { 1, 0, 0 }, - [CMD_GET_DUTY_CYCLE_STATUS] = { 1, 0, 0 }, - [CMD_SET_NETWORK_TYPE] = { 1, 1, 1 }, - [CMD_SET_JOIN_DR_DISTRIBUTION] = { 1, 16, 16 }, - [CMD_SET_ADR_PROFILE] = { 1, 1, 17 }, - [CMD_SET_NB_TRANS] = { 1, 1, 1 }, - [CMD_GET_NB_TRANS] = { 1, 0, 0 }, - [CMD_GET_ENABLED_DATARATE] = { 1, 0, 0 }, - [CMD_SET_ADR_ACK_LIMIT_DELAY] = { 1, 2, 2}, - [CMD_GET_ADR_ACK_LIMIT_DELAY] = { 1, 0, 0}, - [CMD_SET_CRYSTAL_ERR] = { 1, 4, 4 }, - [CMD_LBT_SET_PARAMS] = { 1, 10, 10 }, - [CMD_LBT_GET_PARAMS] = { 1, 0, 0 }, - [CMD_LBT_SET_STATE] = { 1, 1, 1 }, - [CMD_LBT_GET_STATE] = { 1, 0, 0 }, - [CMD_GET_CHARGE] = { 1, 0, 0 }, - [CMD_RESET_CHARGE] = { 1, 0, 0 }, - [CMD_SET_CLASS] = { 1, 1, 1 }, - [CMD_CLASS_B_SET_PING_SLOT_PERIODICITY] = { 1, 1, 1, }, - [CMD_CLASS_B_GET_PING_SLOT_PERIODICITY] = { 1, 0, 0, }, - [CMD_MULTICAST_SET_GROUP_CONFIG] = { 1, 37, 37 }, - [CMD_MULTICAST_GET_GROUP_CONFIG] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_C_START_SESSION] = { 1, 6, 6 }, - [CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_C_STOP_SESSION] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS] = { 1, 0, 0 }, - [CMD_MULTICAST_CLASS_B_START_SESSION] = { 1, 7, 7 }, - [CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_B_STOP_SESSION] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS] = { 1, 0, 0 }, - [CMD_START_ALCSYNC_SERVICE] = { 1, 0, 0 }, - [CMD_STOP_ALCSYNC_SERVICE] = { 1, 0, 0 }, - [CMD_GET_ALCSYNC_TIME] = { 1, 0, 0 }, - [CMD_TRIG_ALCSYNC_REQUEST] = { 1, 0, 0 }, - [CMD_LORAWAN_MAC_REQUEST] = { 1, 1, 1 }, - [CMD_GET_LORAWAN_TIME] = { 1, 0, 0}, - [CMD_GET_LINK_CHECK_DATA] = { 1, 0, 0 }, - [CMD_SET_DUTY_CYCLE_STATE] = { 1, 1, 1 }, - [CMD_DEBUG_CONNECT_WITH_ABP] = { 1, 36, 36 }, - [CMD_TEST] = { 1, 1, 255 }, - [CMD_GET_TX_POWER_OFFSET] = { 1, 0, 0 }, - [CMD_SET_TX_POWER_OFFSET] = { 1, 1, 1 }, - [CMD_CSMA_SET_STATE] = { 1, 1, 1 }, - [CMD_CSMA_GET_STATE] = { 1, 0, 0 }, - [CMD_CSMA_SET_PARAMETERS] = { 1, 3, 3 }, - [CMD_CSMA_GET_PARAMETERS] = { 1, 0, 0 }, - [CMD_STREAM_INIT] = { 1, 3, 3 }, - [CMD_STREAM_ADD_DATA] = { 1, 1, 255 }, - [CMD_STREAM_STATUS] = { 1, 0, 0 }, - [CMD_LFU_INIT] = { 1, 6, 6 }, - [CMD_LFU_DATA] = { 1, 0, 255 }, - [CMD_LFU_START] = { 1, 4, 4 }, - [CMD_LFU_RESET] = { 1, 0, 0 }, - [CMD_DM_ENABLE] = { 1, 1, 1 }, - [CMD_DM_GET_PORT] = { 1, 0, 0 }, - [CMD_DM_SET_PORT] = { 1, 1, 1 }, - [CMD_DM_GET_INFO_INTERVAL] = { 1, 0, 0 }, - [CMD_DM_SET_INFO_INTERVAL] = { 1, 1, 1 }, - [CMD_DM_GET_PERIODIC_INFO_FIELDS] = { 1, 0, 0 }, - [CMD_DM_SET_PERIODIC_INFO_FIELDS] = { 1, 0, MODEM_MAX_INFO_FIELD_SIZE }, - [CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS] = { 1, 0, MODEM_MAX_INFO_FIELD_SIZE }, - [CMD_DM_SET_USER_DATA] = { 1, 0, SMTC_MODEM_DM_USER_DATA_LENGTH }, - [CMD_DM_GET_USER_DATA] = { 1, 0, 0 }, + // [CMD_xxx] = {availability, len_min, len_max} + [CMD_RESET] = {1, 0, 0}, + [CMD_SET_REGION] = {1, 1, 1}, + [CMD_GET_REGION] = {1, 0, 0}, + [CMD_JOIN_NETWORK] = {1, 0, 0}, + [CMD_REQUEST_UPLINK] = {1, 2, 244}, + [CMD_GET_EVENT] = {1, 0, 0}, + [CMD_GET_DOWNLINK_DATA] = {1, 0, 0}, + [CMD_GET_DOWNLINK_METADATA] = {1, 0, 0}, + [CMD_GET_JOIN_EUI] = {1, 0, 0}, + [CMD_SET_JOIN_EUI] = {1, 8, 8}, + [CMD_GET_DEV_EUI] = {1, 0, 0}, + [CMD_SET_DEV_EUI] = {1, 8, 8}, + [CMD_SET_NWKKEY] = {1, 16, 16}, + [CMD_GET_PIN] = {1, 0, 0}, + [CMD_GET_CHIP_EUI] = {1, 0, 0}, + [CMD_DERIVE_KEYS] = {1, 0, 0}, + [CMD_GET_MODEM_VERSION] = {1, 0, 0}, + [CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER] = {1, 0, 0}, + [CMD_SET_CERTIFICATION_MODE] = {1, 1, 1}, + [CMD_EMERGENCY_UPLINK] = {1, 2, 244}, + [CMD_REQUEST_EMPTY_UPLINK] = {1, 3, 3}, + [CMD_LEAVE_NETWORK] = {1, 0, 0}, + [CMD_ALARM_START_TIMER] = {1, 4, 4}, + [CMD_ALARM_CLEAR_TIMER] = {1, 0, 0}, + [CMD_ALARM_GET_REMAINING_TIME] = {1, 0, 0}, + [CMD_GET_NEXT_TX_MAX_PAYLOAD] = {1, 0, 0}, + [CMD_GET_DUTY_CYCLE_STATUS] = {1, 0, 0}, + [CMD_SET_NETWORK_TYPE] = {1, 1, 1}, + [CMD_SET_JOIN_DR_DISTRIBUTION] = {1, 16, 16}, + [CMD_SET_ADR_PROFILE] = {1, 1, 17}, + [CMD_SET_NB_TRANS] = {1, 1, 1}, + [CMD_GET_NB_TRANS] = {1, 0, 0}, + [CMD_GET_ENABLED_DATARATE] = {1, 0, 0}, + [CMD_SET_ADR_ACK_LIMIT_DELAY] = {1, 2, 2}, + [CMD_GET_ADR_ACK_LIMIT_DELAY] = {1, 0, 0}, + [CMD_SET_CRYSTAL_ERR] = {1, 4, 4}, + [CMD_LBT_SET_PARAMS] = {1, 10, 10}, + [CMD_LBT_GET_PARAMS] = {1, 0, 0}, + [CMD_LBT_SET_STATE] = {1, 1, 1}, + [CMD_LBT_GET_STATE] = {1, 0, 0}, + [CMD_GET_CHARGE] = {1, 0, 0}, + [CMD_RESET_CHARGE] = {1, 0, 0}, + [CMD_SET_CLASS] = {1, 1, 1}, + [CMD_CLASS_B_SET_PING_SLOT_PERIODICITY] = {1, 1, 1}, + [CMD_CLASS_B_GET_PING_SLOT_PERIODICITY] = {1, 0, 0}, + [CMD_MULTICAST_SET_GROUP_CONFIG] = {1, 37, 37}, + [CMD_MULTICAST_GET_GROUP_CONFIG] = {1, 1, 1}, + [CMD_MULTICAST_CLASS_C_START_SESSION] = {1, 6, 6}, + [CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS] = {1, 1, 1}, + [CMD_MULTICAST_CLASS_C_STOP_SESSION] = {1, 1, 1}, + [CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS] = {1, 0, 0}, + [CMD_MULTICAST_CLASS_B_START_SESSION] = {1, 7, 7}, + [CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS] = {1, 1, 1}, + [CMD_MULTICAST_CLASS_B_STOP_SESSION] = {1, 1, 1}, + [CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS] = {1, 0, 0}, + [CMD_START_ALCSYNC_SERVICE] = {1, 0, 0}, + [CMD_STOP_ALCSYNC_SERVICE] = {1, 0, 0}, + [CMD_GET_ALCSYNC_TIME] = {1, 0, 0}, + [CMD_TRIG_ALCSYNC_REQUEST] = {1, 0, 0}, + [CMD_LORAWAN_MAC_REQUEST] = {1, 1, 1}, + [CMD_GET_LORAWAN_TIME] = {1, 0, 0}, + [CMD_GET_LINK_CHECK_DATA] = {1, 0, 0}, + [CMD_SET_DUTY_CYCLE_STATE] = {1, 1, 1}, + [CMD_DEBUG_CONNECT_WITH_ABP] = {1, 36, 36}, + [CMD_TEST] = {1, 1, 255}, + [CMD_GET_TX_POWER_OFFSET] = {1, 0, 0}, + [CMD_SET_TX_POWER_OFFSET] = {1, 1, 1}, + [CMD_CSMA_SET_STATE] = {1, 1, 1}, + [CMD_CSMA_GET_STATE] = {1, 0, 0}, + [CMD_CSMA_SET_PARAMETERS] = {1, 3, 3}, + [CMD_CSMA_GET_PARAMETERS] = {1, 0, 0}, + [CMD_STREAM_INIT] = {1, 3, 3}, + [CMD_STREAM_ADD_DATA] = {1, 1, 255}, + [CMD_STREAM_STATUS] = {1, 0, 0}, + [CMD_LFU_INIT] = {1, 6, 6}, + [CMD_LFU_DATA] = {1, 0, 255}, + [CMD_LFU_START] = {1, 4, 4}, + [CMD_LFU_RESET] = {1, 0, 0}, + [CMD_DM_ENABLE] = {1, 1, 1}, + [CMD_DM_GET_PORT] = {1, 0, 0}, + [CMD_DM_SET_PORT] = {1, 1, 1}, + [CMD_DM_GET_INFO_INTERVAL] = {1, 0, 0}, + [CMD_DM_SET_INFO_INTERVAL] = {1, 1, 1}, + [CMD_DM_GET_PERIODIC_INFO_FIELDS] = {1, 0, 0}, + [CMD_DM_SET_PERIODIC_INFO_FIELDS] = {1, 0, MODEM_MAX_INFO_FIELD_SIZE}, + [CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS] = {1, 0, MODEM_MAX_INFO_FIELD_SIZE}, + [CMD_DM_SET_USER_DATA] = {1, SMTC_MODEM_DM_USER_DATA_LENGTH, SMTC_MODEM_DM_USER_DATA_LENGTH}, + [CMD_DM_GET_USER_DATA] = {1, 0, 0}, + [CMD_GET_STATUS] = {1, 0, 0}, + [CMD_SUSPEND_RADIO_COMMUNICATIONS] = {1, 1, 1}, + [CMD_GET_SUSPEND_RADIO_COMMUNICATIONS] = {1, 0, 0}, + [CMD_DM_HANDLE_ALCSYNC] = {1, 1, 1}, + [CMD_SET_APPKEY] = {1, 16, 16}, + [CMD_GET_ADR_PROFILE] = {1, 0, 0}, + [CMD_GET_CERTIFICATION_MODE] = {1, 0, 0}, +#if defined(STM32L476xx) + [CMD_STORE_AND_FORWARD_SET_STATE] = {1, 1, 1}, + [CMD_STORE_AND_FORWARD_GET_STATE] = {1, 0, 0}, + [CMD_STORE_AND_FORWARD_ADD_DATA] = {1, 2, 244}, + [CMD_STORE_AND_FORWARD_CLEAR_DATA] = {1, 0, 0}, + [CMD_STORE_AND_FORWARD_GET_FREE_SLOT] = {1, 0, 0}, +#endif // STM32L476xx +#if defined(ADD_APP_GEOLOCATION) && defined(STM32L476xx) + [CMD_GNSS_SCAN] = {1, 5, 5}, + [CMD_GNSS_SCAN_CANCEL] = {1, 0, 0}, + [CMD_GNSS_GET_EVENT_DATA_SCAN_DONE] = {1, 0, 0}, + [CMD_GNSS_GET_SCAN_DONE_RAW_DATA_LIST] = {1, 0, 0}, + [CMD_GNSS_GET_SCAN_DONE_METADATA_LIST] = {1, 0, 0}, + [CMD_GNSS_GET_SCAN_DONE_SCAN_SV] = {1, 0, 0}, + [CMD_GNSS_GET_EVENT_DATA_TERMINATED] = {1, 0, 0}, + [CMD_GNSS_SET_CONST] = {1, 1, 1}, + [CMD_GNSS_SET_PORT] = {1, 1, 1}, + [CMD_GNSS_SCAN_AGGREGATE] = {1, 1, 1}, + [CMD_GNSS_SEND_MODE] = {1, 1, 1}, + [CMD_GNSS_ALM_DEMOD_START] = {1, 0, 0}, + [CMD_GNSS_ALM_DEMOD_SET_CONSTEL] = {1, 1, 1}, + [CMD_GNSS_ALM_DEMOD_GET_EVENT_DATA_ALM_UPD] = {1, 0, 0}, + [CMD_CLOUD_ALMANAC_START] = {1, 0, 0}, + [CMD_CLOUD_ALMANAC_STOP] = {1, 0, 0}, + [CMD_WIFI_SCAN_START] = {1, 4, 4}, + [CMD_WIFI_SCAN_CANCEL] = {1, 0, 0}, + [CMD_WIFI_GET_SCAN_DONE_SCAN_DATA] = {1, 0, 0}, + [CMD_WIFI_GET_EVENT_DATA_TERMINATED] = {1, 0, 0}, + [CMD_WIFI_SET_PORT] = {1, 1, 1}, + [CMD_WIFI_SEND_MODE] = {1, 1, 1}, + [CMD_WIFI_SET_PAYLOAD_FORMAT] = {1, 1, 1}, + [CMD_LR11XX_RADIO_READ] = {1, 0, 255}, + [CMD_LR11XX_RADIO_WRITE] = {1, 0, 255}, + +#endif // ADD_APP_GEOLOCATION && STM32L476xx + [CMD_SET_RTC_OFFSET] = {1, 4, 4}, +#if defined(USE_RELAY_TX) + [CMD_SET_RELAY_CONFIG] = {1, 10, 24}, + [CMD_GET_RELAY_CONFIG] = {1, 0, 0}, +#endif // ADD_RELAY_TX_CMD + [CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = {1, 0, 0}, + [CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = {1, 1, 1}, + [CMD_MODEM_GET_CRASHLOG] = {1, 0, 0}, }; /** @@ -225,25 +285,25 @@ static const uint8_t host_cmd_tab[CMD_MAX][HOST_CMD_TAB_IDX_COUNT] = { */ static const uint8_t host_cmd_test_tab[CMD_TST_MAX][HOST_CMD_TAB_IDX_COUNT] = { // [CMD_xxx] = {availability, len_min, len_max} - [CMD_TST_START] = { 1, 8, 8 }, - [CMD_TST_NOP] = { 1, 0, 0 }, - [CMD_TST_TX_SINGLE] = { 1, 9, 9 }, - [CMD_TST_TX_CONT] = { 1, 9, 9 }, - [CMD_TST_TX_HOP] = { 1, 4, 4 }, - [CMD_TST_NA_1] = { 1, 0, 0 }, - [CMD_TST_TX_CW] = { 1, 5, 5 }, - [CMD_TST_RX_CONT] = { 1, 7, 7 }, - [CMD_TST_RSSI] = { 1, 7, 7 }, - [CMD_TST_RADIO_RST] = { 1, 0, 0 }, - [CMD_TST_EXIT] = { 1, 0, 0 }, - [CMD_TST_BUSYLOOP] = { 1, 0, 0 }, - [CMD_TST_PANIC] = { 1, 0, 0 }, - [CMD_TST_WATCHDOG] = { 1, 0, 0 }, - [CMD_TST_RADIO_READ] = { 1, 0, 255 }, - [CMD_TST_RADIO_WRITE] = { 1, 0, 255 }, - [CMD_TST_TX_SINGLE_PREAM] = { 1, 11, 11 }, - [CMD_TST_RSSI_GET] = { 1, 0, 0 }, - [CMD_TST_READ_NB_PKTS_RX_CONT] = { 1, 0, 0 }, + [CMD_TST_START] = {1, 8, 8}, // + [CMD_TST_EXIT] = {1, 0, 0}, // + [CMD_TST_NOP] = {1, 0, 0}, // + [CMD_TST_TX_LORA] = {1, 25, 25}, // + [CMD_TST_TX_FSK] = {1, 14, 14}, // + [CMD_TST_TX_LRFHSS] = {1, 18, 18}, // + [CMD_TST_TX_CW] = {1, 5, 5}, // + [CMD_TST_RX_LORA] = {1, 16, 16}, // + [CMD_TST_RX_FSK_CONT] = {1, 4, 4}, // + [CMD_TST_READ_NB_PKTS_RX] = {1, 0, 0}, // + [CMD_TST_READ_LAST_RX_PKT] = {1, 0, 0}, // + [CMD_TST_RSSI] = {1, 10, 10}, // + [CMD_TST_RSSI_GET] = {1, 0, 0}, // + [CMD_TST_RADIO_RST] = {1, 0, 0}, // + [CMD_TST_BUSYLOOP] = {1, 0, 0}, // + [CMD_TST_PANIC] = {1, 0, 0}, // + [CMD_TST_WATCHDOG] = {1, 0, 0}, // + [CMD_TST_RADIO_READ] = {1, 0, 255}, // + [CMD_TST_RADIO_WRITE] = {1, 0, 255}, // }; #if HAL_DBG_TRACE == HAL_FEATURE_ON @@ -251,95 +311,144 @@ static const uint8_t host_cmd_test_tab[CMD_TST_MAX][HOST_CMD_TAB_IDX_COUNT] = { * @brief Host command string names for print purpose * */ -static const char* host_cmd_str[CMD_MAX] = { - [CMD_RESET] = "CMD_RESET", - [CMD_SET_REGION] = "CMD_SET_REGION", - [CMD_GET_REGION] = "CMD_GET_REGION", - [CMD_JOIN_NETWORK] = "CMD_JOIN_NETWORK", - [CMD_REQUEST_UPLINK] = "CMD_REQUEST_UPLINK", - [CMD_GET_EVENT] = "CMD_GET_EVENT", - [CMD_GET_DOWNLINK_DATA] = "CMD_GET_DOWNLINK_DATA", - [CMD_GET_DOWNLINK_METADATA] = "CMD_GET_DOWNLINK_METADATA", - [CMD_GET_JOIN_EUI] = "CMD_GET_JOIN_EUI", - [CMD_SET_JOIN_EUI] = "CMD_SET_JOIN_EUI", - [CMD_GET_DEV_EUI] = "CMD_GET_DEV_EUI", - [CMD_SET_DEV_EUI] = "CMD_SET_DEV_EUI", - [CMD_SET_NWKKEY] = "CMD_SET_NWKKEY", - [CMD_GET_PIN] = "CMD_GET_PIN", - [CMD_GET_CHIP_EUI] = "CMD_GET_CHIP_EUI", - [CMD_DERIVE_KEYS] = "CMD_DERIVE_KEYS", - [CMD_GET_MODEM_VERSION] = "CMD_GET_MODEM_VERSION", - [CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER] = "CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER", - [CMD_SET_CERTIFICATION_MODE] = "CMD_SET_CERTIFICATION_MODE", - [CMD_EMERGENCY_UPLINK] = "CMD_EMERGENCY_UPLINK", - [CMD_REQUEST_EMPTY_UPLINK] = "CMD_REQUEST_EMPTY_UPLINK", - [CMD_LEAVE_NETWORK] = "CMD_LEAVE_NETWORK", - [CMD_ALARM_START_TIMER] = "CMD_ALARM_START_TIMER", - [CMD_ALARM_CLEAR_TIMER] = "CMD_ALARM_CLEAR_TIMER", - [CMD_ALARM_GET_REMAINING_TIME] = "CMD_ALARM_GET_REMAINING_TIME", - [CMD_GET_NEXT_TX_MAX_PAYLOAD] = "CMD_GET_NEXT_TX_MAX_PAYLOAD", - [CMD_GET_DUTY_CYCLE_STATUS] = "CMD_GET_DUTY_CYCLE_STATUS", - [CMD_SET_NETWORK_TYPE] = "CMD_SET_NETWORK_TYPE", - [CMD_SET_JOIN_DR_DISTRIBUTION] = "CMD_SET_JOIN_DR_DISTRIBUTION", - [CMD_SET_ADR_PROFILE] = "CMD_SET_ADR_PROFILE", - [CMD_SET_NB_TRANS] = "CMD_SET_NB_TRANS", - [CMD_GET_NB_TRANS] = "CMD_GET_NB_TRANS", - [CMD_GET_ENABLED_DATARATE] = "CMD_GET_ENABLED_DATARATE", - [CMD_SET_ADR_ACK_LIMIT_DELAY] = "CMD_SET_ADR_ACK_LIMIT_DELAY", - [CMD_GET_ADR_ACK_LIMIT_DELAY] = "CMD_GET_ADR_ACK_LIMIT_DELAY", - [CMD_SET_CRYSTAL_ERR] = "CMD_SET_CRYSTAL_ERR", - [CMD_LBT_SET_PARAMS] = "CMD_LBT_SET_PARAMS", - [CMD_LBT_GET_PARAMS] = "CMD_LBT_GET_PARAMS", - [CMD_LBT_SET_STATE] = "CMD_LBT_SET_STATE", - [CMD_LBT_GET_STATE] = "CMD_LBT_GET_STATE", - [CMD_GET_CHARGE] = "CMD_GET_CHARGE", - [CMD_RESET_CHARGE] = "CMD_RESET_CHARGE", - [CMD_SET_CLASS] = "CMD_SET_CLASS", - [CMD_CLASS_B_SET_PING_SLOT_PERIODICITY] = "CMD_CLASS_B_SET_PING_SLOT_PERIODICITY", - [CMD_CLASS_B_GET_PING_SLOT_PERIODICITY] = "CMD_CLASS_B_GET_PING_SLOT_PERIODICITY", - [CMD_MULTICAST_SET_GROUP_CONFIG] = "CMD_MULTICAST_SET_GROUP_CONFIG", - [CMD_MULTICAST_GET_GROUP_CONFIG] = "CMD_MULTICAST_GET_GROUP_CONFIG", - [CMD_MULTICAST_CLASS_C_START_SESSION] = "CMD_MULTICAST_CLASS_C_START_SESSION", +static const char *host_cmd_str[CMD_MAX] = { + [CMD_RESET] = "CMD_RESET", + [CMD_SET_REGION] = "CMD_SET_REGION", + [CMD_GET_REGION] = "CMD_GET_REGION", + [CMD_JOIN_NETWORK] = "CMD_JOIN_NETWORK", + [CMD_REQUEST_UPLINK] = "CMD_REQUEST_UPLINK", + [CMD_GET_EVENT] = "CMD_GET_EVENT", + [CMD_GET_DOWNLINK_DATA] = "CMD_GET_DOWNLINK_DATA", + [CMD_GET_DOWNLINK_METADATA] = "CMD_GET_DOWNLINK_METADATA", + [CMD_GET_JOIN_EUI] = "CMD_GET_JOIN_EUI", + [CMD_SET_JOIN_EUI] = "CMD_SET_JOIN_EUI", + [CMD_GET_DEV_EUI] = "CMD_GET_DEV_EUI", + [CMD_SET_DEV_EUI] = "CMD_SET_DEV_EUI", + [CMD_SET_NWKKEY] = "CMD_SET_NWKKEY", + [CMD_GET_PIN] = "CMD_GET_PIN", + [CMD_GET_CHIP_EUI] = "CMD_GET_CHIP_EUI", + [CMD_DERIVE_KEYS] = "CMD_DERIVE_KEYS", + [CMD_GET_MODEM_VERSION] = "CMD_GET_MODEM_VERSION", + [CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER] = "CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER", + [CMD_SET_CERTIFICATION_MODE] = "CMD_SET_CERTIFICATION_MODE", + [CMD_EMERGENCY_UPLINK] = "CMD_EMERGENCY_UPLINK", + [CMD_REQUEST_EMPTY_UPLINK] = "CMD_REQUEST_EMPTY_UPLINK", + [CMD_LEAVE_NETWORK] = "CMD_LEAVE_NETWORK", + [CMD_ALARM_START_TIMER] = "CMD_ALARM_START_TIMER", + [CMD_ALARM_CLEAR_TIMER] = "CMD_ALARM_CLEAR_TIMER", + [CMD_ALARM_GET_REMAINING_TIME] = "CMD_ALARM_GET_REMAINING_TIME", + [CMD_GET_NEXT_TX_MAX_PAYLOAD] = "CMD_GET_NEXT_TX_MAX_PAYLOAD", + [CMD_GET_DUTY_CYCLE_STATUS] = "CMD_GET_DUTY_CYCLE_STATUS", + [CMD_SET_NETWORK_TYPE] = "CMD_SET_NETWORK_TYPE", + [CMD_SET_JOIN_DR_DISTRIBUTION] = "CMD_SET_JOIN_DR_DISTRIBUTION", + [CMD_SET_ADR_PROFILE] = "CMD_SET_ADR_PROFILE", + [CMD_SET_NB_TRANS] = "CMD_SET_NB_TRANS", + [CMD_GET_NB_TRANS] = "CMD_GET_NB_TRANS", + [CMD_GET_ENABLED_DATARATE] = "CMD_GET_ENABLED_DATARATE", + [CMD_SET_ADR_ACK_LIMIT_DELAY] = "CMD_SET_ADR_ACK_LIMIT_DELAY", + [CMD_GET_ADR_ACK_LIMIT_DELAY] = "CMD_GET_ADR_ACK_LIMIT_DELAY", + [CMD_SET_CRYSTAL_ERR] = "CMD_SET_CRYSTAL_ERR", + [CMD_LBT_SET_PARAMS] = "CMD_LBT_SET_PARAMS", + [CMD_LBT_GET_PARAMS] = "CMD_LBT_GET_PARAMS", + [CMD_LBT_SET_STATE] = "CMD_LBT_SET_STATE", + [CMD_LBT_GET_STATE] = "CMD_LBT_GET_STATE", + [CMD_GET_CHARGE] = "CMD_GET_CHARGE", + [CMD_RESET_CHARGE] = "CMD_RESET_CHARGE", + [CMD_SET_CLASS] = "CMD_SET_CLASS", + [CMD_CLASS_B_SET_PING_SLOT_PERIODICITY] = "CMD_CLASS_B_SET_PING_SLOT_PERIODICITY", + [CMD_CLASS_B_GET_PING_SLOT_PERIODICITY] = "CMD_CLASS_B_GET_PING_SLOT_PERIODICITY", + [CMD_MULTICAST_SET_GROUP_CONFIG] = "CMD_MULTICAST_SET_GROUP_CONFIG", + [CMD_MULTICAST_GET_GROUP_CONFIG] = "CMD_MULTICAST_GET_GROUP_CONFIG", + [CMD_MULTICAST_CLASS_C_START_SESSION] = "CMD_MULTICAST_CLASS_C_START_SESSION", [CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS] = "CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS", - [CMD_MULTICAST_CLASS_C_STOP_SESSION] = "CMD_MULTICAST_CLASS_C_STOP_SESSION", - [CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS] = "CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS", - [CMD_MULTICAST_CLASS_B_START_SESSION] = "CMD_MULTICAST_CLASS_B_START_SESSION", + [CMD_MULTICAST_CLASS_C_STOP_SESSION] = "CMD_MULTICAST_CLASS_C_STOP_SESSION", + [CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS] = "CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS", + [CMD_MULTICAST_CLASS_B_START_SESSION] = "CMD_MULTICAST_CLASS_B_START_SESSION", [CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS] = "CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS", - [CMD_MULTICAST_CLASS_B_STOP_SESSION] = "CMD_MULTICAST_CLASS_B_STOP_SESSION", - [CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS] = "CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS", - [CMD_START_ALCSYNC_SERVICE] = "CMD_START_ALCSYNC_SERVICE", - [CMD_STOP_ALCSYNC_SERVICE] = "CMD_STOP_ALCSYNC_SERVICE", - [CMD_GET_ALCSYNC_TIME] = "CMD_GET_ALCSYNC_TIME", - [CMD_TRIG_ALCSYNC_REQUEST] = "CMD_TRIG_ALCSYNC_REQUEST", - [CMD_LORAWAN_MAC_REQUEST] = "CMD_LORAWAN_MAC_REQUEST", - [CMD_GET_LORAWAN_TIME] = "CMD_GET_LORAWAN_TIME", - [CMD_GET_LINK_CHECK_DATA] = "CMD_GET_LINK_CHECK_DATA", - [CMD_SET_DUTY_CYCLE_STATE] = "CMD_SET_DUTY_CYCLE_STATE", - [CMD_DEBUG_CONNECT_WITH_ABP] = "CMD_DEBUG_CONNECT_WITH_ABP", - [CMD_TEST] = "CMD_TEST", - [CMD_GET_TX_POWER_OFFSET] = "CMD_GET_TX_POWER_OFFSET", - [CMD_SET_TX_POWER_OFFSET] = "CMD_SET_TX_POWER_OFFSET", - [CMD_CSMA_SET_STATE] = "CMD_CSMA_SET_STATE", - [CMD_CSMA_GET_STATE] = "CMD_CSMA_GET_STATE", - [CMD_CSMA_SET_PARAMETERS] = "CMD_CSMA_SET_PARAMETERS", - [CMD_CSMA_GET_PARAMETERS] = "CMD_CSMA_GET_PARAMETERS", - [CMD_STREAM_INIT] = "CMD_STREAM_INIT", - [CMD_STREAM_ADD_DATA] = "CMD_STREAM_ADD_DATA", - [CMD_STREAM_STATUS] = "CMD_STREAM_STATUS", - [CMD_LFU_INIT] = "CMD_LFU_INIT", - [CMD_LFU_DATA] = "CMD_LFU_DATA", - [CMD_LFU_START] = "CMD_LFU_START", - [CMD_LFU_RESET] = "CMD_LFU_RESET", - [CMD_DM_ENABLE] = "CMD_DM_ENABLE", - [CMD_DM_GET_PORT] = "CMD_DM_GET_PORT", - [CMD_DM_SET_PORT] = "CMD_DM_SET_PORT", - [CMD_DM_GET_INFO_INTERVAL] = "CMD_DM_GET_INFO_INTERVAL", - [CMD_DM_SET_INFO_INTERVAL] = "CMD_DM_SET_INFO_INTERVAL", - [CMD_DM_GET_PERIODIC_INFO_FIELDS] = "CMD_DM_GET_PERIODIC_INFO_FIELDS", - [CMD_DM_SET_PERIODIC_INFO_FIELDS] = "CMD_DM_SET_PERIODIC_INFO_FIELDS", - [CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS] = "CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS", - [CMD_DM_SET_USER_DATA] = "CMD_DM_SET_USER_DATA", - [CMD_DM_GET_USER_DATA] = "CMD_DM_GET_USER_DATA", + [CMD_MULTICAST_CLASS_B_STOP_SESSION] = "CMD_MULTICAST_CLASS_B_STOP_SESSION", + [CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS] = "CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS", + [CMD_START_ALCSYNC_SERVICE] = "CMD_START_ALCSYNC_SERVICE", + [CMD_STOP_ALCSYNC_SERVICE] = "CMD_STOP_ALCSYNC_SERVICE", + [CMD_GET_ALCSYNC_TIME] = "CMD_GET_ALCSYNC_TIME", + [CMD_TRIG_ALCSYNC_REQUEST] = "CMD_TRIG_ALCSYNC_REQUEST", + [CMD_LORAWAN_MAC_REQUEST] = "CMD_LORAWAN_MAC_REQUEST", + [CMD_GET_LORAWAN_TIME] = "CMD_GET_LORAWAN_TIME", + [CMD_GET_LINK_CHECK_DATA] = "CMD_GET_LINK_CHECK_DATA", + [CMD_SET_DUTY_CYCLE_STATE] = "CMD_SET_DUTY_CYCLE_STATE", + [CMD_DEBUG_CONNECT_WITH_ABP] = "CMD_DEBUG_CONNECT_WITH_ABP", + [CMD_TEST] = "CMD_TEST", + [CMD_GET_TX_POWER_OFFSET] = "CMD_GET_TX_POWER_OFFSET", + [CMD_SET_TX_POWER_OFFSET] = "CMD_SET_TX_POWER_OFFSET", + [CMD_CSMA_SET_STATE] = "CMD_CSMA_SET_STATE", + [CMD_CSMA_GET_STATE] = "CMD_CSMA_GET_STATE", + [CMD_CSMA_SET_PARAMETERS] = "CMD_CSMA_SET_PARAMETERS", + [CMD_CSMA_GET_PARAMETERS] = "CMD_CSMA_GET_PARAMETERS", + [CMD_STREAM_INIT] = "CMD_STREAM_INIT", + [CMD_STREAM_ADD_DATA] = "CMD_STREAM_ADD_DATA", + [CMD_STREAM_STATUS] = "CMD_STREAM_STATUS", + [CMD_LFU_INIT] = "CMD_LFU_INIT", + [CMD_LFU_DATA] = "CMD_LFU_DATA", + [CMD_LFU_START] = "CMD_LFU_START", + [CMD_LFU_RESET] = "CMD_LFU_RESET", + [CMD_DM_ENABLE] = "CMD_DM_ENABLE", + [CMD_DM_GET_PORT] = "CMD_DM_GET_PORT", + [CMD_DM_SET_PORT] = "CMD_DM_SET_PORT", + [CMD_DM_GET_INFO_INTERVAL] = "CMD_DM_GET_INFO_INTERVAL", + [CMD_DM_SET_INFO_INTERVAL] = "CMD_DM_SET_INFO_INTERVAL", + [CMD_DM_GET_PERIODIC_INFO_FIELDS] = "CMD_DM_GET_PERIODIC_INFO_FIELDS", + [CMD_DM_SET_PERIODIC_INFO_FIELDS] = "CMD_DM_SET_PERIODIC_INFO_FIELDS", + [CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS] = "CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS", + [CMD_DM_SET_USER_DATA] = "CMD_DM_SET_USER_DATA", + [CMD_DM_GET_USER_DATA] = "CMD_DM_GET_USER_DATA", + [CMD_GET_STATUS] = "CMD_GET_STATUS", + [CMD_SUSPEND_RADIO_COMMUNICATIONS] = "CMD_SUSPEND_RADIO_COMMUNICATIONS", + [CMD_GET_SUSPEND_RADIO_COMMUNICATIONS] = "CMD_GET_SUSPEND_RADIO_COMMUNICATIONS", + [CMD_DM_HANDLE_ALCSYNC] = "CMD_DM_HANDLE_ALCSYNC", + [CMD_SET_APPKEY] = "CMD_SET_APPKEY", + [CMD_GET_ADR_PROFILE] = "CMD_GET_ADR_PROFILE", + [CMD_GET_CERTIFICATION_MODE] = "CMD_GET_CERTIFICATION_MODE", +#if defined(STM32L476xx) + [CMD_STORE_AND_FORWARD_SET_STATE] = "CMD_STORE_AND_FORWARD_SET_STATE", + [CMD_STORE_AND_FORWARD_GET_STATE] = "CMD_STORE_AND_FORWARD_GET_STATE", + [CMD_STORE_AND_FORWARD_ADD_DATA] = "CMD_STORE_AND_FORWARD_ADD_DATA", + [CMD_STORE_AND_FORWARD_CLEAR_DATA] = "CMD_STORE_AND_FORWARD_CLEAR_DATA", + [CMD_STORE_AND_FORWARD_GET_FREE_SLOT] = "CMD_STORE_AND_FORWARD_GET_FREE_SLOT", +#endif // STM32L476xx +#if defined(ADD_APP_GEOLOCATION) && defined(STM32L476xx) + [CMD_GNSS_SCAN] = "CMD_GNSS_SCAN", + [CMD_GNSS_SCAN_CANCEL] = "CMD_GNSS_SCAN_CANCEL", + [CMD_GNSS_GET_EVENT_DATA_SCAN_DONE] = "CMD_GNSS_GET_EVENT_DATA_SCAN_DONE", + [CMD_GNSS_GET_SCAN_DONE_RAW_DATA_LIST] = "CMD_GNSS_GET_SCAN_DONE_RAW_DATA_LIST", + [CMD_GNSS_GET_SCAN_DONE_METADATA_LIST] = "CMD_GNSS_GET_SCAN_DONE_METADATA_LIST", + [CMD_GNSS_GET_SCAN_DONE_SCAN_SV] = "CMD_GNSS_GET_SCAN_DONE_SCAN_SV", + [CMD_GNSS_GET_EVENT_DATA_TERMINATED] = "CMD_GNSS_GET_EVENT_DATA_TERMINATED", + [CMD_GNSS_SET_CONST] = "CMD_GNSS_SET_CONST", + [CMD_GNSS_SET_PORT] = "CMD_GNSS_SET_PORT", + [CMD_GNSS_SCAN_AGGREGATE] = "CMD_GNSS_SCAN_AGGREGATE", + [CMD_GNSS_SEND_MODE] = "CMD_GNSS_SEND_MODE", + [CMD_GNSS_ALM_DEMOD_START] = "CMD_GNSS_ALM_DEMOD_START", + [CMD_GNSS_ALM_DEMOD_SET_CONSTEL] = "CMD_GNSS_ALM_DEMOD_SET_CONSTEL", + [CMD_GNSS_ALM_DEMOD_GET_EVENT_DATA_ALM_UPD] = "CMD_GNSS_ALM_DEMOD_GET_EVENT_DATA_ALM_UPD", + [CMD_CLOUD_ALMANAC_START] = "CMD_CLOUD_ALMANAC_START", + [CMD_CLOUD_ALMANAC_STOP] = "CMD_CLOUD_ALMANAC_STOP", + [CMD_WIFI_SCAN_START] = "CMD_MODEM_WIFI_SCAN_START", + [CMD_WIFI_SCAN_CANCEL] = "CMD_MODEM_WIFI_SCAN_CANCEL", + [CMD_WIFI_GET_SCAN_DONE_SCAN_DATA] = "CMD_MODEM_WIFI_GET_SCAN_DONE_SCAN_DATA", + [CMD_WIFI_GET_EVENT_DATA_TERMINATED] = "CMD_MODEM_WIFI_GET_EVENT_DATA_TERMINATED", + [CMD_WIFI_SET_PORT] = "CMD_MODEM_WIFI_SET_PORT", + [CMD_WIFI_SEND_MODE] = "CMD_MODEM_WIFI_SEND_MODE", + [CMD_WIFI_SET_PAYLOAD_FORMAT] = "CMD_MODEM_WIFI_SET_PAYLOAD_FORMAT", + [CMD_LR11XX_RADIO_READ] = "CMD_LR11XX_RADIO_READ", + [CMD_LR11XX_RADIO_WRITE] = "CMD_LR11XX_RADIO_WRITE", +#endif // ADD_APP_GEOLOCATION && STM32L476xx + [CMD_SET_RTC_OFFSET] = "CMD_SET_RTC_OFFSET", +#if defined(USE_RELAY_TX) + [CMD_SET_RELAY_CONFIG] = "CMD_SET_RELAY_CONFIG", + [CMD_GET_RELAY_CONFIG] = "CMD_GET_RELAY_CONFIG", +#endif + [CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = "CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF", + [CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = "CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF", + [CMD_MODEM_GET_CRASHLOG] = "CMD_GET_CRASHLOG", }; #endif @@ -348,83 +457,39 @@ static const char* host_cmd_str[CMD_MAX] = { * @brief Host test command names for print purpose * */ -static const char* host_cmd_test_str[CMD_TST_MAX] = { - [CMD_TST_START] = "START", - [CMD_TST_NOP] = "NOP", - [CMD_TST_TX_SINGLE] = "TX_SINGLE", - [CMD_TST_TX_CONT] = "TX_CONT", - [CMD_TST_TX_HOP] = "TX_HOP", - [CMD_TST_NA_1] = "NA_1", - [CMD_TST_TX_CW] = "TX_CW", - [CMD_TST_RX_CONT] = "RX_CONT", - [CMD_TST_RSSI] = "RSSI", - [CMD_TST_RADIO_RST] = "RADIO_RST", - [CMD_TST_EXIT] = "EXIT", - [CMD_TST_BUSYLOOP] = "BUSYLOOP", - [CMD_TST_PANIC] = "PANIC", - [CMD_TST_WATCHDOG] = "WATCHDOG", - [CMD_TST_RADIO_READ] = "RADIO_READ", - [CMD_TST_RADIO_WRITE] = "RADIO_WRITE", - [CMD_TST_TX_SINGLE_PREAM] = "TX_SINGLE_PREAM", - [CMD_TST_RSSI_GET] = "TST_RSSI_GET", - [CMD_TST_READ_NB_PKTS_RX_CONT] = "READ_NB_PKTS_RX_CONT", +static const char *host_cmd_test_str[CMD_TST_MAX] = { + [CMD_TST_START] = "START", + [CMD_TST_EXIT] = "EXIT", + [CMD_TST_NOP] = "NOP", + [CMD_TST_TX_LORA] = "TX_LORA", + [CMD_TST_TX_FSK] = "TX_FSK", + [CMD_TST_TX_LRFHSS] = "TX_LRFHSS", + [CMD_TST_TX_CW] = "TX_CW", + [CMD_TST_RX_LORA] = "RX_LORA", + [CMD_TST_RX_FSK_CONT] = "RX_FSK_CONT", + [CMD_TST_READ_NB_PKTS_RX] = "READ_NB_PKTS_RX", + [CMD_TST_READ_LAST_RX_PKT] = "READ_LAST_RX_PKT", + [CMD_TST_RSSI] = "RSSI", + [CMD_TST_RSSI_GET] = "TST_RSSI_GET", + [CMD_TST_RADIO_RST] = "RADIO_RST", + [CMD_TST_BUSYLOOP] = "BUSYLOOP", + [CMD_TST_PANIC] = "PANIC", + [CMD_TST_WATCHDOG] = "WATCHDOG", + [CMD_TST_RADIO_READ] = "RADIO_READ", + [CMD_TST_RADIO_WRITE] = "RADIO_WRITE", }; #endif /* clang-format off */ -/** - * @brief Spreading factor conversion table from hw modem command format to test modem api - * - */ -static const smtc_modem_test_sf_t cmd_test_sf_table[SMTC_MODEM_TEST_LORA_SF_COUNT] = { - SMTC_MODEM_TEST_FSK, - SMTC_MODEM_TEST_LORA_SF7, - SMTC_MODEM_TEST_LORA_SF8, - SMTC_MODEM_TEST_LORA_SF9, - SMTC_MODEM_TEST_LORA_SF10, - SMTC_MODEM_TEST_LORA_SF11, - SMTC_MODEM_TEST_LORA_SF12, - SMTC_MODEM_TEST_LORA_SF5, - SMTC_MODEM_TEST_LORA_SF6 -}; - -/** - * @brief Bandwidth conversion table from hw modem command format to test modem api - * - */ -static const smtc_modem_test_bw_t cmd_test_bw_table[SMTC_MODEM_TEST_BW_COUNT] = { - SMTC_MODEM_TEST_BW_125_KHZ, - SMTC_MODEM_TEST_BW_250_KHZ, - SMTC_MODEM_TEST_BW_500_KHZ, - SMTC_MODEM_TEST_BW_200_KHZ, - SMTC_MODEM_TEST_BW_400_KHZ, - SMTC_MODEM_TEST_BW_800_KHZ, - SMTC_MODEM_TEST_BW_1600_KHZ, -}; - -/** - * @brief Coding rate conversion table from hw modem command format to test modem api - * - */ -static const smtc_modem_test_cr_t cmd_test_cr_table[SMTC_MODEM_TEST_CR_COUNT] = { - SMTC_MODEM_TEST_CR_4_5, - SMTC_MODEM_TEST_CR_4_6, - SMTC_MODEM_TEST_CR_4_7, - SMTC_MODEM_TEST_CR_4_8, - SMTC_MODEM_TEST_CR_LI_4_5, - SMTC_MODEM_TEST_CR_LI_4_6, - SMTC_MODEM_TEST_CR_LI_4_8 -}; - /** * @brief Modem class conversion table from hw modem command format to modem api - * + * */ -static const smtc_modem_class_t cmd_modem_class_table[]={ +static const smtc_modem_class_t cmd_modem_class_table[] = { SMTC_MODEM_CLASS_A, SMTC_MODEM_CLASS_C, - SMTC_MODEM_CLASS_B, + SMTC_MODEM_CLASS_B }; /** @@ -444,12 +509,27 @@ static const uint8_t events_lut[SMTC_MODEM_EVENT_MAX] = { [SMTC_MODEM_EVENT_CLASS_B_STATUS] = 0x14, [SMTC_MODEM_EVENT_LORAWAN_MAC_TIME] = 0x19, [SMTC_MODEM_EVENT_LORAWAN_FUOTA_DONE] = 0x1A, - [SMTC_MODEM_EVENT_NO_MORE_MULTICAST_SESSION_CLASS_C] = 0x1A, - [SMTC_MODEM_EVENT_NO_MORE_MULTICAST_SESSION_CLASS_B] = 0x1B, - [SMTC_MODEM_EVENT_NEW_MULTICAST_SESSION_CLASS_C] = 0x1C, - [SMTC_MODEM_EVENT_NEW_MULTICAST_SESSION_CLASS_B] = 0x1D, + [SMTC_MODEM_EVENT_NO_MORE_MULTICAST_SESSION_CLASS_C] = 0x1B, + [SMTC_MODEM_EVENT_NO_MORE_MULTICAST_SESSION_CLASS_B] = 0x1C, + [SMTC_MODEM_EVENT_NEW_MULTICAST_SESSION_CLASS_C] = 0x1D, + [SMTC_MODEM_EVENT_NEW_MULTICAST_SESSION_CLASS_B] = 0x1E, + [SMTC_MODEM_EVENT_FIRMWARE_MANAGEMENT] = 0x1F, [SMTC_MODEM_EVENT_STREAM_DONE] = 0x08, [SMTC_MODEM_EVENT_UPLOAD_DONE] = 0x05, + [SMTC_MODEM_EVENT_DM_SET_CONF] = 0x06, + [SMTC_MODEM_EVENT_MUTE] = 0x07, + [SMTC_MODEM_EVENT_GNSS_SCAN_DONE] = 0x20, + [SMTC_MODEM_EVENT_GNSS_TERMINATED] = 0x21, + [SMTC_MODEM_EVENT_GNSS_ALMANAC_DEMOD_UPDATE] = 0x22, + [SMTC_MODEM_EVENT_WIFI_SCAN_DONE] = 0x23, + [SMTC_MODEM_EVENT_WIFI_TERMINATED] = 0x24, + [SMTC_MODEM_EVENT_RELAY_TX_DYNAMIC] = 0x30, + [SMTC_MODEM_EVENT_RELAY_TX_MODE] = 0x31, + [SMTC_MODEM_EVENT_RELAY_TX_SYNC] = 0x32, + [SMTC_MODEM_EVENT_RELAY_RX_RUNNING] = 0x33, + [SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE] = 0x34, + [SMTC_MODEM_EVENT_TEST_MODE] = 0x35, //!< Test mode event + }; /** @@ -481,7 +561,7 @@ static const cmd_serial_rc_code_t rc_lut[] = { * @param [in] length Received command length * @return cmd_length_valid_t */ -static cmd_length_valid_t cmd_parser_check_cmd_size( host_cmd_id_t cmd_id, uint8_t length ); +static cmd_length_valid_t cmd_parser_check_cmd_size(host_cmd_id_t cmd_id, uint8_t length); /** * @brief @@ -490,60 +570,56 @@ static cmd_length_valid_t cmd_parser_check_cmd_size( host_cmd_id_t cmd_id, uint8 * @param [in] length Received test command length * @return cmd_length_valid_t */ -static cmd_length_valid_t cmd_test_parser_check_cmd_size( host_cmd_test_id_t test_id, uint8_t length ); +static cmd_length_valid_t cmd_test_parser_check_cmd_size(host_cmd_test_id_t test_id, uint8_t length); /** - * @brief Check if received sf, bw and cr are acceptable + * @brief Crc function used for LFU (Large File Upload) * - * @param [in] sf Received spreading factor - * @param [in] bw Received bandwidth - * @param [in] cr Received coding rate - * @return cmd_parse_status_t + * @param [in] buf Payload buffer + * @param [in] len Length of the payload + * @return uint32_t The calculated CRC */ -static cmd_parse_status_t cmd_test_parser_check_sf_bw_cr( uint8_t sf, uint8_t bw, uint8_t cr ); - -uint32_t cmd_parser_crc( const uint8_t* buf, int len ); - +uint32_t cmd_parser_crc(const uint8_t *buf, int len); /* * ----------------------------------------------------------------------------- * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- */ -cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output ) +cmd_parse_status_t parse_cmd(cmd_input_t *cmd_input, cmd_response_t *cmd_output) { - cmd_parse_status_t ret = PARSE_OK; + cmd_parse_status_t ret = PARSE_OK; cmd_output->return_code = CMD_RC_OK; - cmd_output->length = 0; + cmd_output->length = 0; - if( ( cmd_input->cmd_code >= CMD_MAX ) || - ( host_cmd_tab[cmd_input->cmd_code][HOST_CMD_TAB_IDX_AVAILABILITY] != 1 ) ) + if ((cmd_input->cmd_code >= CMD_MAX) || + (host_cmd_tab[cmd_input->cmd_code][HOST_CMD_TAB_IDX_AVAILABILITY] != 1)) { - SMTC_HAL_TRACE_ERROR( "Unknown command (0x%x)\n", cmd_input->cmd_code ); + SMTC_HAL_TRACE_ERROR("Unknown command (0x%x)\n", cmd_input->cmd_code); cmd_output->return_code = CMD_RC_UNKNOWN; - cmd_output->length = 0; + cmd_output->length = 0; return PARSE_ERROR; } - if( cmd_parser_check_cmd_size( cmd_input->cmd_code, cmd_input->length ) == CMD_LENGTH_NOT_VALID ) + if (cmd_parser_check_cmd_size(cmd_input->cmd_code, cmd_input->length) == CMD_LENGTH_NOT_VALID) { cmd_output->return_code = CMD_RC_BAD_SIZE; - cmd_output->length = 0; + cmd_output->length = 0; return PARSE_ERROR; } - SMTC_HAL_TRACE_WARNING( "CMD_%s (0x%02x)\n", host_cmd_str[cmd_input->cmd_code], cmd_input->cmd_code ); - switch( cmd_input->cmd_code ) + SMTC_HAL_TRACE_WARNING("CMD_%s (0x%02x)\n", host_cmd_str[cmd_input->cmd_code], cmd_input->cmd_code); + switch (cmd_input->cmd_code) { case CMD_GET_EVENT: { - smtc_modem_event_t current_event = { 0 }; - uint8_t event_pending_count = 0; - cmd_output->return_code = rc_lut[smtc_modem_get_event( ¤t_event, &event_pending_count )]; - if( cmd_output->return_code == CMD_RC_NO_EVENT ) + smtc_modem_event_t current_event = {0}; + uint8_t event_pending_count = 0; + cmd_output->return_code = rc_lut[smtc_modem_get_event(¤t_event, &event_pending_count)]; + if (cmd_output->return_code == CMD_RC_NO_EVENT) { // No event available cmd_output->length = 0; break; } - + // buffer[0]: event type cmd_output->buffer[0] = events_lut[current_event.event_type]; @@ -551,49 +627,60 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output cmd_output->buffer[1] = current_event.missed_events; // buffer[2-N]; event data, depend on event_type - switch( current_event.event_type ) + switch (current_event.event_type) { case SMTC_MODEM_EVENT_RESET: - cmd_output->buffer[2] = 0; - cmd_output->buffer[3] = 0; - cmd_output->length = 4; + cmd_output->buffer[2] = (uint8_t)(current_event.event_data.reset.count >> 8); + cmd_output->buffer[3] = (uint8_t)(current_event.event_data.reset.count); + cmd_output->length = 4; break; case SMTC_MODEM_EVENT_TXDONE: - threadx_callback_to_release_smtc_tx(); cmd_output->buffer[2] = current_event.event_data.txdone.status; - cmd_output->length = 3; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_LINK_CHECK: cmd_output->buffer[2] = current_event.event_data.link_check.status; - cmd_output->length = 3; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_CLASS_B_PING_SLOT_INFO: cmd_output->buffer[2] = current_event.event_data.class_b_ping_slot_info.status; - cmd_output->length = 3; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_CLASS_B_STATUS: cmd_output->buffer[2] = current_event.event_data.class_b_status.status; - cmd_output->length = 3; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_LORAWAN_MAC_TIME: cmd_output->buffer[2] = current_event.event_data.lorawan_mac_time.status; - cmd_output->length = 3; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_LORAWAN_FUOTA_DONE: cmd_output->buffer[2] = current_event.event_data.fuota_status.successful; - cmd_output->length = 3; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_NEW_MULTICAST_SESSION_CLASS_C: cmd_output->buffer[2] = current_event.event_data.new_multicast_class_c.group_id; - cmd_output->length = 3; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_NEW_MULTICAST_SESSION_CLASS_B: cmd_output->buffer[2] = current_event.event_data.new_multicast_class_b.group_id; - cmd_output->length = 3; + cmd_output->length = 3; + break; + case SMTC_MODEM_EVENT_FIRMWARE_MANAGEMENT: + cmd_output->buffer[2] = current_event.event_data.fmp.status; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_UPLOAD_DONE: cmd_output->buffer[2] = current_event.event_data.uploaddone.status; - cmd_output->length = 3; + cmd_output->length = 3; + break; + case SMTC_MODEM_EVENT_DM_SET_CONF: + cmd_output->buffer[2] = current_event.event_data.setconf.opcode; + cmd_output->length = 3; + break; + case SMTC_MODEM_EVENT_MUTE: + cmd_output->buffer[2] = current_event.event_data.mute.status; + cmd_output->length = 3; break; case SMTC_MODEM_EVENT_DOWNDATA: case SMTC_MODEM_EVENT_ALCSYNC_TIME: @@ -603,27 +690,51 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output case SMTC_MODEM_EVENT_NO_MORE_MULTICAST_SESSION_CLASS_C: case SMTC_MODEM_EVENT_NO_MORE_MULTICAST_SESSION_CLASS_B: case SMTC_MODEM_EVENT_STREAM_DONE: + case SMTC_MODEM_EVENT_GNSS_SCAN_DONE: + case SMTC_MODEM_EVENT_GNSS_TERMINATED: + case SMTC_MODEM_EVENT_GNSS_ALMANAC_DEMOD_UPDATE: + case SMTC_MODEM_EVENT_WIFI_SCAN_DONE: + case SMTC_MODEM_EVENT_WIFI_TERMINATED: cmd_output->length = 2; break; + + case SMTC_MODEM_EVENT_RELAY_TX_DYNAMIC: + case SMTC_MODEM_EVENT_RELAY_TX_MODE: + case SMTC_MODEM_EVENT_RELAY_TX_SYNC: + cmd_output->buffer[2] = current_event.event_data.relay_tx.status; + cmd_output->length = 3; + break; + case SMTC_MODEM_EVENT_RELAY_RX_RUNNING: + cmd_output->buffer[2] = current_event.event_data.relay_rx.status; + cmd_output->length = 3; + break; + case SMTC_MODEM_EVENT_TEST_MODE: + cmd_output->buffer[2] = current_event.event_data.test_mode_status.status; + cmd_output->length = 3; + break; + case SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE: + cmd_output->buffer[2] = current_event.event_data.regional_duty_cycle.status; + cmd_output->length = 3; + break; default: cmd_output->length = 0; break; } // Handle event_pending_count - if( event_pending_count == 0 ) + if (event_pending_count == 0) { // de-assert hw_modem irq line to indicate host that all events have been retrieved - hal_gpio_set_value( HW_MODEM_EVENT_PIN, 0 ); + hal_gpio_set_value(HW_MODEM_EVENT_PIN, 0); } break; } case CMD_GET_DOWNLINK_DATA: { - cmd_output->return_code = rc_lut[smtc_modem_get_downlink_data( &cmd_output->buffer[2], &cmd_output->buffer[1], - &last_dl_metadata, &cmd_output->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_get_downlink_data(&cmd_output->buffer[2], &cmd_output->buffer[1], + &last_dl_metadata, &cmd_output->buffer[0])]; - if( cmd_output->return_code == CMD_RC_OK ) + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 2 + cmd_output->buffer[1]; } @@ -633,16 +744,16 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output { cmd_output->return_code = CMD_RC_OK; - cmd_output->buffer[0] = last_dl_metadata.stack_id; - cmd_output->buffer[1] = last_dl_metadata.rssi; - cmd_output->buffer[2] = last_dl_metadata.snr; - cmd_output->buffer[3] = last_dl_metadata.window; - cmd_output->buffer[4] = last_dl_metadata.fport; - cmd_output->buffer[5] = last_dl_metadata.fpending_bit; - cmd_output->buffer[6] = ( last_dl_metadata.frequency_hz >> 24 ) & 0xff; - cmd_output->buffer[7] = ( last_dl_metadata.frequency_hz >> 16 ) & 0xff; - cmd_output->buffer[8] = ( last_dl_metadata.frequency_hz >> 8 ) & 0xff; - cmd_output->buffer[9] = ( last_dl_metadata.frequency_hz & 0xff ); + cmd_output->buffer[0] = last_dl_metadata.stack_id; + cmd_output->buffer[1] = last_dl_metadata.rssi; + cmd_output->buffer[2] = last_dl_metadata.snr; + cmd_output->buffer[3] = last_dl_metadata.window; + cmd_output->buffer[4] = last_dl_metadata.fport; + cmd_output->buffer[5] = last_dl_metadata.fpending_bit; + cmd_output->buffer[6] = (last_dl_metadata.frequency_hz >> 24) & 0xff; + cmd_output->buffer[7] = (last_dl_metadata.frequency_hz >> 16) & 0xff; + cmd_output->buffer[8] = (last_dl_metadata.frequency_hz >> 8) & 0xff; + cmd_output->buffer[9] = (last_dl_metadata.frequency_hz & 0xff); cmd_output->buffer[10] = last_dl_metadata.datarate; cmd_output->length = 11; @@ -650,40 +761,40 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_RESET: { - smtc_modem_hal_reset_mcu( ); + smtc_modem_hal_reset_mcu(); cmd_output->return_code = CMD_RC_OK; break; } case CMD_RESET_CHARGE: { - cmd_output->return_code = rc_lut[smtc_modem_reset_charge( )]; + cmd_output->return_code = rc_lut[smtc_modem_reset_charge()]; break; } case CMD_GET_CHARGE: { - uint32_t charge = 0; - cmd_output->return_code = rc_lut[smtc_modem_get_charge( &charge )]; - if( cmd_output->return_code == CMD_RC_OK ) + uint32_t charge = 0; + cmd_output->return_code = rc_lut[smtc_modem_get_charge(&charge)]; + if (cmd_output->return_code == CMD_RC_OK) { - cmd_output->buffer[0] = ( charge >> 24 ) & 0xFF; - cmd_output->buffer[1] = ( charge >> 16 ) & 0xFF; - cmd_output->buffer[2] = ( charge >> 8 ) & 0xFF; - cmd_output->buffer[3] = ( charge & 0xFF ); - cmd_output->length = 4; + cmd_output->buffer[0] = (charge >> 24) & 0xFF; + cmd_output->buffer[1] = (charge >> 16) & 0xFF; + cmd_output->buffer[2] = (charge >> 8) & 0xFF; + cmd_output->buffer[3] = (charge & 0xFF); + cmd_output->length = 4; } break; } case CMD_GET_TX_POWER_OFFSET: { - int8_t offset = radio_utilities_get_tx_power_offset( ); - cmd_output->buffer[0] = offset; - cmd_output->length = 1; + int8_t offset = radio_utilities_get_tx_power_offset(); + cmd_output->buffer[0] = offset; + cmd_output->length = 1; cmd_output->return_code = CMD_RC_OK; break; } case CMD_SET_TX_POWER_OFFSET: { - radio_utilities_set_tx_power_offset( cmd_input->buffer[0] ); + radio_utilities_set_tx_power_offset(cmd_input->buffer[0]); cmd_output->return_code = CMD_RC_OK; break; } @@ -691,14 +802,14 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output { uint32_t gps_time_s = 0; - cmd_output->return_code = rc_lut[smtc_modem_get_alcsync_time( STACK_ID, &gps_time_s )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_alcsync_time(STACK_ID, &gps_time_s)]; + if (cmd_output->return_code == CMD_RC_OK) { - cmd_output->buffer[0] = ( gps_time_s >> 24 ) & 0xFF; - cmd_output->buffer[1] = ( gps_time_s >> 16 ) & 0xFF; - cmd_output->buffer[2] = ( gps_time_s >> 8 ) & 0xFF; - cmd_output->buffer[3] = ( gps_time_s & 0xFF ); - cmd_output->length = 4; + cmd_output->buffer[0] = (gps_time_s >> 24) & 0xFF; + cmd_output->buffer[1] = (gps_time_s >> 16) & 0xFF; + cmd_output->buffer[2] = (gps_time_s >> 8) & 0xFF; + cmd_output->buffer[3] = (gps_time_s & 0xFF); + cmd_output->length = 4; } break; } @@ -710,19 +821,19 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output alarm |= cmd_input->buffer[2] << 8; alarm |= cmd_input->buffer[3]; - cmd_output->return_code = rc_lut[smtc_modem_alarm_start_timer( alarm )]; + cmd_output->return_code = rc_lut[smtc_modem_alarm_start_timer(alarm)]; break; } case CMD_GET_PIN: { -#if defined( USE_LR11XX_CRYPTO ) +#if defined(USE_LR11XX_CRYPTO) uint8_t chip_pin[4]; - cmd_output->return_code = rc_lut[smtc_modem_get_pin( STACK_ID, chip_pin )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_pin(STACK_ID, chip_pin)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 4; // reverse endianess - for( uint8_t i = 0; i < cmd_output->length; i++ ) + for (uint8_t i = 0; i < cmd_output->length; i++) { cmd_output->buffer[i] = chip_pin[i]; } @@ -734,14 +845,14 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_GET_CHIP_EUI: { -#if defined( USE_LR11XX_CRYPTO ) +#if defined(USE_LR11XX_CRYPTO) uint8_t chip_eui[8]; - cmd_output->return_code = rc_lut[smtc_modem_get_chip_eui( STACK_ID, chip_eui )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_chip_eui(STACK_ID, chip_eui)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 8; // reverse endianess - for( uint8_t i = 0; i < cmd_output->length; i++ ) + for (uint8_t i = 0; i < cmd_output->length; i++) { cmd_output->buffer[i] = chip_eui[i]; } @@ -753,8 +864,8 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_GET_JOIN_EUI: { - cmd_output->return_code = rc_lut[smtc_modem_get_joineui( STACK_ID, &cmd_output->buffer[0] )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_joineui(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 8; } @@ -762,13 +873,13 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_SET_JOIN_EUI: { - cmd_output->return_code = rc_lut[smtc_modem_set_joineui( STACK_ID, &cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_set_joineui(STACK_ID, &cmd_input->buffer[0])]; break; } case CMD_GET_DEV_EUI: { - cmd_output->return_code = rc_lut[smtc_modem_get_deveui( STACK_ID, &cmd_output->buffer[0] )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_deveui(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 8; } @@ -776,32 +887,32 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_SET_DEV_EUI: { - cmd_output->return_code = rc_lut[smtc_modem_set_deveui( STACK_ID, &cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_set_deveui(STACK_ID, &cmd_input->buffer[0])]; break; } case CMD_SET_NWKKEY: - { // same as CMD_SETAPPKEY, @todo nwk key and app key !!!! - cmd_output->return_code = rc_lut[smtc_modem_set_nwkkey( STACK_ID, &cmd_input->buffer[0] )]; + { + cmd_output->return_code = rc_lut[smtc_modem_set_nwkkey(STACK_ID, &cmd_input->buffer[0])]; break; } case CMD_SET_CLASS: { - if( cmd_input->buffer[0] > 2 ) + if (cmd_input->buffer[0] > 2) { cmd_output->return_code = CMD_RC_INVALID; - cmd_output->length = 0; + cmd_output->length = 0; } else { cmd_output->return_code = - rc_lut[smtc_modem_set_class( STACK_ID, cmd_modem_class_table[cmd_input->buffer[0]] )]; + rc_lut[smtc_modem_set_class(STACK_ID, cmd_modem_class_table[cmd_input->buffer[0]])]; } break; } case CMD_GET_REGION: { - cmd_output->return_code = rc_lut[smtc_modem_get_region( STACK_ID, &cmd_output->buffer[0] )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_region(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 1; } @@ -809,29 +920,38 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_SET_REGION: { - cmd_output->return_code = rc_lut[smtc_modem_set_region( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_set_region(STACK_ID, cmd_input->buffer[0])]; break; } case CMD_SET_ADR_PROFILE: { cmd_output->return_code = - rc_lut[smtc_modem_adr_set_profile( STACK_ID, cmd_input->buffer[0], &cmd_input->buffer[1] )]; + rc_lut[smtc_modem_adr_set_profile(STACK_ID, cmd_input->buffer[0], &cmd_input->buffer[1])]; + break; + } + case CMD_GET_ADR_PROFILE: + { + cmd_output->return_code = rc_lut[smtc_modem_adr_get_profile(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) + { + cmd_output->length = 1; + } break; } case CMD_JOIN_NETWORK: { - cmd_output->return_code = rc_lut[smtc_modem_join_network( STACK_ID )]; + cmd_output->return_code = rc_lut[smtc_modem_join_network(STACK_ID)]; break; } case CMD_LEAVE_NETWORK: { - cmd_output->return_code = rc_lut[smtc_modem_leave_network( STACK_ID )]; + cmd_output->return_code = rc_lut[smtc_modem_leave_network(STACK_ID)]; break; } case CMD_GET_NEXT_TX_MAX_PAYLOAD: { - cmd_output->return_code = rc_lut[smtc_modem_get_next_tx_max_payload( STACK_ID, &cmd_output->buffer[0] )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_next_tx_max_payload(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 1; } @@ -840,36 +960,35 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output case CMD_REQUEST_UPLINK: { // check if confirmed/not confirmed arg if different from 0/1 (modem api takes bool) - if( ( cmd_input->buffer[1] != 0x00 ) && ( cmd_input->buffer[1] != 0x01 ) ) + if ((cmd_input->buffer[1] != 0x00) && (cmd_input->buffer[1] != 0x01)) { cmd_output->return_code = CMD_RC_INVALID; } else { - threadx_callback_to_protect_smtc_tx (); cmd_output->return_code = rc_lut[smtc_modem_request_uplink( - STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1], &cmd_input->buffer[2], cmd_input->length - 2 )]; + STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1], &cmd_input->buffer[2], cmd_input->length - 2)]; } break; } case CMD_EMERGENCY_UPLINK: { // check if confirmed/not confirmed arg if different from 0/1 (modem api takes bool) - if( ( cmd_input->buffer[1] != 0x00 ) && ( cmd_input->buffer[1] != 0x01 ) ) + if ((cmd_input->buffer[1] != 0x00) && (cmd_input->buffer[1] != 0x01)) { cmd_output->return_code = CMD_RC_INVALID; } else { cmd_output->return_code = rc_lut[smtc_modem_request_emergency_uplink( - STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1], &cmd_input->buffer[2], cmd_input->length - 2 )]; + STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1], &cmd_input->buffer[2], cmd_input->length - 2)]; } break; } case CMD_DERIVE_KEYS: { -#if defined( USE_LR11XX_CRYPTO ) - cmd_output->return_code = rc_lut[smtc_modem_derive_keys( STACK_ID )]; +#if defined(USE_LR11XX_CRYPTO) + cmd_output->return_code = rc_lut[smtc_modem_derive_keys(STACK_ID)]; #else cmd_output->return_code = CMD_RC_FAIL; #endif @@ -877,36 +996,111 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_SET_CERTIFICATION_MODE: { - cmd_output->return_code = rc_lut[smtc_modem_set_certification_mode( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_set_certification_mode(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_GET_CERTIFICATION_MODE: + { + bool certification_enabled = false; + cmd_output->return_code = rc_lut[smtc_modem_get_certification_mode(STACK_ID, &certification_enabled)]; + if (cmd_output->return_code == CMD_RC_OK) + { + cmd_output->buffer[0] = (uint8_t)certification_enabled; + cmd_output->length = 1; + } + break; + } + case CMD_SET_RTC_OFFSET: + { + uint32_t rtc_offset = 0; + rtc_offset |= cmd_input->buffer[0] << 24; + rtc_offset |= cmd_input->buffer[1] << 16; + rtc_offset |= cmd_input->buffer[2] << 8; + rtc_offset |= cmd_input->buffer[3]; + SMTC_HAL_TRACE_PRINTF("Not supported\n"); + ; + + break; + } + +#if defined(USE_RELAY_TX) + case CMD_SET_RELAY_CONFIG: + { + smtc_modem_relay_tx_config_t user_relay_config = {0}; + + user_relay_config.second_ch.freq_hz |= cmd_input->buffer[0] << 24; + user_relay_config.second_ch.freq_hz |= cmd_input->buffer[1] << 16; + user_relay_config.second_ch.freq_hz |= cmd_input->buffer[2] << 8; + user_relay_config.second_ch.freq_hz |= cmd_input->buffer[3]; + + user_relay_config.second_ch.ack_freq_hz |= cmd_input->buffer[4] << 24; + user_relay_config.second_ch.ack_freq_hz |= cmd_input->buffer[5] << 16; + user_relay_config.second_ch.ack_freq_hz |= cmd_input->buffer[6] << 8; + user_relay_config.second_ch.ack_freq_hz |= cmd_input->buffer[7]; + + user_relay_config.second_ch.dr = cmd_input->buffer[8]; + user_relay_config.second_ch_enable = cmd_input->buffer[9]; + + user_relay_config.backoff = cmd_input->buffer[10]; + user_relay_config.activation = cmd_input->buffer[11]; + user_relay_config.smart_level = cmd_input->buffer[12]; + user_relay_config.number_of_miss_wor_ack_to_switch_in_nosync_mode = cmd_input->buffer[13]; + smtc_modem_relay_tx_enable(STACK_ID, &user_relay_config); + + break; + } + case CMD_GET_RELAY_CONFIG: + { + smtc_modem_relay_tx_config_t user_relay_config = {0}; + smtc_modem_relay_tx_get_config(STACK_ID, &user_relay_config); + cmd_output->buffer[0] = (user_relay_config.second_ch.freq_hz >> 24) & 0xFF; + cmd_output->buffer[1] = (user_relay_config.second_ch.freq_hz >> 16) & 0xFF; + cmd_output->buffer[2] = (user_relay_config.second_ch.freq_hz >> 8) & 0xFF; + cmd_output->buffer[3] = (user_relay_config.second_ch.freq_hz & 0xFF); + + cmd_output->buffer[4] = (user_relay_config.second_ch.ack_freq_hz >> 24) & 0xFF; + cmd_output->buffer[5] = (user_relay_config.second_ch.ack_freq_hz >> 16) & 0xFF; + cmd_output->buffer[6] = (user_relay_config.second_ch.ack_freq_hz >> 8) & 0xFF; + cmd_output->buffer[7] = (user_relay_config.second_ch.ack_freq_hz & 0xFF); + cmd_output->buffer[8] = user_relay_config.second_ch.dr; + cmd_output->buffer[9] = user_relay_config.second_ch_enable; + + cmd_output->buffer[10] = user_relay_config.backoff; + cmd_output->buffer[11] = user_relay_config.activation; + cmd_output->buffer[12] = user_relay_config.smart_level; + cmd_output->buffer[13] = user_relay_config.number_of_miss_wor_ack_to_switch_in_nosync_mode; + cmd_output->length = 14; + cmd_output->return_code = CMD_RC_OK; break; } +#endif case CMD_TEST: { - cmd_tst_input_t cmd_tst_input; + cmd_tst_input_t cmd_tst_input; cmd_tst_response_t cmd_tst_output; - cmd_tst_input.cmd_code = ( host_cmd_test_id_t ) cmd_input->buffer[0]; - cmd_tst_input.length = cmd_input->length - 1; - cmd_tst_input.buffer = &cmd_input->buffer[1]; - cmd_tst_output.buffer = &cmd_output->buffer[0]; + cmd_tst_input.cmd_code = (host_cmd_test_id_t)cmd_input->buffer[0]; + cmd_tst_input.length = cmd_input->length - 1; + cmd_tst_input.buffer = &cmd_input->buffer[1]; + cmd_tst_output.buffer = &cmd_output->buffer[0]; - ret = cmd_test_parser( &cmd_tst_input, &cmd_tst_output ); + ret = cmd_test_parser(&cmd_tst_input, &cmd_tst_output); cmd_output->return_code = cmd_tst_output.return_code; - cmd_output->length = cmd_tst_output.length; + cmd_output->length = cmd_tst_output.length; break; } case CMD_GET_DUTY_CYCLE_STATUS: { int32_t next_free_dtc = 0; - cmd_output->return_code = rc_lut[smtc_modem_get_duty_cycle_status( STACK_ID, &next_free_dtc )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_duty_cycle_status(STACK_ID, &next_free_dtc)]; + if (cmd_output->return_code == CMD_RC_OK) { - cmd_output->buffer[0] = ( next_free_dtc >> 24 ) & 0xff; - cmd_output->buffer[1] = ( next_free_dtc >> 16 ) & 0xff; - cmd_output->buffer[2] = ( next_free_dtc >> 8 ) & 0xff; - cmd_output->buffer[3] = ( next_free_dtc & 0xff ); + cmd_output->buffer[0] = (next_free_dtc >> 24) & 0xff; + cmd_output->buffer[1] = (next_free_dtc >> 16) & 0xff; + cmd_output->buffer[2] = (next_free_dtc >> 8) & 0xff; + cmd_output->buffer[3] = (next_free_dtc & 0xff); cmd_output->length = 4; } @@ -914,42 +1108,42 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_SET_DUTY_CYCLE_STATE: { - cmd_output->return_code = rc_lut[smtc_modem_debug_set_duty_cycle_state( cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_debug_set_duty_cycle_state(cmd_input->buffer[0])]; break; } case CMD_GET_ENABLED_DATARATE: { uint16_t enabled_datarate = 0; - cmd_output->return_code = rc_lut[smtc_modem_get_enabled_datarates( STACK_ID, &enabled_datarate )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_enabled_datarates(STACK_ID, &enabled_datarate)]; + if (cmd_output->return_code == CMD_RC_OK) { - cmd_output->buffer[0] = ( enabled_datarate >> 8 ) & 0xff; - cmd_output->buffer[1] = ( enabled_datarate & 0xff ); - cmd_output->length = 2; + cmd_output->buffer[0] = (enabled_datarate >> 8) & 0xff; + cmd_output->buffer[1] = (enabled_datarate & 0xff); + cmd_output->length = 2; } break; } case CMD_SET_NETWORK_TYPE: { - if( cmd_input->buffer[0] > 1 ) + if (cmd_input->buffer[0] > 1) { cmd_output->return_code = CMD_RC_INVALID; } else { - cmd_output->return_code = rc_lut[smtc_modem_set_network_type( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_set_network_type(STACK_ID, cmd_input->buffer[0])]; } break; } case CMD_SET_NB_TRANS: { - cmd_output->return_code = rc_lut[smtc_modem_set_nb_trans( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_set_nb_trans(STACK_ID, cmd_input->buffer[0])]; break; } case CMD_GET_NB_TRANS: { - cmd_output->return_code = rc_lut[smtc_modem_get_nb_trans( STACK_ID, &cmd_output->buffer[0] )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_nb_trans(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 1; } @@ -962,7 +1156,7 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output crystal_error |= cmd_input->buffer[1] << 16; crystal_error |= cmd_input->buffer[2] << 8; crystal_error |= cmd_input->buffer[3]; - cmd_output->return_code = rc_lut[smtc_modem_set_crystal_error_ppm( crystal_error )]; + cmd_output->return_code = rc_lut[smtc_modem_set_crystal_error_ppm(crystal_error)]; break; } case CMD_MULTICAST_SET_GROUP_CONFIG: @@ -975,20 +1169,20 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output addr |= cmd_input->buffer[4]; cmd_output->return_code = rc_lut[smtc_modem_multicast_set_grp_config( - STACK_ID, cmd_input->buffer[0], addr, &cmd_input->buffer[5], &cmd_input->buffer[21] )]; + STACK_ID, cmd_input->buffer[0], addr, &cmd_input->buffer[5], &cmd_input->buffer[21])]; break; } case CMD_MULTICAST_GET_GROUP_CONFIG: { uint32_t addr = 0; - cmd_output->return_code = rc_lut[smtc_modem_multicast_get_grp_config( STACK_ID, cmd_input->buffer[0], &addr )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_multicast_get_grp_config(STACK_ID, cmd_input->buffer[0], &addr)]; + if (cmd_output->return_code == CMD_RC_OK) { - cmd_output->buffer[0] = ( addr >> 24 ) & 0xff; - cmd_output->buffer[1] = ( addr >> 16 ) & 0xff; - cmd_output->buffer[2] = ( addr >> 8 ) & 0xff; - cmd_output->buffer[3] = ( addr & 0xff ); + cmd_output->buffer[0] = (addr >> 24) & 0xff; + cmd_output->buffer[1] = (addr >> 16) & 0xff; + cmd_output->buffer[2] = (addr >> 8) & 0xff; + cmd_output->buffer[3] = (addr & 0xff); cmd_output->length = 4; } @@ -1003,25 +1197,25 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output freq |= cmd_input->buffer[3] << 8; freq |= cmd_input->buffer[4]; - cmd_output->return_code = rc_lut[smtc_modem_multicast_class_c_start_session( STACK_ID, cmd_input->buffer[0], - freq, cmd_input->buffer[5] )]; + cmd_output->return_code = rc_lut[smtc_modem_multicast_class_c_start_session(STACK_ID, cmd_input->buffer[0], + freq, cmd_input->buffer[5])]; break; } case CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS: { uint32_t freq = 0; - uint8_t dr = 0xFF; - bool is_session_started; + uint8_t dr = 0xFF; + bool is_session_started; cmd_output->return_code = rc_lut[smtc_modem_multicast_class_c_get_session_status( - STACK_ID, cmd_input->buffer[0], &is_session_started, &freq, &dr )]; - if( cmd_output->return_code == CMD_RC_OK ) + STACK_ID, cmd_input->buffer[0], &is_session_started, &freq, &dr)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->buffer[0] = is_session_started; - cmd_output->buffer[1] = ( freq >> 24 ) & 0xff; - cmd_output->buffer[2] = ( freq >> 16 ) & 0xff; - cmd_output->buffer[3] = ( freq >> 8 ) & 0xff; - cmd_output->buffer[4] = ( freq & 0xff ); + cmd_output->buffer[1] = (freq >> 24) & 0xff; + cmd_output->buffer[2] = (freq >> 16) & 0xff; + cmd_output->buffer[3] = (freq >> 8) & 0xff; + cmd_output->buffer[4] = (freq & 0xff); cmd_output->buffer[5] = dr; cmd_output->length = 6; @@ -1030,19 +1224,19 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_MULTICAST_CLASS_C_STOP_SESSION: { - cmd_output->return_code = rc_lut[smtc_modem_multicast_class_c_stop_session( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_multicast_class_c_stop_session(STACK_ID, cmd_input->buffer[0])]; break; } case CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS: { - cmd_output->return_code = rc_lut[smtc_modem_multicast_class_c_stop_all_sessions( STACK_ID )]; + cmd_output->return_code = rc_lut[smtc_modem_multicast_class_c_stop_all_sessions(STACK_ID)]; break; } case CMD_GET_MODEM_VERSION: { smtc_modem_version_t modem_version; - cmd_output->return_code = rc_lut[smtc_modem_get_modem_version( &modem_version )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_modem_version(&modem_version)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->buffer[0] = modem_version.major; cmd_output->buffer[1] = modem_version.minor; @@ -1054,35 +1248,35 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_ALARM_CLEAR_TIMER: { - cmd_output->return_code = rc_lut[smtc_modem_alarm_clear_timer( )]; + cmd_output->return_code = rc_lut[smtc_modem_alarm_clear_timer()]; break; } case CMD_ALARM_GET_REMAINING_TIME: { uint32_t remaining_time = 0; - cmd_output->return_code = rc_lut[smtc_modem_alarm_get_remaining_time( &remaining_time )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_alarm_get_remaining_time(&remaining_time)]; + if (cmd_output->return_code == CMD_RC_OK) { - cmd_output->buffer[0] = ( remaining_time >> 24 ) & 0xff; - cmd_output->buffer[1] = ( remaining_time >> 16 ) & 0xff; - cmd_output->buffer[2] = ( remaining_time >> 8 ) & 0xff; - cmd_output->buffer[3] = ( remaining_time & 0xff ); - cmd_output->length = 4; + cmd_output->buffer[0] = (remaining_time >> 24) & 0xff; + cmd_output->buffer[1] = (remaining_time >> 16) & 0xff; + cmd_output->buffer[2] = (remaining_time >> 8) & 0xff; + cmd_output->buffer[3] = (remaining_time & 0xff); + cmd_output->length = 4; } break; } case CMD_REQUEST_EMPTY_UPLINK: { - cmd_output->return_code = rc_lut[smtc_modem_request_empty_uplink( STACK_ID, cmd_input->buffer[0], - cmd_input->buffer[1], cmd_input->buffer[2] )]; + cmd_output->return_code = rc_lut[smtc_modem_request_empty_uplink(STACK_ID, cmd_input->buffer[0], + cmd_input->buffer[1], cmd_input->buffer[2])]; break; } case CMD_LBT_SET_PARAMS: { uint32_t listening_duration_ms = 0; - int16_t threshold_dbm = 0; - uint32_t bw_hz = 0; + int16_t threshold_dbm = 0; + uint32_t bw_hz = 0; listening_duration_ms |= cmd_input->buffer[0] << 24; listening_duration_ms |= cmd_input->buffer[1] << 16; @@ -1098,28 +1292,28 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output bw_hz |= cmd_input->buffer[9]; cmd_output->return_code = - rc_lut[smtc_modem_lbt_set_parameters( STACK_ID, listening_duration_ms, threshold_dbm, bw_hz )]; + rc_lut[smtc_modem_lbt_set_parameters(STACK_ID, listening_duration_ms, threshold_dbm, bw_hz)]; break; } case CMD_LBT_GET_PARAMS: { uint32_t listening_duration_ms; - int16_t threshold_dbm; + int16_t threshold_dbm; uint32_t bw_hz; cmd_output->return_code = - rc_lut[smtc_modem_lbt_get_parameters( STACK_ID, &listening_duration_ms, &threshold_dbm, &bw_hz )]; - if( cmd_output->return_code == CMD_RC_OK ) - { - cmd_output->buffer[0] = ( listening_duration_ms >> 24 ) & 0xff; - cmd_output->buffer[1] = ( listening_duration_ms >> 16 ) & 0xff; - cmd_output->buffer[2] = ( listening_duration_ms >> 8 ) & 0xff; - cmd_output->buffer[3] = ( listening_duration_ms & 0xff ); - cmd_output->buffer[4] = ( threshold_dbm >> 8 ) & 0xff; - cmd_output->buffer[5] = ( threshold_dbm & 0xff ); - cmd_output->buffer[6] = ( bw_hz >> 24 ) & 0xff; - cmd_output->buffer[7] = ( bw_hz >> 16 ) & 0xff; - cmd_output->buffer[8] = ( bw_hz >> 8 ) & 0xff; - cmd_output->buffer[9] = ( bw_hz & 0xff ); + rc_lut[smtc_modem_lbt_get_parameters(STACK_ID, &listening_duration_ms, &threshold_dbm, &bw_hz)]; + if (cmd_output->return_code == CMD_RC_OK) + { + cmd_output->buffer[0] = (listening_duration_ms >> 24) & 0xff; + cmd_output->buffer[1] = (listening_duration_ms >> 16) & 0xff; + cmd_output->buffer[2] = (listening_duration_ms >> 8) & 0xff; + cmd_output->buffer[3] = (listening_duration_ms & 0xff); + cmd_output->buffer[4] = (threshold_dbm >> 8) & 0xff; + cmd_output->buffer[5] = (threshold_dbm & 0xff); + cmd_output->buffer[6] = (bw_hz >> 24) & 0xff; + cmd_output->buffer[7] = (bw_hz >> 16) & 0xff; + cmd_output->buffer[8] = (bw_hz >> 8) & 0xff; + cmd_output->buffer[9] = (bw_hz & 0xff); cmd_output->length = 10; } @@ -1127,46 +1321,46 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_LBT_SET_STATE: { - cmd_output->return_code = rc_lut[smtc_modem_lbt_set_state( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_lbt_set_state(STACK_ID, cmd_input->buffer[0])]; break; } case CMD_LBT_GET_STATE: { bool enabled; - cmd_output->return_code = rc_lut[smtc_modem_lbt_get_state( STACK_ID, &enabled )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_lbt_get_state(STACK_ID, &enabled)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->buffer[0] = enabled; - cmd_output->length = 1; + cmd_output->length = 1; } break; } case CMD_START_ALCSYNC_SERVICE: { - cmd_output->return_code = rc_lut[smtc_modem_start_alcsync_service( STACK_ID )]; + cmd_output->return_code = rc_lut[smtc_modem_start_alcsync_service(STACK_ID)]; break; } case CMD_STOP_ALCSYNC_SERVICE: { - cmd_output->return_code = rc_lut[smtc_modem_stop_alcsync_service( STACK_ID )]; + cmd_output->return_code = rc_lut[smtc_modem_stop_alcsync_service(STACK_ID)]; break; } case CMD_TRIG_ALCSYNC_REQUEST: { - cmd_output->return_code = rc_lut[smtc_modem_trigger_alcsync_request( STACK_ID )]; + cmd_output->return_code = rc_lut[smtc_modem_trigger_alcsync_request(STACK_ID)]; break; } case CMD_CLASS_B_SET_PING_SLOT_PERIODICITY: { cmd_output->return_code = rc_lut[smtc_modem_class_b_set_ping_slot_periodicity( - STACK_ID, ( smtc_modem_class_b_ping_slot_periodicity_t ) cmd_input->buffer[0] )]; + STACK_ID, (smtc_modem_class_b_ping_slot_periodicity_t)cmd_input->buffer[0])]; break; } case CMD_CLASS_B_GET_PING_SLOT_PERIODICITY: { cmd_output->return_code = - rc_lut[smtc_modem_class_b_get_ping_slot_periodicity( STACK_ID, &cmd_output->buffer[0] )]; - if( cmd_output->return_code == CMD_RC_OK ) + rc_lut[smtc_modem_class_b_get_ping_slot_periodicity(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 1; } @@ -1182,27 +1376,27 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output freq |= cmd_input->buffer[4]; cmd_output->return_code = rc_lut[smtc_modem_multicast_class_b_start_session( - STACK_ID, cmd_input->buffer[0], freq, cmd_input->buffer[5], cmd_input->buffer[6] )]; + STACK_ID, cmd_input->buffer[0], freq, cmd_input->buffer[5], cmd_input->buffer[6])]; break; } case CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS: { - uint32_t freq = 0; - uint8_t dr = 0xFF; - bool is_session_started; - bool is_session_waiting_for_beacon; + uint32_t freq = 0; + uint8_t dr = 0xFF; + bool is_session_started; + bool is_session_waiting_for_beacon; smtc_modem_class_b_ping_slot_periodicity_t ping_slot_periodicity; cmd_output->return_code = rc_lut[smtc_modem_multicast_class_b_get_session_status( STACK_ID, cmd_input->buffer[0], &is_session_started, &is_session_waiting_for_beacon, &freq, &dr, - &ping_slot_periodicity )]; - if( cmd_output->return_code == CMD_RC_OK ) + &ping_slot_periodicity)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->buffer[0] = is_session_started; - cmd_output->buffer[1] = ( freq >> 24 ) & 0xff; - cmd_output->buffer[2] = ( freq >> 16 ) & 0xff; - cmd_output->buffer[3] = ( freq >> 8 ) & 0xff; - cmd_output->buffer[4] = ( freq & 0xff ); + cmd_output->buffer[1] = (freq >> 24) & 0xff; + cmd_output->buffer[2] = (freq >> 16) & 0xff; + cmd_output->buffer[3] = (freq >> 8) & 0xff; + cmd_output->buffer[4] = (freq & 0xff); cmd_output->buffer[5] = dr; cmd_output->buffer[6] = is_session_waiting_for_beacon; cmd_output->buffer[7] = ping_slot_periodicity; @@ -1213,12 +1407,12 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_MULTICAST_CLASS_B_STOP_SESSION: { - cmd_output->return_code = rc_lut[smtc_modem_multicast_class_b_stop_session( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_multicast_class_b_stop_session(STACK_ID, cmd_input->buffer[0])]; break; } case CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS: { - cmd_output->return_code = rc_lut[smtc_modem_multicast_class_b_stop_all_sessions( STACK_ID )]; + cmd_output->return_code = rc_lut[smtc_modem_multicast_class_b_stop_all_sessions(STACK_ID)]; break; } case CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER: @@ -1251,14 +1445,14 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output case CMD_SET_ADR_ACK_LIMIT_DELAY: { cmd_output->return_code = - rc_lut[smtc_modem_set_adr_ack_limit_delay( STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1] )]; + rc_lut[smtc_modem_set_adr_ack_limit_delay(STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1])]; break; } case CMD_GET_ADR_ACK_LIMIT_DELAY: { cmd_output->return_code = - rc_lut[smtc_modem_get_adr_ack_limit_delay( STACK_ID, &cmd_output->buffer[0], &cmd_output->buffer[1] )]; - if( cmd_output->return_code == CMD_RC_OK ) + rc_lut[smtc_modem_get_adr_ack_limit_delay(STACK_ID, &cmd_output->buffer[0], &cmd_output->buffer[1])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 2; } @@ -1269,41 +1463,41 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output uint32_t gps_time_s; uint32_t gps_fractional_s; - cmd_output->return_code = rc_lut[smtc_modem_get_lorawan_mac_time( STACK_ID, &gps_time_s, &gps_fractional_s )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_lorawan_mac_time(STACK_ID, &gps_time_s, &gps_fractional_s)]; + if (cmd_output->return_code == CMD_RC_OK) { - cmd_output->buffer[0] = ( gps_time_s >> 24 ) & 0xFF; - cmd_output->buffer[1] = ( gps_time_s >> 16 ) & 0xFF; - cmd_output->buffer[2] = ( gps_time_s >> 8 ) & 0xFF; - cmd_output->buffer[3] = ( gps_time_s & 0xFF ); - cmd_output->buffer[4] = ( gps_fractional_s >> 24 ) & 0xFF; - cmd_output->buffer[5] = ( gps_fractional_s >> 16 ) & 0xFF; - cmd_output->buffer[6] = ( gps_fractional_s >> 8 ) & 0xFF; - cmd_output->buffer[7] = ( gps_fractional_s & 0xFF ); - cmd_output->length = 8; + cmd_output->buffer[0] = (gps_time_s >> 24) & 0xFF; + cmd_output->buffer[1] = (gps_time_s >> 16) & 0xFF; + cmd_output->buffer[2] = (gps_time_s >> 8) & 0xFF; + cmd_output->buffer[3] = (gps_time_s & 0xFF); + cmd_output->buffer[4] = (gps_fractional_s >> 24) & 0xFF; + cmd_output->buffer[5] = (gps_fractional_s >> 16) & 0xFF; + cmd_output->buffer[6] = (gps_fractional_s >> 8) & 0xFF; + cmd_output->buffer[7] = (gps_fractional_s & 0xFF); + cmd_output->length = 8; } break; } case CMD_SET_JOIN_DR_DISTRIBUTION: { - cmd_output->return_code = rc_lut[smtc_modem_adr_set_join_distribution( STACK_ID, &cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_adr_set_join_distribution(STACK_ID, &cmd_input->buffer[0])]; break; } case CMD_LORAWAN_MAC_REQUEST: { - cmd_output->return_code = rc_lut[smtc_modem_trig_lorawan_mac_request( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_trig_lorawan_mac_request(STACK_ID, cmd_input->buffer[0])]; break; } case CMD_GET_LINK_CHECK_DATA: { uint8_t margin; uint8_t gw_cnt; - cmd_output->return_code = rc_lut[smtc_modem_get_lorawan_link_check_data( STACK_ID, &margin, &gw_cnt )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_get_lorawan_link_check_data(STACK_ID, &margin, &gw_cnt)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->buffer[0] = margin; cmd_output->buffer[1] = gw_cnt; - cmd_output->length = 2; + cmd_output->length = 2; } break; } @@ -1315,86 +1509,109 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output dev_addr |= cmd_input->buffer[1] << 16; dev_addr |= cmd_input->buffer[2] << 8; dev_addr |= cmd_input->buffer[3]; - cmd_output->return_code = rc_lut[smtc_modem_debug_connect_with_abp( STACK_ID, dev_addr, &cmd_input->buffer[4], - &cmd_input->buffer[20] )]; + cmd_output->return_code = rc_lut[smtc_modem_debug_connect_with_abp(STACK_ID, dev_addr, &cmd_input->buffer[4], + &cmd_input->buffer[20])]; break; } case CMD_CSMA_SET_STATE: { - cmd_output->return_code = rc_lut[smtc_modem_csma_set_state( STACK_ID, cmd_input->buffer[0] )]; +#if defined(LR11XX) || defined(SX126X) + cmd_output->return_code = rc_lut[smtc_modem_csma_set_state(STACK_ID, cmd_input->buffer[0])]; +#else + cmd_output->return_code = CMD_RC_NOT_IMPLEMENTED; +#endif break; } case CMD_CSMA_GET_STATE: { +#if defined(LR11XX) || defined(SX126X) bool enable; - cmd_output->return_code = rc_lut[smtc_modem_csma_get_state( STACK_ID, &enable )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_csma_get_state(STACK_ID, &enable)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->buffer[0] = enable; - cmd_output->length = 1; + cmd_output->length = 1; } +#else + cmd_output->return_code = CMD_RC_NOT_IMPLEMENTED; +#endif break; } case CMD_CSMA_SET_PARAMETERS: { - cmd_output->return_code = rc_lut[smtc_modem_csma_set_parameters( STACK_ID, cmd_input->buffer[0], - cmd_input->buffer[1], cmd_input->buffer[2] )]; +#if defined(LR11XX) || defined(SX126X) + if (cmd_input->buffer[1] > 1) // bo_enabled is a bool + { + cmd_output->return_code = CMD_RC_INVALID; + } + else + { + cmd_output->return_code = rc_lut[smtc_modem_csma_set_parameters( + STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1], cmd_input->buffer[2])]; + } +#else + cmd_output->return_code = CMD_RC_NOT_IMPLEMENTED; +#endif break; } case CMD_CSMA_GET_PARAMETERS: { +#if defined(LR11XX) || defined(SX126X) uint8_t max_ch_change; - bool bo_enabled; + bool bo_enabled; uint8_t nb_bo_max; cmd_output->return_code = - rc_lut[smtc_modem_csma_get_parameters( STACK_ID, &max_ch_change, &bo_enabled, &nb_bo_max )]; - if( cmd_output->return_code == CMD_RC_OK ) + rc_lut[smtc_modem_csma_get_parameters(STACK_ID, &max_ch_change, &bo_enabled, &nb_bo_max)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->buffer[0] = max_ch_change; cmd_output->buffer[1] = bo_enabled; cmd_output->buffer[2] = nb_bo_max; - cmd_output->length = 3; + cmd_output->length = 3; } +#else + cmd_output->return_code = CMD_RC_NOT_IMPLEMENTED; +#endif break; } case CMD_STREAM_INIT: { - uint8_t port = cmd_input->buffer[0]; - uint8_t cipher = cmd_input->buffer[1]; + uint8_t port = cmd_input->buffer[0]; + uint8_t cipher = cmd_input->buffer[1]; uint8_t redundancy_ratio = cmd_input->buffer[2]; - cmd_output->return_code = rc_lut[smtc_modem_stream_init( STACK_ID, port, cipher, redundancy_ratio )]; - cmd_output->length = 0; + cmd_output->return_code = rc_lut[smtc_modem_stream_init(STACK_ID, port, cipher, redundancy_ratio)]; + cmd_output->length = 0; break; } case CMD_STREAM_ADD_DATA: { - uint8_t* data = &( cmd_input->buffer[0] ); - uint8_t data_len = cmd_input->length; - cmd_output->return_code = rc_lut[smtc_modem_stream_add_data( STACK_ID, data, data_len )]; - cmd_output->length = 0; + uint8_t *data = &(cmd_input->buffer[0]); + uint8_t data_len = cmd_input->length; + cmd_output->return_code = rc_lut[smtc_modem_stream_add_data(STACK_ID, data, data_len)]; + cmd_output->length = 0; break; } case CMD_STREAM_STATUS: { uint16_t pending = 0; - uint16_t free = 0; + uint16_t free = 0; - cmd_output->return_code = rc_lut[smtc_modem_stream_status( STACK_ID, &pending, &free )]; + cmd_output->return_code = rc_lut[smtc_modem_stream_status(STACK_ID, &pending, &free)]; - if( cmd_output->return_code == CMD_RC_OK ) + if (cmd_output->return_code == CMD_RC_OK) { - cmd_output->length = 4; - cmd_output->buffer[0] = ( pending >> 8 ) & 0xff; + cmd_output->length = 4; + cmd_output->buffer[0] = (pending >> 8) & 0xff; cmd_output->buffer[1] = pending & 0xff; - cmd_output->buffer[2] = ( free >> 8 ) & 0xff; + cmd_output->buffer[2] = (free >> 8) & 0xff; cmd_output->buffer[3] = free & 0xff; } break; } case CMD_LFU_INIT: { - uint16_t size = 0; + uint16_t size = 0; uint16_t average_delay = 0; size = cmd_input->buffer[2] << 8; @@ -1403,15 +1620,15 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output average_delay = cmd_input->buffer[4] << 8; average_delay |= cmd_input->buffer[5]; - file_size = size; - upload_status = UPLOAD_NOT_INIT; + file_size = size; + upload_status = UPLOAD_NOT_INIT; upload_current_size = 0; // empty the file_storage buffer - memset( file_store, 0, FILE_UPLOAD_MAX_SIZE ); + memset(file_store, 0, FILE_UPLOAD_MAX_SIZE); cmd_output->return_code = rc_lut[smtc_modem_file_upload_init( - STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1], file_store, file_size, average_delay )]; - if( cmd_output->return_code == CMD_RC_OK ) + STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1], file_store, file_size, average_delay)]; + if (cmd_output->return_code == CMD_RC_OK) { upload_status = UPLOAD_INIT; } @@ -1420,36 +1637,36 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output case CMD_LFU_DATA: { // First check if modem is in test mode - if( modem_in_test_mode == true ) + if (modem_in_test_mode == true) { cmd_output->return_code = CMD_RC_BUSY; } else { // here is a emulation of upload data to keep compliant with modem-e - if( ( upload_status != UPLOAD_INIT ) && ( upload_status != UPLOAD_DATA_ON_GOING ) ) + if ((upload_status != UPLOAD_INIT) && (upload_status != UPLOAD_DATA_ON_GOING)) { cmd_output->return_code = CMD_RC_NOT_INIT; - SMTC_HAL_TRACE_ERROR( "Upload file data, not init\n" ); + SMTC_HAL_TRACE_ERROR("Upload file data, not init\n"); } - else if( &cmd_input->buffer[0] == NULL ) + else if (&cmd_input->buffer[0] == NULL) { cmd_output->return_code = CMD_RC_NOT_INIT; - SMTC_HAL_TRACE_ERROR( "Upload file data, null\n" ); + SMTC_HAL_TRACE_ERROR("Upload file data, null\n"); } - else if( ( upload_current_size + cmd_input->length ) > file_size ) + else if ((upload_current_size + cmd_input->length) > file_size) { cmd_output->return_code = CMD_RC_INVALID; - SMTC_HAL_TRACE_ERROR( "Upload file data, size invalid\n" ); + SMTC_HAL_TRACE_ERROR("Upload file data, size invalid\n"); } - else if( upload_status == UPLOAD_STARTED ) + else if (upload_status == UPLOAD_STARTED) { cmd_output->return_code = CMD_RC_INVALID; - SMTC_HAL_TRACE_ERROR( "Upload file still on going\n" ); + SMTC_HAL_TRACE_ERROR("Upload file still on going\n"); } else { - memcpy( ( uint8_t* ) file_store + upload_current_size, &cmd_input->buffer[0], cmd_input->length ); + memcpy((uint8_t *)file_store + upload_current_size, &cmd_input->buffer[0], cmd_input->length); upload_current_size += cmd_input->length; upload_status = UPLOAD_DATA_ON_GOING; @@ -1466,22 +1683,22 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output input_crc |= cmd_input->buffer[3]; // check if file_size defined at upload_init cmd is equal to the actual received length - if( file_size != upload_current_size ) + if (file_size != upload_current_size) { cmd_output->return_code = CMD_RC_BAD_SIZE; - SMTC_HAL_TRACE_ERROR( "Data size uploaded does not correspond to what was defined\n" ); - smtc_modem_file_upload_reset( STACK_ID ); + SMTC_HAL_TRACE_ERROR("Data size uploaded does not correspond to what was defined\n"); + smtc_modem_file_upload_reset(STACK_ID); } - else if( input_crc != cmd_parser_crc( file_store, file_size ) ) + else if (input_crc != cmd_parser_crc(file_store, file_size)) { cmd_output->return_code = CMD_RC_BAD_CRC; - SMTC_HAL_TRACE_ERROR( "Bad crc after uploading file data\n" ); - smtc_modem_file_upload_reset( STACK_ID ); + SMTC_HAL_TRACE_ERROR("Bad crc after uploading file data\n"); + smtc_modem_file_upload_reset(STACK_ID); } else { - cmd_output->return_code = rc_lut[smtc_modem_file_upload_start( STACK_ID )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_file_upload_start(STACK_ID)]; + if (cmd_output->return_code == CMD_RC_OK) { upload_status = UPLOAD_STARTED; } @@ -1490,18 +1707,18 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_LFU_RESET: { - cmd_output->return_code = rc_lut[smtc_modem_file_upload_reset( STACK_ID )]; + cmd_output->return_code = rc_lut[smtc_modem_file_upload_reset(STACK_ID)]; break; } case CMD_DM_ENABLE: { - cmd_output->return_code = rc_lut[smtc_modem_dm_enable( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_dm_enable(STACK_ID, cmd_input->buffer[0])]; break; } case CMD_DM_GET_PORT: { - cmd_output->return_code = rc_lut[smtc_modem_dm_get_fport( STACK_ID, &cmd_output->buffer[0] )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_dm_get_fport(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = 1; } @@ -1509,18 +1726,18 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output } case CMD_DM_SET_PORT: { - cmd_output->return_code = rc_lut[smtc_modem_dm_set_fport( STACK_ID, cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_dm_set_fport(STACK_ID, cmd_input->buffer[0])]; break; } case CMD_DM_GET_INFO_INTERVAL: { smtc_modem_dm_info_interval_format_t format; - uint8_t interval; - cmd_output->return_code = rc_lut[smtc_modem_dm_get_info_interval( STACK_ID, &format, &interval )]; - if( cmd_output->return_code == CMD_RC_OK ) + uint8_t interval; + cmd_output->return_code = rc_lut[smtc_modem_dm_get_info_interval(STACK_ID, &format, &interval)]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->buffer[0] = interval & 0x3F; - cmd_output->buffer[0] |= ( ( uint8_t ) format << 6 ) & 0xC0; + cmd_output->buffer[0] |= ((uint8_t)format << 6) & 0xC0; cmd_output->length = 1; } break; @@ -1528,14 +1745,14 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output case CMD_DM_SET_INFO_INTERVAL: { cmd_output->return_code = rc_lut[smtc_modem_dm_set_info_interval( - STACK_ID, ( cmd_input->buffer[0] >> 6 ) & 0x03, cmd_input->buffer[0] & 0x3F )]; + STACK_ID, (cmd_input->buffer[0] >> 6) & 0x03, cmd_input->buffer[0] & 0x3F)]; break; } case CMD_DM_GET_PERIODIC_INFO_FIELDS: { cmd_output->return_code = - rc_lut[smtc_modem_dm_get_periodic_info_fields( STACK_ID, &cmd_output->buffer[0], &cmd_output->length )]; - if( cmd_output->return_code != CMD_RC_OK ) + rc_lut[smtc_modem_dm_get_periodic_info_fields(STACK_ID, &cmd_output->buffer[0], &cmd_output->length)]; + if (cmd_output->return_code != CMD_RC_OK) { cmd_output->length = 0; } @@ -1544,165 +1761,740 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output case CMD_DM_SET_PERIODIC_INFO_FIELDS: { cmd_output->return_code = - rc_lut[smtc_modem_dm_set_periodic_info_fields( STACK_ID, &cmd_input->buffer[0], cmd_input->length )]; + rc_lut[smtc_modem_dm_set_periodic_info_fields(STACK_ID, &cmd_input->buffer[0], cmd_input->length)]; break; } case CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS: { cmd_output->return_code = - rc_lut[smtc_modem_dm_request_immediate_info_field( STACK_ID, &cmd_input->buffer[0], cmd_input->length )]; + rc_lut[smtc_modem_dm_request_immediate_info_field(STACK_ID, &cmd_input->buffer[0], cmd_input->length)]; break; } case CMD_DM_SET_USER_DATA: { - cmd_output->return_code = rc_lut[smtc_modem_dm_set_user_data( STACK_ID, &cmd_input->buffer[0] )]; + cmd_output->return_code = rc_lut[smtc_modem_dm_set_user_data(STACK_ID, &cmd_input->buffer[0])]; break; } case CMD_DM_GET_USER_DATA: { - cmd_output->return_code = rc_lut[smtc_modem_dm_get_user_data( STACK_ID, &cmd_output->buffer[0] )]; - if( cmd_output->return_code == CMD_RC_OK ) + cmd_output->return_code = rc_lut[smtc_modem_dm_get_user_data(STACK_ID, &cmd_output->buffer[0])]; + if (cmd_output->return_code == CMD_RC_OK) { cmd_output->length = SMTC_MODEM_DM_USER_DATA_LENGTH; } break; } + case CMD_GET_STATUS: + { + smtc_modem_status_mask_t status_mask = {0}; + cmd_output->return_code = rc_lut[smtc_modem_get_status(STACK_ID, &status_mask)]; + if (cmd_output->return_code == CMD_RC_OK) + { + cmd_output->buffer[0] = (uint8_t)(status_mask); + cmd_output->length = 1; + } + break; + } + case CMD_GET_SUSPEND_RADIO_COMMUNICATIONS: + { + bool suspend; + cmd_output->return_code = rc_lut[smtc_modem_get_suspend_radio_communications(STACK_ID, &suspend)]; + cmd_output->buffer[0] = suspend; + cmd_output->length = 1; + break; + } + case CMD_SUSPEND_RADIO_COMMUNICATIONS: + { + cmd_output->return_code = rc_lut[smtc_modem_suspend_radio_communications(cmd_input->buffer[0])]; + break; + } + case CMD_DM_HANDLE_ALCSYNC: + { + cmd_output->return_code = rc_lut[smtc_modem_dm_handle_alcsync(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_SET_APPKEY: + { + cmd_output->return_code = rc_lut[smtc_modem_set_appkey(STACK_ID, &cmd_input->buffer[0])]; + break; + } + case CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF: + { + bool enabled = true; + cmd_output->return_code = rc_lut[smtc_modem_get_join_duty_cycle_backoff_bypass(STACK_ID, &enabled)]; + if (cmd_output->return_code == CMD_RC_OK) + { + cmd_output->buffer[0] = enabled; + cmd_output->length = 1; + } + break; + } + case CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF: + { + cmd_output->return_code = + rc_lut[smtc_modem_set_join_duty_cycle_backoff_bypass(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_MODEM_GET_CRASHLOG: + { + uint8_t crash_string_length = 0; + + cmd_output->buffer[0] = smtc_modem_hal_crashlog_get_status(); + smtc_modem_hal_crashlog_restore(&cmd_output->buffer[1], &crash_string_length); + + memset(&cmd_output->buffer[crash_string_length + 1], 0, CRASH_LOG_SIZE - crash_string_length); + + // clear status but not the data to be read if needed + smtc_modem_hal_crashlog_set_status(false); + + cmd_output->length = CRASH_LOG_SIZE + 1; // +1 crashlog status + cmd_output->return_code = CMD_RC_OK; + break; + } +#if defined(STM32L476xx) + case CMD_STORE_AND_FORWARD_SET_STATE: + { + cmd_output->return_code = rc_lut[smtc_modem_store_and_forward_set_state(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_STORE_AND_FORWARD_GET_STATE: + { + smtc_modem_store_and_forward_state_t state = {0}; + cmd_output->return_code = rc_lut[smtc_modem_store_and_forward_get_state(STACK_ID, &state)]; + if (cmd_output->return_code == CMD_RC_OK) + { + cmd_output->buffer[0] = (uint8_t)(state); + cmd_output->length = 1; + } + break; + } + case CMD_STORE_AND_FORWARD_ADD_DATA: + { + cmd_output->return_code = rc_lut[smtc_modem_store_and_forward_flash_add_data( + STACK_ID, cmd_input->buffer[0], cmd_input->buffer[1], &cmd_input->buffer[2], cmd_input->length - 2)]; + break; + } + case CMD_STORE_AND_FORWARD_CLEAR_DATA: + { + cmd_output->return_code = rc_lut[smtc_modem_store_and_forward_flash_clear_data(STACK_ID)]; + break; + } + case CMD_STORE_AND_FORWARD_GET_FREE_SLOT: + { + uint32_t capacity = 0; + uint32_t free_slot = 0; + cmd_output->return_code = + rc_lut[smtc_modem_store_and_forward_flash_get_number_of_free_slot(STACK_ID, &capacity, &free_slot)]; + if (cmd_output->return_code == CMD_RC_OK) + { + uint8_t idx = 0; + cmd_output->buffer[idx++] = (capacity >> 24) & 0xFF; + cmd_output->buffer[idx++] = (capacity >> 16) & 0xFF; + cmd_output->buffer[idx++] = (capacity >> 8) & 0xFF; + cmd_output->buffer[idx++] = (capacity & 0xFF); + cmd_output->buffer[idx++] = (free_slot >> 24) & 0xFF; + cmd_output->buffer[idx++] = (free_slot >> 16) & 0xFF; + cmd_output->buffer[idx++] = (free_slot >> 8) & 0xFF; + cmd_output->buffer[idx++] = (free_slot & 0xFF); + + cmd_output->length = idx; + } + break; + } +#endif // STM32L476xx + +#if defined(ADD_APP_GEOLOCATION) && defined(STM32L476xx) + case CMD_GNSS_SCAN: + { + smtc_modem_gnss_mode_t mode = cmd_input->buffer[0]; + uint32_t start_delay = 0; + + start_delay |= cmd_input->buffer[1] << 24; + start_delay |= cmd_input->buffer[2] << 16; + start_delay |= cmd_input->buffer[3] << 8; + start_delay |= cmd_input->buffer[4]; + cmd_output->return_code = rc_lut[smtc_modem_gnss_scan(STACK_ID, mode, start_delay)]; + break; + } + case CMD_GNSS_SCAN_CANCEL: + { + cmd_output->return_code = rc_lut[smtc_modem_gnss_scan_cancel(STACK_ID)]; + break; + } + case CMD_GNSS_GET_EVENT_DATA_SCAN_DONE: + { + // Reset value of static scan data saved struct + memset(&gnss_scan_data, 0, sizeof(smtc_modem_gnss_event_data_scan_done_t)); + + // Get the value of the struct + gnss_scan_done_rc = rc_lut[smtc_modem_gnss_get_event_data_scan_done(STACK_ID, &gnss_scan_data)]; + cmd_output->return_code = gnss_scan_done_rc; + + if (gnss_scan_done_rc == CMD_RC_OK) + { + // Fill the output buffer + uint8_t scan_done_offset = 0; + + cmd_output->buffer[scan_done_offset++] = gnss_scan_data.is_valid; + + cmd_output->buffer[scan_done_offset++] = gnss_scan_data.token; + + cmd_output->buffer[scan_done_offset++] = gnss_scan_data.nb_scans_valid; + + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.power_consumption_nah >> 24) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.power_consumption_nah >> 16) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.power_consumption_nah >> 8) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.power_consumption_nah & 0xff); + + cmd_output->buffer[scan_done_offset++] = gnss_scan_data.context.mode; + + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.context.almanac_crc >> 24) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.context.almanac_crc >> 16) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.context.almanac_crc >> 8) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.context.almanac_crc & 0xff); + + cmd_output->buffer[scan_done_offset++] = gnss_scan_data.indoor_detected; + + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.navgroup_duration_ms >> 24) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.navgroup_duration_ms >> 16) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.navgroup_duration_ms >> 8) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.navgroup_duration_ms) & 0xff; + + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.timestamp >> 24) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.timestamp >> 16) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.timestamp >> 8) & 0xff; + cmd_output->buffer[scan_done_offset++] = (gnss_scan_data.timestamp) & 0xff; + + cmd_output->length = scan_done_offset; + } + break; + } + case CMD_GNSS_GET_SCAN_DONE_RAW_DATA_LIST: + { + cmd_output->return_code = gnss_scan_done_rc; + if (cmd_output->return_code == CMD_RC_OK) + { + uint8_t raw_data_offset = 0; + for (uint8_t scan_index = 0; scan_index < gnss_scan_data.nb_scans_valid; scan_index++) + { + cmd_output->buffer[raw_data_offset++] = (gnss_scan_data.scans[scan_index].timestamp >> 24) & 0xff; + cmd_output->buffer[raw_data_offset++] = (gnss_scan_data.scans[scan_index].timestamp >> 16) & 0xff; + cmd_output->buffer[raw_data_offset++] = (gnss_scan_data.scans[scan_index].timestamp >> 8) & 0xff; + cmd_output->buffer[raw_data_offset++] = (gnss_scan_data.scans[scan_index].timestamp & 0xff); + + cmd_output->buffer[raw_data_offset++] = gnss_scan_data.scans[scan_index].nav_size; + + memcpy(&cmd_output->buffer[raw_data_offset], gnss_scan_data.scans[scan_index].nav, + gnss_scan_data.scans[scan_index].nav_size); + + raw_data_offset += gnss_scan_data.scans[scan_index].nav_size; + } + // At the end of the scan loop the size of the buff is known + cmd_output->length = raw_data_offset; + } + break; + } + case CMD_GNSS_GET_SCAN_DONE_METADATA_LIST: + { + cmd_output->return_code = gnss_scan_done_rc; + if (cmd_output->return_code == CMD_RC_OK) + { + uint8_t metadata_offset = 0; + for (uint8_t scan_index = 0; scan_index < gnss_scan_data.nb_scans_valid; scan_index++) + { + uint32_t lat_x10000 = + (uint32_t)(gnss_scan_data.scans[scan_index].aiding_position.latitude * 10000); + + cmd_output->buffer[metadata_offset++] = (lat_x10000 >> 24) & 0xff; + cmd_output->buffer[metadata_offset++] = (lat_x10000 >> 16) & 0xff; + cmd_output->buffer[metadata_offset++] = (lat_x10000 >> 8) & 0xff; + cmd_output->buffer[metadata_offset++] = (lat_x10000 & 0xff); + + uint32_t long_x10000 = + (uint32_t)(gnss_scan_data.scans[scan_index].aiding_position.longitude * 10000); + + cmd_output->buffer[metadata_offset++] = (long_x10000 >> 24) & 0xff; + cmd_output->buffer[metadata_offset++] = (long_x10000 >> 16) & 0xff; + cmd_output->buffer[metadata_offset++] = (long_x10000 >> 8) & 0xff; + cmd_output->buffer[metadata_offset++] = (long_x10000 & 0xff); + + cmd_output->buffer[metadata_offset++] = gnss_scan_data.scans[scan_index].scan_mode_launched; + + cmd_output->buffer[metadata_offset++] = + (gnss_scan_data.scans[scan_index].scan_duration_ms >> 24) & 0xff; + cmd_output->buffer[metadata_offset++] = + (gnss_scan_data.scans[scan_index].scan_duration_ms >> 16) & 0xff; + cmd_output->buffer[metadata_offset++] = + (gnss_scan_data.scans[scan_index].scan_duration_ms >> 8) & 0xff; + cmd_output->buffer[metadata_offset++] = (gnss_scan_data.scans[scan_index].scan_duration_ms & 0xff); + } + // At the end of the scan loop the size of the buff is known + cmd_output->length = metadata_offset; + } + break; + } + + case CMD_GNSS_GET_SCAN_DONE_SCAN_SV: + { + cmd_output->return_code = gnss_scan_done_rc; + if (cmd_output->return_code == CMD_RC_OK) + { + uint8_t sv_index = 0; + for (uint8_t scan_index = 0; scan_index < gnss_scan_data.nb_scans_valid; scan_index++) + { + cmd_output->buffer[sv_index++] = gnss_scan_data.scans[scan_index].nb_svs; + + for (uint8_t nav_index = 0; nav_index < gnss_scan_data.scans[scan_index].nb_svs; nav_index++) + { + cmd_output->buffer[sv_index++] = gnss_scan_data.scans[scan_index].info_svs[nav_index].satellite_id; + cmd_output->buffer[sv_index++] = gnss_scan_data.scans[scan_index].info_svs[nav_index].cnr; + cmd_output->buffer[sv_index++] = + (gnss_scan_data.scans[scan_index].info_svs[nav_index].doppler >> 8) & 0xff; + cmd_output->buffer[sv_index++] = + (gnss_scan_data.scans[scan_index].info_svs[nav_index].doppler & 0xff); + } + } + + // At the end of the scan loop the size of the buff is known + cmd_output->length = sv_index; + } + break; + } + case CMD_GNSS_GET_EVENT_DATA_TERMINATED: + { + smtc_modem_gnss_event_data_terminated_t gnss_data_terminated = {0}; + + cmd_output->return_code = rc_lut[smtc_modem_gnss_get_event_data_terminated(STACK_ID, &gnss_data_terminated)]; + + if (cmd_output->return_code == CMD_RC_OK) + { + cmd_output->buffer[0] = gnss_data_terminated.nb_scans_sent; + cmd_output->length = 1; + } + break; + } + case CMD_GNSS_SET_CONST: + { + cmd_output->return_code = rc_lut[smtc_modem_gnss_set_constellations(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_GNSS_SET_PORT: + { + cmd_output->return_code = rc_lut[smtc_modem_gnss_set_port(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_GNSS_SCAN_AGGREGATE: + { + smtc_modem_gnss_scan_aggregate(STACK_ID, cmd_input->buffer[0]); + // Above function do not have return code + cmd_output->return_code = CMD_RC_OK; + break; + } + case CMD_GNSS_SEND_MODE: + { + cmd_output->return_code = rc_lut[smtc_modem_gnss_send_mode(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_GNSS_ALM_DEMOD_START: + { + cmd_output->return_code = rc_lut[smtc_modem_almanac_demodulation_start(STACK_ID)]; + break; + } + case CMD_GNSS_ALM_DEMOD_SET_CONSTEL: + { + cmd_output->return_code = + rc_lut[smtc_modem_almanac_demodulation_set_constellations(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_GNSS_ALM_DEMOD_GET_EVENT_DATA_ALM_UPD: + { + smtc_modem_almanac_demodulation_event_data_almanac_update_t event_data_alm_update = {0}; + cmd_output->return_code = + rc_lut[smtc_modem_almanac_demodulation_get_event_data_almanac_update(STACK_ID, &event_data_alm_update)]; + if (cmd_output->return_code == CMD_RC_OK) + { + uint8_t index = 0; + + cmd_output->buffer[index++] = event_data_alm_update.status_gps; + cmd_output->buffer[index++] = event_data_alm_update.status_beidou; + cmd_output->buffer[index++] = event_data_alm_update.update_progress_gps; + cmd_output->buffer[index++] = event_data_alm_update.update_progress_beidou; + + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_update_from_sat_done >> 24) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_update_from_sat_done >> 16) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_update_from_sat_done >> 8) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_update_from_sat_done & 0xff); + + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_update_from_sat_success >> 24) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_update_from_sat_success >> 16) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_update_from_sat_success >> 8) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_update_from_sat_success & 0xff); + + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_aborted_by_rp >> 24) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_aborted_by_rp >> 16) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_aborted_by_rp >> 8) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_nb_aborted_by_rp & 0xff); + + cmd_output->buffer[index++] = (event_data_alm_update.stat_cumulative_timings_s >> 24) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_cumulative_timings_s >> 16) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_cumulative_timings_s >> 8) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.stat_cumulative_timings_s & 0xff); + + cmd_output->buffer[index++] = (event_data_alm_update.power_consumption_nah >> 24) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.power_consumption_nah >> 16) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.power_consumption_nah >> 8) & 0xff; + cmd_output->buffer[index++] = (event_data_alm_update.power_consumption_nah & 0xff); + + cmd_output->length = index; + } + break; + } + case CMD_CLOUD_ALMANAC_START: + { + cmd_output->return_code = rc_lut[smtc_modem_almanac_start(STACK_ID)]; + break; + } + case CMD_CLOUD_ALMANAC_STOP: + { + cmd_output->return_code = rc_lut[smtc_modem_almanac_stop(STACK_ID)]; + break; + } + case CMD_WIFI_SCAN_START: + { + uint32_t start_delay = 0; + + start_delay |= cmd_input->buffer[0] << 24; + start_delay |= cmd_input->buffer[1] << 16; + start_delay |= cmd_input->buffer[2] << 8; + start_delay |= cmd_input->buffer[3]; + cmd_output->return_code = rc_lut[smtc_modem_wifi_scan(STACK_ID, start_delay)]; + break; + } + case CMD_WIFI_SCAN_CANCEL: + { + cmd_output->return_code = rc_lut[smtc_modem_wifi_scan_cancel(STACK_ID)]; + break; + } + case CMD_WIFI_GET_SCAN_DONE_SCAN_DATA: + { + smtc_modem_wifi_event_data_scan_done_t wifi_scan_done_data = {0}; + cmd_output->return_code = rc_lut[smtc_modem_wifi_get_event_data_scan_done(STACK_ID, &wifi_scan_done_data)]; + if (cmd_output->return_code == CMD_RC_OK) + { + uint8_t index = 0; + + cmd_output->buffer[index++] = wifi_scan_done_data.nbr_results; + + cmd_output->buffer[index++] = (wifi_scan_done_data.power_consumption_nah >> 24) & 0xff; + cmd_output->buffer[index++] = (wifi_scan_done_data.power_consumption_nah >> 16) & 0xff; + cmd_output->buffer[index++] = (wifi_scan_done_data.power_consumption_nah >> 8) & 0xff; + cmd_output->buffer[index++] = (wifi_scan_done_data.power_consumption_nah & 0xff); + + cmd_output->buffer[index++] = (wifi_scan_done_data.scan_duration_ms >> 24) & 0xff; + cmd_output->buffer[index++] = (wifi_scan_done_data.scan_duration_ms >> 16) & 0xff; + cmd_output->buffer[index++] = (wifi_scan_done_data.scan_duration_ms >> 8) & 0xff; + cmd_output->buffer[index++] = (wifi_scan_done_data.scan_duration_ms & 0xff); + + for (uint8_t scan_index = 0; scan_index < wifi_scan_done_data.nbr_results; scan_index++) + { + // copy LR11XX_WIFI_MAC_ADDRESS_LENGTH bytes of mac adress + memcpy(&cmd_output->buffer[index], wifi_scan_done_data.results[scan_index].mac_address, + LR11XX_WIFI_MAC_ADDRESS_LENGTH); + index += LR11XX_WIFI_MAC_ADDRESS_LENGTH; + + cmd_output->buffer[index++] = wifi_scan_done_data.results[scan_index].channel; + cmd_output->buffer[index++] = wifi_scan_done_data.results[scan_index].type; + cmd_output->buffer[index++] = wifi_scan_done_data.results[scan_index].rssi; + } + cmd_output->length = index; + } + break; + } + case CMD_WIFI_GET_EVENT_DATA_TERMINATED: + { + smtc_modem_wifi_event_data_terminated_t wifi_data_terminated = {0}; + + cmd_output->return_code = rc_lut[smtc_modem_wifi_get_event_data_terminated(STACK_ID, &wifi_data_terminated)]; + + if (cmd_output->return_code == CMD_RC_OK) + { + cmd_output->buffer[0] = wifi_data_terminated.nb_scans_sent; + cmd_output->length = 1; + } + break; + } + case CMD_WIFI_SET_PORT: + { + cmd_output->return_code = rc_lut[smtc_modem_wifi_set_port(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_WIFI_SEND_MODE: + { + cmd_output->return_code = rc_lut[smtc_modem_wifi_send_mode(STACK_ID, cmd_input->buffer[0])]; + break; + } + case CMD_WIFI_SET_PAYLOAD_FORMAT: + { + smtc_modem_wifi_set_payload_format(STACK_ID, cmd_input->buffer[0]); + // Above function do not have return code + cmd_output->return_code = CMD_RC_OK; + break; + } + case CMD_LR11XX_RADIO_READ: + { + // First check if modem is in test mode + if (modem_in_test_mode == true) + { + cmd_output->return_code = CMD_RC_BUSY; + } + else + { +#if defined(LR11XX_TRANSCEIVER) + uint8_t command_length = cmd_input->buffer[0]; + uint8_t command[255] = {0}; + memcpy(command, &cmd_input->buffer[1], command_length); + + uint8_t data_length = cmd_input->buffer[command_length + 1]; + uint8_t data[255] = {0}; + if (lr11xx_hal_read(NULL, command, command_length, data, data_length) != LR11XX_HAL_STATUS_OK) + { + cmd_output->return_code = CMD_RC_FAIL; + } + else + { + cmd_output->return_code = CMD_RC_OK; + } + memcpy(cmd_output->buffer, data, data_length); + cmd_output->length = data_length; +#else + cmd_output->return_code = CMD_RC_FAIL; +#endif + } + break; + } + case CMD_LR11XX_RADIO_WRITE: + { + // First check if modem is in test mode + if (modem_in_test_mode == true) + { + cmd_output->return_code = CMD_RC_BUSY; + } + else + { +#if defined(LR11XX_TRANSCEIVER) + uint8_t command_length = cmd_input->buffer[0]; + uint8_t command[255] = {0}; + memcpy(command, &cmd_input->buffer[1], command_length); + + uint8_t data_length = cmd_input->buffer[command_length + 1]; + uint8_t data[255] = {0}; + memcpy(data, &cmd_input->buffer[command_length + 2], data_length); + if (lr11xx_hal_write(NULL, command, command_length, data, data_length) != LR11XX_HAL_STATUS_OK) + { + cmd_output->return_code = CMD_RC_FAIL; + } + else + { + cmd_output->return_code = CMD_RC_OK; + } + cmd_output->length = 0; +#else + cmd_output->return_code = CMD_RC_FAIL; +#endif + } + break; + } + +#endif // ADD_APP_GEOLOCATION && STM32L476xx default: { - SMTC_HAL_TRACE_ERROR( "Unknown command (0x%x)\n", cmd_input->cmd_code ); + SMTC_HAL_TRACE_ERROR("Unknown command (0x%x)\n", cmd_input->cmd_code); cmd_output->return_code = CMD_RC_UNKNOWN; - cmd_output->length = 0; + cmd_output->length = 0; return PARSE_ERROR; break; } } cmd_input->cmd_code = CMD_MAX; - cmd_input->length = 0; + cmd_input->length = 0; return ret; } -cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_response_t* cmd_tst_output ) +cmd_parse_status_t cmd_test_parser(cmd_tst_input_t *cmd_tst_input, cmd_tst_response_t *cmd_tst_output) { cmd_parse_status_t ret = PARSE_OK; - if( ( cmd_tst_input->cmd_code >= CMD_TST_MAX ) || - ( host_cmd_test_tab[cmd_tst_input->cmd_code][HOST_CMD_TAB_IDX_AVAILABILITY] != 1 ) ) + if ((cmd_tst_input->cmd_code >= CMD_TST_MAX) || + (host_cmd_test_tab[cmd_tst_input->cmd_code][HOST_CMD_TAB_IDX_AVAILABILITY] != 1)) { - SMTC_HAL_TRACE_ERROR( "Unknown command test (0x%x)\n", cmd_tst_input->cmd_code ); + SMTC_HAL_TRACE_ERROR("Unknown command test (0x%x)\n", cmd_tst_input->cmd_code); cmd_tst_output->return_code = CMD_RC_UNKNOWN; - cmd_tst_output->length = 0; + cmd_tst_output->length = 0; return PARSE_ERROR; } - if( cmd_test_parser_check_cmd_size( cmd_tst_input->cmd_code, cmd_tst_input->length ) == CMD_LENGTH_NOT_VALID ) + if (cmd_test_parser_check_cmd_size(cmd_tst_input->cmd_code, cmd_tst_input->length) == CMD_LENGTH_NOT_VALID) { - SMTC_HAL_TRACE_ERROR( "Invalid size command test (0x%x)\n", cmd_tst_input->cmd_code ); + SMTC_HAL_TRACE_ERROR("Invalid size command test (0x%x)\n", cmd_tst_input->cmd_code); cmd_tst_output->return_code = CMD_RC_BAD_SIZE; - cmd_tst_output->length = 0; + cmd_tst_output->length = 0; return PARSE_ERROR; } - cmd_tst_output->return_code = CMD_RC_OK; // by default the return code is ok and length is 0 - cmd_tst_output->length = 0; + cmd_tst_output->return_code = CMD_RC_OK; // by default the return code is ok and length is 0 + cmd_tst_output->length = 0; #if MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON - SMTC_HAL_TRACE_WARNING( "\tCMD_TST_%s (0x%02x)\n", host_cmd_test_str[cmd_tst_input->cmd_code], - cmd_tst_input->cmd_code ); + SMTC_HAL_TRACE_WARNING("\tCMD_TST_%s (0x%02x)\n", host_cmd_test_str[cmd_tst_input->cmd_code], + cmd_tst_input->cmd_code); #endif - switch( cmd_tst_input->cmd_code ) + switch (cmd_tst_input->cmd_code) { case CMD_TST_START: { - if( strncmp( ( char* ) cmd_tst_input->buffer, "TESTTEST", 8 ) == 0 ) + if (strncmp((char *)cmd_tst_input->buffer, "TESTTEST", 8) == 0) { - cmd_tst_output->return_code = rc_lut[smtc_modem_test_start( )]; - if( cmd_tst_output->return_code == CMD_RC_OK ) + cmd_tst_output->return_code = rc_lut[smtc_modem_test_start()]; + if (cmd_tst_output->return_code == CMD_RC_OK) { modem_in_test_mode = true; } } else { - SMTC_HAL_TRACE_ERROR( "TST MODE: invalid enablement payload\n" ); + SMTC_HAL_TRACE_ERROR("TST MODE: invalid enablement payload\n"); cmd_tst_output->return_code = CMD_RC_INVALID; } break; } + case CMD_TST_EXIT: + { + cmd_tst_output->return_code = rc_lut[smtc_modem_test_stop()]; + if (cmd_tst_output->return_code == CMD_RC_OK) + { + modem_in_test_mode = false; + } + break; + } case CMD_TST_NOP: { - cmd_tst_output->return_code = rc_lut[smtc_modem_test_nop( )]; + cmd_tst_output->return_code = rc_lut[smtc_modem_test_nop(true)]; break; } - case CMD_TST_TX_SINGLE: + case CMD_TST_TX_LORA: { - uint8_t raw_sf = cmd_tst_input->buffer[5]; - uint8_t raw_bw = cmd_tst_input->buffer[6]; - uint8_t raw_cr = cmd_tst_input->buffer[7]; - - // integrity of the data shall be tested here as we perform a data change using LUT before calling api - // function - if( cmd_test_parser_check_sf_bw_cr( raw_sf, raw_bw, raw_cr ) == PARSE_OK ) - { - smtc_modem_test_sf_t sf = cmd_test_sf_table[raw_sf]; - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; - smtc_modem_test_cr_t cr = cmd_test_cr_table[raw_cr]; - - int8_t pw = cmd_tst_input->buffer[4]; - uint8_t len = cmd_tst_input->buffer[8]; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; + int8_t pw = cmd_tst_input->buffer[4]; + uint8_t len = cmd_tst_input->buffer[5]; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx( NULL, len, freq, pw, sf, bw, cr, 8, false )]; + uint8_t sf = cmd_tst_input->buffer[6]; + uint8_t bw = cmd_tst_input->buffer[7]; + if (bw < RAL_LORA_BW_010_KHZ) + { + cmd_tst_output->return_code = CMD_RC_INVALID; } else { - // one of the data is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; + uint8_t cr = cmd_tst_input->buffer[8]; + + uint8_t invert_iq = cmd_tst_input->buffer[9] & 0x01; + uint8_t crc_is_on = cmd_tst_input->buffer[10] & 0x01; + ral_lora_pkt_len_modes_t header_type = cmd_tst_input->buffer[11] & 0x01; + + uint32_t preamble_size = 0; + preamble_size |= cmd_tst_input->buffer[12] << 24; + preamble_size |= cmd_tst_input->buffer[13] << 16; + preamble_size |= cmd_tst_input->buffer[14] << 8; + preamble_size |= cmd_tst_input->buffer[15]; + + uint32_t nb_of_tx = 0; + nb_of_tx |= cmd_tst_input->buffer[16] << 24; + nb_of_tx |= cmd_tst_input->buffer[17] << 16; + nb_of_tx |= cmd_tst_input->buffer[18] << 8; + nb_of_tx |= cmd_tst_input->buffer[19]; + + uint32_t delay_ms = 0; + delay_ms |= cmd_tst_input->buffer[20] << 24; + delay_ms |= cmd_tst_input->buffer[21] << 16; + delay_ms |= cmd_tst_input->buffer[22] << 8; + delay_ms |= cmd_tst_input->buffer[23]; + + uint8_t sync_word = cmd_tst_input->buffer[24]; + + cmd_tst_output->return_code = + rc_lut[smtc_modem_test_tx_lora(NULL, len, freq, pw, sf, bw, cr, sync_word, invert_iq, crc_is_on, + header_type, preamble_size, nb_of_tx, delay_ms)]; } break; } - case CMD_TST_TX_CONT: + case CMD_TST_TX_FSK: { - uint8_t raw_sf = cmd_tst_input->buffer[5]; - uint8_t raw_bw = cmd_tst_input->buffer[6]; - uint8_t raw_cr = cmd_tst_input->buffer[7]; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; - // integrity of the data shall be tested here as we perform a data change using LUT before calling api - // function - if( cmd_test_parser_check_sf_bw_cr( raw_sf, raw_bw, raw_cr ) == PARSE_OK ) - { - smtc_modem_test_sf_t sf = cmd_test_sf_table[raw_sf]; - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; - smtc_modem_test_cr_t cr = cmd_test_cr_table[raw_cr]; + int8_t pw = cmd_tst_input->buffer[4]; + uint8_t len = cmd_tst_input->buffer[5]; - int8_t pw = cmd_tst_input->buffer[4]; - uint8_t len = cmd_tst_input->buffer[8]; + uint32_t nb_of_tx = 0; + nb_of_tx |= cmd_tst_input->buffer[6] << 24; + nb_of_tx |= cmd_tst_input->buffer[7] << 16; + nb_of_tx |= cmd_tst_input->buffer[8] << 8; + nb_of_tx |= cmd_tst_input->buffer[9]; - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; + uint32_t delay_ms = 0; + delay_ms |= cmd_tst_input->buffer[10] << 24; + delay_ms |= cmd_tst_input->buffer[11] << 16; + delay_ms |= cmd_tst_input->buffer[12] << 8; + delay_ms |= cmd_tst_input->buffer[13]; + + cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx_fsk(NULL, len, freq, pw, nb_of_tx, delay_ms)]; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx( NULL, len, freq, pw, sf, bw, cr, 8, true )]; - } - else - { - // one of the data is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; - } break; } - case CMD_TST_TX_HOP: + case CMD_TST_TX_LRFHSS: { - cmd_tst_output->return_code = CMD_RC_NOT_IMPLEMENTED; - cmd_tst_output->length = 0; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; + + int8_t pw = cmd_tst_input->buffer[4]; + uint8_t len = cmd_tst_input->buffer[5]; + + uint8_t grid = cmd_tst_input->buffer[6]; + uint8_t bw = cmd_tst_input->buffer[7]; + uint8_t cr = cmd_tst_input->buffer[8]; + + SMTC_HAL_TRACE_PRINTF("grid:%u, bw:%u,cr:%u\n", grid, bw, cr); + + uint32_t nb_of_tx = 0; + nb_of_tx |= cmd_tst_input->buffer[9] << 24; + nb_of_tx |= cmd_tst_input->buffer[10] << 16; + nb_of_tx |= cmd_tst_input->buffer[11] << 8; + nb_of_tx |= cmd_tst_input->buffer[12]; + + uint32_t delay_ms = 0; + delay_ms |= cmd_tst_input->buffer[13] << 24; + delay_ms |= cmd_tst_input->buffer[14] << 16; + delay_ms |= cmd_tst_input->buffer[15] << 8; + delay_ms |= cmd_tst_input->buffer[16]; + + bool enable_hopping = cmd_tst_input->buffer[17] & 0x01; + + cmd_tst_output->return_code = + rc_lut[smtc_modem_test_tx_lrfhss(NULL, len, freq, pw, cr, bw, grid, enable_hopping, nb_of_tx, delay_ms)]; + break; } case CMD_TST_TX_CW: @@ -1715,104 +2507,115 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp freq |= cmd_tst_input->buffer[2] << 8; freq |= cmd_tst_input->buffer[3]; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx_cw( freq, pw )]; + cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx_cw(freq, pw)]; break; } - case CMD_TST_RX_CONT: + case CMD_TST_RX_LORA: { - uint8_t raw_sf = cmd_tst_input->buffer[4]; - uint8_t raw_bw = cmd_tst_input->buffer[5]; - uint8_t raw_cr = cmd_tst_input->buffer[6]; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; - // integrity of the data shall be tested here as we perform a data change using LUT before calling api - // function - if( cmd_test_parser_check_sf_bw_cr( raw_sf, raw_bw, raw_cr ) == PARSE_OK ) - { - smtc_modem_test_sf_t sf = cmd_test_sf_table[raw_sf]; - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; - smtc_modem_test_cr_t cr = cmd_test_cr_table[raw_cr]; + uint8_t sf = cmd_tst_input->buffer[4]; + uint8_t bw = cmd_tst_input->buffer[5]; + uint8_t cr = cmd_tst_input->buffer[6]; - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; + uint8_t sync_word = cmd_tst_input->buffer[7]; + uint8_t invert_iq = cmd_tst_input->buffer[8] & 0x01; + uint8_t crc_is_on = cmd_tst_input->buffer[9] & 0x01; + ral_lora_pkt_len_modes_t header_type = cmd_tst_input->buffer[10] & 0x01; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_rx_continuous( freq, sf, bw, cr )]; - } - else - { - // one of the data is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; - } + uint32_t preamble_size = 0; + preamble_size |= cmd_tst_input->buffer[11] << 24; + preamble_size |= cmd_tst_input->buffer[12] << 16; + preamble_size |= cmd_tst_input->buffer[13] << 8; + preamble_size |= cmd_tst_input->buffer[14]; + + uint8_t nb_symb_timeout = cmd_tst_input->buffer[15]; + cmd_tst_output->return_code = rc_lut[smtc_modem_test_rx_lora( + freq, sf, bw, cr, sync_word, invert_iq, crc_is_on, header_type, preamble_size, nb_symb_timeout)]; + + break; + } + case CMD_TST_RX_FSK_CONT: + { + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; + + cmd_tst_output->return_code = rc_lut[smtc_modem_test_rx_fsk_continuous(freq)]; + + break; + } + case CMD_TST_READ_NB_PKTS_RX: + { + uint32_t nb_read_pkt = 0; + cmd_tst_output->return_code = rc_lut[smtc_modem_test_get_nb_rx_packets(&nb_read_pkt)]; + cmd_tst_output->buffer[0] = (nb_read_pkt >> 24) & 0xFF; + cmd_tst_output->buffer[1] = (nb_read_pkt >> 16) & 0xFF; + cmd_tst_output->buffer[2] = (nb_read_pkt >> 8) & 0xFF; + cmd_tst_output->buffer[3] = (nb_read_pkt & 0xFF); + cmd_tst_output->length = 4; break; } - case CMD_TST_READ_NB_PKTS_RX_CONT: + case CMD_TST_READ_LAST_RX_PKT: { - uint32_t nb_read_pkt = 0; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_get_nb_rx_packets( &nb_read_pkt )]; - cmd_tst_output->buffer[0] = ( nb_read_pkt >> 24 ) & 0xFF; - cmd_tst_output->buffer[1] = ( nb_read_pkt >> 16 ) & 0xFF; - cmd_tst_output->buffer[2] = ( nb_read_pkt >> 8 ) & 0xFF; - cmd_tst_output->buffer[3] = ( nb_read_pkt & 0xFF ); - cmd_tst_output->length = 4; + int16_t rssi; + int16_t snr; + uint8_t rx_payload_length; + cmd_tst_output->return_code = rc_lut[smtc_modem_test_get_last_rx_packets(&rssi, &snr, &cmd_tst_output->buffer[4], &rx_payload_length)]; + cmd_tst_output->buffer[0] = (snr >> 8) & 0xFF; + cmd_tst_output->buffer[1] = (snr & 0xFF); + cmd_tst_output->buffer[2] = (rssi >> 8) & 0xFF; + cmd_tst_output->buffer[3] = (rssi & 0xFF); + cmd_tst_output->length = 4 + rx_payload_length; break; } case CMD_TST_RSSI: { - uint8_t raw_bw = cmd_tst_input->buffer[6]; - if( raw_bw < SMTC_MODEM_TEST_BW_COUNT ) - { - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; + uint16_t time_ms = 0; + time_ms |= cmd_tst_input->buffer[4] << 8; + time_ms |= cmd_tst_input->buffer[5]; - uint16_t time_ms = 0; - time_ms |= cmd_tst_input->buffer[4] << 8; - time_ms |= cmd_tst_input->buffer[5]; + uint32_t bw = 0; + bw |= cmd_tst_input->buffer[6] << 24; + bw |= cmd_tst_input->buffer[7] << 16; + bw |= cmd_tst_input->buffer[8] << 8; + bw |= cmd_tst_input->buffer[9]; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_rssi( freq, bw, time_ms )]; - } - else - { - // bw is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; - } + cmd_tst_output->return_code = rc_lut[smtc_modem_test_rssi_lbt(freq, bw, time_ms)]; break; } case CMD_TST_RSSI_GET: { - int8_t rssi = 0; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_get_rssi( &rssi )]; - cmd_tst_output->buffer[0] = rssi; - cmd_tst_output->length = 1; + int8_t rssi = 0; + cmd_tst_output->return_code = rc_lut[smtc_modem_test_get_rssi(&rssi)]; + cmd_tst_output->buffer[0] = rssi; + cmd_tst_output->length = 1; break; } case CMD_TST_RADIO_RST: { - cmd_tst_output->return_code = rc_lut[smtc_modem_test_radio_reset( )]; - break; - } - case CMD_TST_EXIT: - { - cmd_tst_output->return_code = rc_lut[smtc_modem_test_stop( )]; - if( cmd_tst_output->return_code == CMD_RC_OK ) - { - modem_in_test_mode = false; - } + cmd_tst_output->return_code = rc_lut[smtc_modem_test_radio_reset()]; break; } case CMD_TST_BUSYLOOP: { // First check if modem is in test mode - if( modem_in_test_mode == true ) + if (modem_in_test_mode == true) { // Endless loop - while( 1 ) + while (1) { }; } @@ -1825,9 +2628,9 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp case CMD_TST_PANIC: { // First check if modem is in test mode - if( modem_in_test_mode == true ) + if (modem_in_test_mode == true) { - mcu_panic( ); + SMTC_MODEM_HAL_PANIC("TEST PANIC"); } else { @@ -1838,11 +2641,11 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp case CMD_TST_WATCHDOG: { // First check if modem is in test mode - if( modem_in_test_mode == true ) + if (modem_in_test_mode == true) { - hal_mcu_disable_irq( ); + hal_mcu_disable_irq(); // Endless loop - while( 1 ) + while (1) { }; break; @@ -1856,82 +2659,46 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp case CMD_TST_RADIO_READ: { uint8_t command_length = cmd_tst_input->buffer[0]; - uint8_t command[255] = { 0 }; - memcpy( command, &cmd_tst_input->buffer[1], command_length ); + uint8_t command[255] = {0}; + memcpy(command, &cmd_tst_input->buffer[1], command_length); uint8_t data_length = cmd_tst_input->buffer[command_length + 1]; - uint8_t data[255] = { 0 }; + uint8_t data[255] = {0}; cmd_tst_output->return_code = - rc_lut[smtc_modem_test_direct_radio_read( command, command_length, data, data_length )]; - memcpy( cmd_tst_output->buffer, data, data_length ); + rc_lut[smtc_modem_test_direct_radio_read(command, command_length, data, data_length)]; + memcpy(cmd_tst_output->buffer, data, data_length); cmd_tst_output->length = data_length; break; } case CMD_TST_RADIO_WRITE: { uint8_t command_length = cmd_tst_input->buffer[0]; - uint8_t command[255] = { 0 }; - memcpy( command, &cmd_tst_input->buffer[1], command_length ); + uint8_t command[255] = {0}; + memcpy(command, &cmd_tst_input->buffer[1], command_length); uint8_t data_length = cmd_tst_input->buffer[command_length + 1]; - uint8_t data[255] = { 0 }; - memcpy( data, &cmd_tst_input->buffer[command_length + 1], data_length ); + uint8_t data[255] = {0}; + memcpy(data, &cmd_tst_input->buffer[command_length + 1], data_length); cmd_tst_output->return_code = - rc_lut[smtc_modem_test_direct_radio_write( command, command_length, data, data_length )]; + rc_lut[smtc_modem_test_direct_radio_write(command, command_length, data, data_length)]; cmd_tst_output->length = 0; break; } - case CMD_TST_TX_SINGLE_PREAM: - { - uint8_t raw_sf = cmd_tst_input->buffer[5]; - uint8_t raw_bw = cmd_tst_input->buffer[6]; - uint8_t raw_cr = cmd_tst_input->buffer[7]; - - // integrity of the data shall be tested here as we perform a data change using LUT before calling api - // function - if( cmd_test_parser_check_sf_bw_cr( raw_sf, raw_bw, raw_cr ) == PARSE_OK ) - { - smtc_modem_test_sf_t sf = cmd_test_sf_table[raw_sf]; - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; - smtc_modem_test_cr_t cr = cmd_test_cr_table[raw_cr]; - int8_t pw = cmd_tst_input->buffer[4]; - uint8_t len = cmd_tst_input->buffer[8]; - - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; - - uint16_t preamble_length = 0; - preamble_length |= cmd_tst_input->buffer[9] << 8; - preamble_length |= cmd_tst_input->buffer[10]; - - cmd_tst_output->return_code = - rc_lut[smtc_modem_test_tx( NULL, len, freq, pw, sf, bw, cr, preamble_length, false )]; - } - else - { - // one of the data is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; - } - break; - } default: { cmd_tst_output->return_code = CMD_RC_UNKNOWN; - cmd_tst_output->length = 0; + cmd_tst_output->length = 0; break; } } // Erase test command content to avoid twice calls cmd_tst_input->cmd_code = CMD_TST_MAX; - cmd_tst_input->length = 0; + cmd_tst_input->length = 0; - return ( ret ); + return (ret); } /* @@ -1939,70 +2706,50 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- */ -static cmd_length_valid_t cmd_parser_check_cmd_size( host_cmd_id_t cmd_id, uint8_t length ) +static cmd_length_valid_t cmd_parser_check_cmd_size(host_cmd_id_t cmd_id, uint8_t length) { // cmd len too small - if( length < host_cmd_tab[cmd_id][HOST_CMD_TAB_IDX_MIN_LENGTH] ) + if (length < host_cmd_tab[cmd_id][HOST_CMD_TAB_IDX_MIN_LENGTH]) { - SMTC_HAL_TRACE_ERROR( "Command size too small\n" ); + SMTC_HAL_TRACE_ERROR("Command size too small\n"); return CMD_LENGTH_NOT_VALID; } // cmd len too long - if( length > host_cmd_tab[cmd_id][HOST_CMD_TAB_IDX_MAX_LENGTH] ) + if (length > host_cmd_tab[cmd_id][HOST_CMD_TAB_IDX_MAX_LENGTH]) { - SMTC_HAL_TRACE_ERROR( "Command size too long\n" ); + SMTC_HAL_TRACE_ERROR("Command size too long\n"); return CMD_LENGTH_NOT_VALID; } return CMD_LENGTH_VALID; } -static cmd_length_valid_t cmd_test_parser_check_cmd_size( host_cmd_test_id_t tst_id, uint8_t length ) +static cmd_length_valid_t cmd_test_parser_check_cmd_size(host_cmd_test_id_t tst_id, uint8_t length) { // cmd len too small - if( length < host_cmd_test_tab[tst_id][HOST_CMD_TAB_IDX_MIN_LENGTH] ) + if (length < host_cmd_test_tab[tst_id][HOST_CMD_TAB_IDX_MIN_LENGTH]) { - SMTC_HAL_TRACE_ERROR( "Invalid command test size (too small)\n" ); + SMTC_HAL_TRACE_ERROR("Invalid command test size (too small)\n"); return CMD_LENGTH_NOT_VALID; } // cmd len too long - if( length > host_cmd_test_tab[tst_id][HOST_CMD_TAB_IDX_MAX_LENGTH] ) + if (length > host_cmd_test_tab[tst_id][HOST_CMD_TAB_IDX_MAX_LENGTH]) { - SMTC_HAL_TRACE_ERROR( "Invalid command test size (too long)\n" ); + SMTC_HAL_TRACE_ERROR("Invalid command test size (too long)\n"); return CMD_LENGTH_NOT_VALID; } return CMD_LENGTH_VALID; } -static cmd_parse_status_t cmd_test_parser_check_sf_bw_cr( uint8_t sf, uint8_t bw, uint8_t cr ) -{ - if( sf >= SMTC_MODEM_TEST_LORA_SF_COUNT ) - { - return PARSE_ERROR; - } - else if( bw >= SMTC_MODEM_TEST_BW_COUNT ) - { - return PARSE_ERROR; - } - else if( cr >= SMTC_MODEM_TEST_CR_COUNT ) - { - return PARSE_ERROR; - } - else - { - return PARSE_OK; - } -} - -uint32_t cmd_parser_crc( const uint8_t* buf, int len ) +uint32_t cmd_parser_crc(const uint8_t *buf, int len) { uint32_t crc = 0xFFFFFFFF; - while( len-- > 0 ) + while (len-- > 0) { crc = crc ^ *buf++; - for( int i = 0; i < 8; i++ ) + for (int i = 0; i < 8; i++) { - uint32_t mask = -( crc & 1 ); - crc = ( crc >> 1 ) ^ ( 0xEDB88320 & mask ); + uint32_t mask = -(crc & 1); + crc = (crc >> 1) ^ (0xEDB88320 & mask); } } return ~crc; diff --git a/lbm_applications/1_thread_x_on_stm32_u5/main_examples/cmd_parser.h b/lbm_applications/1_thread_x_on_stm32_u5/main_examples/cmd_parser.h index 499c578..4065e50 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/main_examples/cmd_parser.h +++ b/lbm_applications/1_thread_x_on_stm32_u5/main_examples/cmd_parser.h @@ -35,252 +35,302 @@ #define CMD_PARSER_H__ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/* - * ----------------------------------------------------------------------------- - * --- DEPENDENCIES ------------------------------------------------------------ - */ + /* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ -#include // C99 types -#include // bool type +#include // C99 types +#include // bool type #include "smtc_modem_api.h" -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC MACROS ----------------------------------------------------------- - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC MACROS ----------------------------------------------------------- + */ -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC TYPES ------------------------------------------------------------ - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC TYPES ------------------------------------------------------------ + */ -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC CONSTANTS -------------------------------------------------------- - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC CONSTANTS -------------------------------------------------------- + */ -/** - * @brief Host command opcode definition - */ -typedef enum host_cmd_id_e -{ - CMD_RESET = 0x00, - CMD_SET_REGION = 0x01, - CMD_GET_REGION = 0x02, - CMD_JOIN_NETWORK = 0x03, - CMD_REQUEST_UPLINK = 0x04, - CMD_GET_EVENT = 0x05, - CMD_GET_DOWNLINK_DATA = 0x06, - CMD_GET_DOWNLINK_METADATA = 0x07, - CMD_GET_JOIN_EUI = 0x08, - CMD_SET_JOIN_EUI = 0x09, - CMD_GET_DEV_EUI = 0x0A, - CMD_SET_DEV_EUI = 0x0B, - CMD_SET_NWKKEY = 0x0C, - CMD_GET_PIN = 0x0D, - CMD_GET_CHIP_EUI = 0x0E, - CMD_DERIVE_KEYS = 0x0F, - CMD_GET_MODEM_VERSION = 0x10, - CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER = 0x11, - CMD_SET_CERTIFICATION_MODE = 0x12, - CMD_EMERGENCY_UPLINK = 0x13, - CMD_REQUEST_EMPTY_UPLINK = 0x14, - CMD_LEAVE_NETWORK = 0x15, - CMD_ALARM_START_TIMER = 0x16, - CMD_ALARM_CLEAR_TIMER = 0x17, - CMD_ALARM_GET_REMAINING_TIME = 0x18, - CMD_GET_NEXT_TX_MAX_PAYLOAD = 0x19, - CMD_GET_DUTY_CYCLE_STATUS = 0x1A, - CMD_SET_NETWORK_TYPE = 0x1B, - CMD_SET_JOIN_DR_DISTRIBUTION = 0x1C, - CMD_SET_ADR_PROFILE = 0x1D, - CMD_SET_NB_TRANS = 0x1E, - CMD_GET_NB_TRANS = 0x1F, - CMD_GET_ENABLED_DATARATE = 0x20, - CMD_SET_ADR_ACK_LIMIT_DELAY = 0x21, - CMD_GET_ADR_ACK_LIMIT_DELAY = 0x22, - CMD_SET_CRYSTAL_ERR = 0x23, - CMD_LBT_SET_PARAMS = 0x24, - CMD_LBT_GET_PARAMS = 0x25, - CMD_LBT_SET_STATE = 0x26, - CMD_LBT_GET_STATE = 0x27, - CMD_GET_CHARGE = 0x28, - CMD_RESET_CHARGE = 0x29, - CMD_SET_CLASS = 0x2A, - CMD_CLASS_B_SET_PING_SLOT_PERIODICITY = 0x2B, - CMD_CLASS_B_GET_PING_SLOT_PERIODICITY = 0x2C, - CMD_MULTICAST_SET_GROUP_CONFIG = 0x2D, - CMD_MULTICAST_GET_GROUP_CONFIG = 0x2E, - CMD_MULTICAST_CLASS_C_START_SESSION = 0x2F, - CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS = 0x30, - CMD_MULTICAST_CLASS_C_STOP_SESSION = 0x31, - CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS = 0x32, - CMD_MULTICAST_CLASS_B_START_SESSION = 0x33, - CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS = 0x34, - CMD_MULTICAST_CLASS_B_STOP_SESSION = 0x35, - CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS = 0x36, - CMD_START_ALCSYNC_SERVICE = 0x37, - CMD_STOP_ALCSYNC_SERVICE = 0x38, - CMD_GET_ALCSYNC_TIME = 0x39, - CMD_TRIG_ALCSYNC_REQUEST = 0x3A, - CMD_LORAWAN_MAC_REQUEST = 0x3B, - CMD_GET_LORAWAN_TIME = 0x3C, - CMD_GET_LINK_CHECK_DATA = 0x3D, - CMD_SET_DUTY_CYCLE_STATE = 0x3E, - CMD_DEBUG_CONNECT_WITH_ABP = 0x3F, - CMD_TEST = 0x40, - CMD_SET_TX_POWER_OFFSET = 0x41, - CMD_GET_TX_POWER_OFFSET = 0x42, - CMD_CSMA_SET_STATE = 0x43, - CMD_CSMA_GET_STATE = 0x44, - CMD_CSMA_SET_PARAMETERS = 0x45, - CMD_CSMA_GET_PARAMETERS = 0x46, - CMD_STREAM_INIT = 0x47, - CMD_STREAM_ADD_DATA = 0x48, - CMD_STREAM_STATUS = 0x49, - CMD_LFU_INIT = 0x4A, - CMD_LFU_DATA = 0x4B, - CMD_LFU_START = 0x4C, - CMD_LFU_RESET = 0x4D, - CMD_DM_ENABLE = 0x4E, - CMD_DM_GET_PORT = 0x4F, - CMD_DM_SET_PORT = 0x50, - CMD_DM_GET_INFO_INTERVAL = 0x51, - CMD_DM_SET_INFO_INTERVAL = 0x52, - CMD_DM_GET_PERIODIC_INFO_FIELDS = 0x53, - CMD_DM_SET_PERIODIC_INFO_FIELDS = 0x54, - CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS = 0x55, - CMD_DM_SET_USER_DATA = 0x56, - CMD_DM_GET_USER_DATA = 0x57, - CMD_MAX -} host_cmd_id_t; + /** + * @brief Host command opcode definition + */ + typedef enum host_cmd_id_e + { + CMD_RESET = 0x00, + CMD_SET_REGION = 0x01, + CMD_GET_REGION = 0x02, + CMD_JOIN_NETWORK = 0x03, + CMD_REQUEST_UPLINK = 0x04, + CMD_GET_EVENT = 0x05, + CMD_GET_DOWNLINK_DATA = 0x06, + CMD_GET_DOWNLINK_METADATA = 0x07, + CMD_GET_JOIN_EUI = 0x08, + CMD_SET_JOIN_EUI = 0x09, + CMD_GET_DEV_EUI = 0x0A, + CMD_SET_DEV_EUI = 0x0B, + CMD_SET_NWKKEY = 0x0C, + CMD_GET_PIN = 0x0D, + CMD_GET_CHIP_EUI = 0x0E, + CMD_DERIVE_KEYS = 0x0F, + CMD_GET_MODEM_VERSION = 0x10, + CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER = 0x11, + CMD_SET_CERTIFICATION_MODE = 0x12, + CMD_EMERGENCY_UPLINK = 0x13, + CMD_REQUEST_EMPTY_UPLINK = 0x14, + CMD_LEAVE_NETWORK = 0x15, + CMD_ALARM_START_TIMER = 0x16, + CMD_ALARM_CLEAR_TIMER = 0x17, + CMD_ALARM_GET_REMAINING_TIME = 0x18, + CMD_GET_NEXT_TX_MAX_PAYLOAD = 0x19, + CMD_GET_DUTY_CYCLE_STATUS = 0x1A, + CMD_SET_NETWORK_TYPE = 0x1B, + CMD_SET_JOIN_DR_DISTRIBUTION = 0x1C, + CMD_SET_ADR_PROFILE = 0x1D, + CMD_SET_NB_TRANS = 0x1E, + CMD_GET_NB_TRANS = 0x1F, + CMD_GET_ENABLED_DATARATE = 0x20, + CMD_SET_ADR_ACK_LIMIT_DELAY = 0x21, + CMD_GET_ADR_ACK_LIMIT_DELAY = 0x22, + CMD_SET_CRYSTAL_ERR = 0x23, + CMD_LBT_SET_PARAMS = 0x24, + CMD_LBT_GET_PARAMS = 0x25, + CMD_LBT_SET_STATE = 0x26, + CMD_LBT_GET_STATE = 0x27, + CMD_GET_CHARGE = 0x28, + CMD_RESET_CHARGE = 0x29, + CMD_SET_CLASS = 0x2A, + CMD_CLASS_B_SET_PING_SLOT_PERIODICITY = 0x2B, + CMD_CLASS_B_GET_PING_SLOT_PERIODICITY = 0x2C, + CMD_MULTICAST_SET_GROUP_CONFIG = 0x2D, + CMD_MULTICAST_GET_GROUP_CONFIG = 0x2E, + CMD_MULTICAST_CLASS_C_START_SESSION = 0x2F, + CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS = 0x30, + CMD_MULTICAST_CLASS_C_STOP_SESSION = 0x31, + CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS = 0x32, + CMD_MULTICAST_CLASS_B_START_SESSION = 0x33, + CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS = 0x34, + CMD_MULTICAST_CLASS_B_STOP_SESSION = 0x35, + CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS = 0x36, + CMD_START_ALCSYNC_SERVICE = 0x37, + CMD_STOP_ALCSYNC_SERVICE = 0x38, + CMD_GET_ALCSYNC_TIME = 0x39, + CMD_TRIG_ALCSYNC_REQUEST = 0x3A, + CMD_LORAWAN_MAC_REQUEST = 0x3B, + CMD_GET_LORAWAN_TIME = 0x3C, + CMD_GET_LINK_CHECK_DATA = 0x3D, + CMD_SET_DUTY_CYCLE_STATE = 0x3E, + CMD_DEBUG_CONNECT_WITH_ABP = 0x3F, + CMD_TEST = 0x40, + CMD_SET_TX_POWER_OFFSET = 0x41, + CMD_GET_TX_POWER_OFFSET = 0x42, + CMD_CSMA_SET_STATE = 0x43, + CMD_CSMA_GET_STATE = 0x44, + CMD_CSMA_SET_PARAMETERS = 0x45, + CMD_CSMA_GET_PARAMETERS = 0x46, + CMD_STREAM_INIT = 0x47, + CMD_STREAM_ADD_DATA = 0x48, + CMD_STREAM_STATUS = 0x49, + CMD_LFU_INIT = 0x4A, + CMD_LFU_DATA = 0x4B, + CMD_LFU_START = 0x4C, + CMD_LFU_RESET = 0x4D, + CMD_DM_ENABLE = 0x4E, + CMD_DM_GET_PORT = 0x4F, + CMD_DM_SET_PORT = 0x50, + CMD_DM_GET_INFO_INTERVAL = 0x51, + CMD_DM_SET_INFO_INTERVAL = 0x52, + CMD_DM_GET_PERIODIC_INFO_FIELDS = 0x53, + CMD_DM_SET_PERIODIC_INFO_FIELDS = 0x54, + CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS = 0x55, + CMD_DM_SET_USER_DATA = 0x56, + CMD_DM_GET_USER_DATA = 0x57, + CMD_GET_STATUS = 0x58, + CMD_SUSPEND_RADIO_COMMUNICATIONS = 0x59, + CMD_DM_HANDLE_ALCSYNC = 0x5A, + CMD_SET_APPKEY = 0x5B, + CMD_GET_ADR_PROFILE = 0x5C, + CMD_GET_CERTIFICATION_MODE = 0x5D, +#if defined(STM32L476xx) + CMD_STORE_AND_FORWARD_SET_STATE = 0x5E, + CMD_STORE_AND_FORWARD_GET_STATE = 0x5F, + CMD_STORE_AND_FORWARD_ADD_DATA = 0x60, + CMD_STORE_AND_FORWARD_CLEAR_DATA = 0x61, + CMD_STORE_AND_FORWARD_GET_FREE_SLOT = 0x62, +#endif // STM32L476xx +#if defined(ADD_APP_GEOLOCATION) && defined(STM32L476xx) + CMD_GNSS_SCAN = 0x70, + CMD_GNSS_SCAN_CANCEL = 0x71, + CMD_GNSS_GET_EVENT_DATA_SCAN_DONE = 0x72, + CMD_GNSS_GET_SCAN_DONE_RAW_DATA_LIST = 0x73, + CMD_GNSS_GET_SCAN_DONE_METADATA_LIST = 0x74, + CMD_GNSS_GET_SCAN_DONE_SCAN_SV = 0x75, + CMD_GNSS_GET_EVENT_DATA_TERMINATED = 0x76, + CMD_GNSS_SET_CONST = 0x77, + CMD_GNSS_SET_PORT = 0x78, + CMD_GNSS_SCAN_AGGREGATE = 0x79, + CMD_GNSS_SEND_MODE = 0x7A, + CMD_GNSS_ALM_DEMOD_START = 0x7B, + CMD_GNSS_ALM_DEMOD_SET_CONSTEL = 0x7C, + CMD_GNSS_ALM_DEMOD_GET_EVENT_DATA_ALM_UPD = 0x7D, + CMD_CLOUD_ALMANAC_START = 0x7E, + CMD_CLOUD_ALMANAC_STOP = 0x7F, + CMD_WIFI_SCAN_START = 0x80, + CMD_WIFI_SCAN_CANCEL = 0x81, + CMD_WIFI_GET_SCAN_DONE_SCAN_DATA = 0x82, + CMD_WIFI_GET_EVENT_DATA_TERMINATED = 0x83, + CMD_WIFI_SET_PORT = 0x84, + CMD_WIFI_SEND_MODE = 0x85, + CMD_WIFI_SET_PAYLOAD_FORMAT = 0x86, + CMD_LR11XX_RADIO_READ = 0x90, + CMD_LR11XX_RADIO_WRITE = 0x91, +#endif // ADD_APP_GEOLOCATION && STM32L476xx + CMD_SET_RTC_OFFSET = 0x92, +#if defined(USE_RELAY_TX) + CMD_SET_RELAY_CONFIG = 0x93, + CMD_GET_RELAY_CONFIG = 0x94, +#endif + CMD_GET_SUSPEND_RADIO_COMMUNICATIONS = 0x95, + CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF = 0x96, + CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF = 0x97, + CMD_MODEM_GET_CRASHLOG = 0x98, + CMD_MAX + } host_cmd_id_t; -/** - * @brief Host test command opcode definition - */ -typedef enum host_cmd_test_id_e -{ - CMD_TST_START = 0x00, - CMD_TST_NOP = 0x01, - CMD_TST_TX_SINGLE = 0x02, - CMD_TST_TX_CONT = 0x03, - CMD_TST_TX_HOP = 0x04, - CMD_TST_NA_1 = 0x05, - CMD_TST_TX_CW = 0x06, - CMD_TST_RX_CONT = 0x07, - CMD_TST_RSSI = 0x08, - CMD_TST_RADIO_RST = 0x09, - CMD_TST_EXIT = 0x0B, - CMD_TST_BUSYLOOP = 0x0C, - CMD_TST_PANIC = 0x0D, - CMD_TST_WATCHDOG = 0x0E, - CMD_TST_RADIO_READ = 0x0F, - CMD_TST_RADIO_WRITE = 0x10, - CMD_TST_TX_SINGLE_PREAM = 0x14, - CMD_TST_RSSI_GET = 0x15, - CMD_TST_READ_NB_PKTS_RX_CONT = 0x18, - CMD_TST_MAX -} host_cmd_test_id_t; + /** + * @brief Host test command opcode definition + */ + typedef enum host_cmd_test_id_e + { + CMD_TST_START = 0x00, + CMD_TST_EXIT = 0x01, + CMD_TST_NOP = 0x02, + CMD_TST_TX_LORA = 0x03, + CMD_TST_TX_FSK = 0x04, + CMD_TST_TX_LRFHSS = 0x05, + CMD_TST_TX_CW = 0x06, + CMD_TST_RX_LORA = 0x07, + CMD_TST_RX_FSK_CONT = 0x08, + CMD_TST_READ_NB_PKTS_RX = 0x09, + CMD_TST_READ_LAST_RX_PKT = 0x0A, + CMD_TST_RSSI = 0x0B, + CMD_TST_RSSI_GET = 0x0C, + CMD_TST_RADIO_RST = 0x0D, + CMD_TST_BUSYLOOP = 0x0E, + CMD_TST_PANIC = 0x0F, + CMD_TST_WATCHDOG = 0x10, + CMD_TST_RADIO_READ = 0x11, + CMD_TST_RADIO_WRITE = 0x12, + CMD_TST_MAX + } host_cmd_test_id_t; -/** - * @brief Command parser serial return code - */ -typedef enum cmd_serial_rc_code_e -{ - CMD_RC_OK = 0x00, - CMD_RC_UNKNOWN = 0x01, - CMD_RC_NOT_IMPLEMENTED = 0x02, - CMD_RC_NOT_INIT = 0x03, - CMD_RC_INVALID = 0x04, - CMD_RC_BUSY = 0x05, - CMD_RC_FAIL = 0x06, - CMD_RC_BAD_CRC = 0x08, - CMD_RC_BAD_SIZE = 0x0A, - CMD_RC_FRAME_ERROR = 0x0F, - CMD_RC_NO_TIME = 0x10, - CMD_RC_INVALID_STACK_ID = 0x11, - CMD_RC_NO_EVENT = 0x12, -} cmd_serial_rc_code_t; + /** + * @brief Command parser serial return code + */ + typedef enum cmd_serial_rc_code_e + { + CMD_RC_OK = 0x00, + CMD_RC_UNKNOWN = 0x01, + CMD_RC_NOT_IMPLEMENTED = 0x02, + CMD_RC_NOT_INIT = 0x03, + CMD_RC_INVALID = 0x04, + CMD_RC_BUSY = 0x05, + CMD_RC_FAIL = 0x06, + CMD_RC_BAD_CRC = 0x08, + CMD_RC_BAD_SIZE = 0x0A, + CMD_RC_FRAME_ERROR = 0x0F, + CMD_RC_NO_TIME = 0x10, + CMD_RC_INVALID_STACK_ID = 0x11, + CMD_RC_NO_EVENT = 0x12, + } cmd_serial_rc_code_t; -/** - * @brief Input command structure - */ -typedef struct cmd_input_e -{ - host_cmd_id_t cmd_code; - uint8_t length; - uint8_t* buffer; -} cmd_input_t; + /** + * @brief Input command structure + */ + typedef struct cmd_input_e + { + host_cmd_id_t cmd_code; + uint8_t length; + uint8_t *buffer; + } cmd_input_t; -/** - * @brief Command response struture - */ -typedef struct cmd_response_e -{ - cmd_serial_rc_code_t return_code; - uint8_t length; - uint8_t* buffer; -} cmd_response_t; + /** + * @brief Command response struture + */ + typedef struct cmd_response_e + { + cmd_serial_rc_code_t return_code; + uint8_t length; + uint8_t *buffer; + } cmd_response_t; -/** - * @brief Input test command structure - */ -typedef struct cmd_tst_response_e -{ - cmd_serial_rc_code_t return_code; - uint8_t length; - uint8_t* buffer; -} cmd_tst_response_t; + /** + * @brief Input test command structure + */ + typedef struct cmd_tst_response_e + { + cmd_serial_rc_code_t return_code; + uint8_t length; + uint8_t *buffer; + } cmd_tst_response_t; -/** - * @brief Test command response struture - */ -typedef struct cmd_tst_input_e -{ - host_cmd_test_id_t cmd_code; - uint8_t length; - uint8_t* buffer; -} cmd_tst_input_t; + /** + * @brief Test command response struture + */ + typedef struct cmd_tst_input_e + { + host_cmd_test_id_t cmd_code; + uint8_t length; + uint8_t *buffer; + } cmd_tst_input_t; -/** - * @brief Command parser status - */ -typedef enum cmd_parse_status_e -{ - PARSE_ERROR, - PARSE_OK, -} cmd_parse_status_t; -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC FUNCTIONS PROTOTYPES --------------------------------------------- - */ + /** + * @brief Command parser status + */ + typedef enum cmd_parse_status_e + { + PARSE_ERROR, + PARSE_OK, + } cmd_parse_status_t; + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS PROTOTYPES --------------------------------------------- + */ -/** - * @brief Parse command received on serial link - * - * @param [in] cmd_input Contains the command received - * @param [out] cmd_output Contains the response to the received command - * @return cmd_parse_status_t - */ -cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output ); + /** + * @brief Parse command received on serial link + * + * @param [in] cmd_input Contains the command received + * @param [out] cmd_output Contains the response to the received command + * @return cmd_parse_status_t + */ + cmd_parse_status_t parse_cmd(cmd_input_t *cmd_input, cmd_response_t *cmd_output); -/** - * @brief Parse test command received on serial link - * - * @param [in] cmd_tst_input Contains the command received - * @param [out] cmd_tst_output Contains the response to the received command - * @return cmd_parse_status_t - */ -cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_response_t* cmd_tst_output ); + /** + * @brief Parse test command received on serial link + * + * @param [in] cmd_tst_input Contains the command received + * @param [out] cmd_tst_output Contains the response to the received command + * @return cmd_parse_status_t + */ + cmd_parse_status_t cmd_test_parser(cmd_tst_input_t *cmd_tst_input, cmd_tst_response_t *cmd_tst_output); #ifdef __cplusplus } #endif -#endif // CMD_PARSER_H__ +#endif // CMD_PARSER_H__ /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_applications/1_thread_x_on_stm32_u5/main_examples/example_options.h b/lbm_applications/1_thread_x_on_stm32_u5/main_examples/example_options.h index 324f1ad..8b08fa2 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/main_examples/example_options.h +++ b/lbm_applications/1_thread_x_on_stm32_u5/main_examples/example_options.h @@ -36,16 +36,17 @@ #define EXAMPLE_OPTIONS_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/* - * ----------------------------------------------------------------------------- - * --- DEPENDENCIES ------------------------------------------------------------ - */ + /* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ -#include // C99 types -#include // bool type +#include // C99 types +#include // bool type #include "smtc_modem_api.h" @@ -79,13 +80,10 @@ extern "C" { */ #define MODEM_EXAMPLE_REGION SMTC_MODEM_REGION_EU_868 - -// clang-format on - #ifdef __cplusplus } #endif -#endif // EXAMPLE_OPTIONS_H +#endif // EXAMPLE_OPTIONS_H /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_applications/1_thread_x_on_stm32_u5/main_examples/hw_modem.c b/lbm_applications/1_thread_x_on_stm32_u5/main_examples/hw_modem.c index f15d0d5..554bf34 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/main_examples/hw_modem.c +++ b/lbm_applications/1_thread_x_on_stm32_u5/main_examples/hw_modem.c @@ -57,7 +57,7 @@ * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define HW_MODEM_RX_BUFF_MAX_LENGTH 259 +#define HW_MODEM_RX_BUFF_MAX_LENGTH 261 /* * ----------------------------------------------------------------------------- diff --git a/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/radio_utilities.c b/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/radio_utilities.c index fb961d0..78bf549 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/radio_utilities.c +++ b/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/radio_utilities.c @@ -3,11 +3,12 @@ * * @brief User radio utilities implementations * - * Revised BSD License - * Copyright Semtech Corporation 2022. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* diff --git a/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/radio_utilities.h b/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/radio_utilities.h index 57a38e9..f787cf4 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/radio_utilities.h +++ b/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/radio_utilities.h @@ -3,11 +3,12 @@ * * @brief User radio utilities definitions * - * Revised BSD License - * Copyright Semtech Corporation 2022. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef RADIO_UTILITIES_H diff --git a/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/ral_lr11xx_bsp.c b/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/ral_lr11xx_bsp.c index 4e6f7b2..7a366f8 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/ral_lr11xx_bsp.c +++ b/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/ral_lr11xx_bsp.c @@ -52,6 +52,34 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +// TODO: check values +#define LR11XX_GFSK_RX_CONSUMPTION_DCDC 5400 +#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 7500 + +#define LR11XX_GFSK_RX_CONSUMPTION_LDO 5400 +#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO 7500 + +#define LR11XX_LORA_RX_CONSUMPTION_DCDC 5700 +#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC 7800 + +#define LR11XX_LORA_RX_CONSUMPTION_LDO 5700 +#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO 7800 + +#define LR11XX_LP_MIN_OUTPUT_POWER -17 +#define LR11XX_LP_MAX_OUTPUT_POWER 15 + +#define LR11XX_HP_MIN_OUTPUT_POWER -9 +#define LR11XX_HP_MAX_OUTPUT_POWER 22 + +#define LR11XX_HF_MIN_OUTPUT_POWER -18 +#define LR11XX_HF_MAX_OUTPUT_POWER 13 + +#define LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET 17 +#define LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET 9 +#define LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET 18 + +#define LR11XX_PWR_VREG_VBAT_SWITCH 8 + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -77,21 +105,187 @@ typedef struct lr11xx_pa_pwr_cfg_s * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define LR11XX_PWR_VREG_VBAT_SWITCH 8 - -#define LR11XX_MIN_PWR_LP_LF -17 -#define LR11XX_MAX_PWR_LP_LF 15 - -#define LR11XX_MIN_PWR_HP_LF -9 -#define LR11XX_MAX_PWR_HP_LF 22 - -#define LR11XX_MIN_PWR_PA_HF -18 -#define LR11XX_MAX_PWR_PA_HF 13 - -const lr11xx_pa_pwr_cfg_t pa_lp_cfg_table[LR11XX_MAX_PWR_LP_LF - LR11XX_MIN_PWR_LP_LF + 1] = LR11XX_PA_LP_LF_CFG_TABLE; -const lr11xx_pa_pwr_cfg_t pa_hp_cfg_table[LR11XX_MAX_PWR_HP_LF - LR11XX_MIN_PWR_HP_LF + 1] = LR11XX_PA_HP_LF_CFG_TABLE; - -const lr11xx_pa_pwr_cfg_t pa_hf_cfg_table[LR11XX_MAX_PWR_PA_HF - LR11XX_MIN_PWR_PA_HF + 1] = LR11XX_PA_HF_CFG_TABLE; +const lr11xx_pa_pwr_cfg_t pa_lp_cfg_table[LR11XX_LP_MAX_OUTPUT_POWER - LR11XX_LP_MIN_OUTPUT_POWER + 1] = LR11XX_PA_LP_LF_CFG_TABLE; +const lr11xx_pa_pwr_cfg_t pa_hp_cfg_table[LR11XX_HP_MAX_OUTPUT_POWER - LR11XX_HP_MIN_OUTPUT_POWER + 1] = LR11XX_PA_HP_LF_CFG_TABLE; + +const lr11xx_pa_pwr_cfg_t pa_hf_cfg_table[LR11XX_HF_MAX_OUTPUT_POWER - LR11XX_HF_MIN_OUTPUT_POWER + 1] = LR11XX_PA_HF_CFG_TABLE; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[] = { + 10820, // -17 dBm + 10980, // -16 dBm + 11060, // -15 dBm + 11160, // -14 dBm + 11300, // -13 dBm + 11430, // -12 dBm + 11550, // -11 dBm + 11680, // -10 dBm + 11930, // -9 dBm + 12170, // -8 dBm + 12420, // -7 dBm + 12650, // -6 dBm + 12900, // -5 dBm + 13280, // -4 dBm + 13600, // -3 dBm + 14120, // -2 dBm + 14600, // -1 dBm + 15090, // 0 dBm + 15780, // 1 dBm + 16490, // 2 dBm + 17250, // 3 dBm + 17850, // 4 dBm + 18720, // 5 dBm + 19640, // 6 dBm + 20560, // 7 dBm + 21400, // 8 dBm + 22620, // 9 dBm + 23720, // 10 dBm + 25050, // 11 dBm + 26350, // 12 dBm + 27870, // 13 dBm + 28590, // 14 dBm + 37820, // 15 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[] = { + 14950, // -17 dBm + 15280, // -16 dBm + 15530, // -15 dBm + 15770, // -14 dBm + 16020, // -13 dBm + 16290, // -12 dBm + 16550, // -11 dBm + 16760, // -10 dBm + 17280, // -9 dBm + 17770, // -8 dBm + 18250, // -7 dBm + 18750, // -6 dBm + 19250, // -5 dBm + 19960, // -4 dBm + 20710, // -3 dBm + 21620, // -2 dBm + 22570, // -1 dBm + 23570, // 0 dBm + 24990, // 1 dBm + 26320, // 2 dBm + 27830, // 3 dBm + 29070, // 4 dBm + 30660, // 5 dBm + 32490, // 6 dBm + 34220, // 7 dBm + 35820, // 8 dBm + 38180, // 9 dBm + 40220, // 10 dBm + 42800, // 11 dBm + 45030, // 12 dBm + 47900, // 13 dBm + 51220, // 14 dBm + 66060, // 15 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[] = { + 27750, // -9 dBm + 29100, // -8 dBm + 30320, // -7 dBm + 31650, // -6 dBm + 34250, // -5 dBm + 35550, // -4 dBm + 36770, // -3 dBm + 39250, // -2 dBm + 41480, // -1 dBm + 43820, // 0 dBm + 46000, // 1 dBm + 49020, // 2 dBm + 50900, // 3 dBm + 54200, // 4 dBm + 56330, // 5 dBm + 59050, // 6 dBm + 62210, // 7 dBm + 65270, // 8 dBm + 68600, // 9 dBm + 71920, // 10 dBm + 75500, // 11 dBm + 79500, // 12 dBm + 84130, // 13 dBm + 88470, // 14 dBm + 92200, // 15 dBm + 94340, // 16 dBm + 96360, // 17 dBm + 98970, // 18 dBm + 102220, // 19 dBm + 106250, // 20 dBm + 111300, // 21 dBm + 113040, // 22 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[] = { + 31310, // -9 dBm + 32700, // -8 dBm + 33970, // -7 dBm + 35270, // -6 dBm + 37900, // -5 dBm + 39140, // -4 dBm + 40380, // -3 dBm + 42860, // -2 dBm + 45150, // -1 dBm + 47400, // 0 dBm + 49600, // 1 dBm + 52600, // 2 dBm + 54460, // 3 dBm + 57690, // 4 dBm + 59840, // 5 dBm + 62550, // 6 dBm + 65750, // 7 dBm + 68520, // 8 dBm + 72130, // 9 dBm + 75230, // 10 dBm + 78600, // 11 dBm + 82770, // 12 dBm + 87450, // 13 dBm + 91700, // 14 dBm + 95330, // 15 dBm + 97520, // 16 dBm + 99520, // 17 dBm + 102080, // 18 dBm + 105140, // 19 dBm + 109300, // 20 dBm + 114460, // 21 dBm + 116530, // 22 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[] = { + 11800, // -18 dBm + 11800, // -17 dBm + 11800, // -16 dBm + 11900, // -15 dBm + 12020, // -14 dBm + 12120, // -13 dBm + 12230, // -12 dBm + 12390, // -11 dBm + 12540, // -10 dBm + 12740, // -9 dBm + 12960, // -8 dBm + 13150, // -7 dBm + 13460, // -6 dBm + 13770, // -5 dBm + 14070, // -4 dBm + 14460, // -3 dBm + 15030, // -2 dBm + 15440, // -1 dBm + 16030, // 0 dBm + 16980, // 1 dBm + 17590, // 2 dBm + 18270, // 3 dBm + 19060, // 4 dBm + 19900, // 5 dBm + 20740, // 6 dBm + 21610, // 7 dBm + 22400, // 8 dBm + 23370, // 9 dBm + 24860, // 10 dBm + 26410, // 11 dBm + 26430, // 12 dBm + 27890, // 13 dBm +}; /* * ----------------------------------------------------------------------------- @@ -250,8 +444,8 @@ void ral_lr11xx_bsp_get_rssi_calibration_table( const void* context, const uint3 } } -void ral_lr11xx_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_lr11xx_bsp_get_lora_cad_det_peak( const void *context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed } @@ -284,32 +478,32 @@ void lr11xx_get_tx_cfg( lr11xx_pa_type_t pa_type, int8_t expected_output_pwr_in_ case LR11XX_WITH_LF_LP_PA: { // Check power boundaries for LP LF PA: The output power must be in range [ -17 , +15 ] dBm - if( power < LR11XX_MIN_PWR_LP_LF ) + if( power < LR11XX_LP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_LP_LF; + power = LR11XX_LP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_LP_LF ) + else if( power > LR11XX_LP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_LP_LF; + power = LR11XX_LP_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_LP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].power; output_params->chip_output_pwr_in_dbm_expected = power; break; } case LR11XX_WITH_LF_HP_PA: { // Check power boundaries for HP LF PA: The output power must be in range [ -9 , +22 ] dBm - if( power < LR11XX_MIN_PWR_HP_LF ) + if( power < LR11XX_HP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_HP_LF; + power = LR11XX_HP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_HP_LF ) + else if( power > LR11XX_HP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_HP_LF; + power = LR11XX_HP_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HP; output_params->chip_output_pwr_in_dbm_expected = power; @@ -324,62 +518,214 @@ void lr11xx_get_tx_cfg( lr11xx_pa_type_t pa_type, int8_t expected_output_pwr_in_ output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT; } - output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].power; break; } case LR11XX_WITH_LF_LP_HP_PA: { // Check power boundaries for LP/HP LF PA: The output power must be in range [ -17 , +22 ] dBm - if( power < LR11XX_MIN_PWR_LP_LF ) + if( power < LR11XX_LP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_LP_LF; + power = LR11XX_LP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_HP_LF ) + else if( power > LR11XX_HP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_HP_LF; + power = LR11XX_HP_MAX_OUTPUT_POWER; } output_params->chip_output_pwr_in_dbm_expected = power; - if( power <= LR11XX_MAX_PWR_LP_LF ) + if( power <= LR11XX_LP_MAX_OUTPUT_POWER ) { output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_LP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].power; } else { output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT; - output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].power; } break; } case LR11XX_WITH_HF_PA: { // Check power boundaries for HF PA: The output power must be in range [ -18 , +13 ] dBm - if( power < LR11XX_MIN_PWR_PA_HF ) + if( power < LR11XX_HF_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_PA_HF; + power = LR11XX_HF_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_PA_HF ) + else if( power > LR11XX_HF_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_PA_HF; + power = LR11XX_HF_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HF; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].power; output_params->chip_output_pwr_in_dbm_expected = power; break; } } } +ral_status_t ral_lr11xx_bsp_get_instantaneous_tx_power_consumption( const void *context, + const ral_lr11xx_bsp_tx_cfg_output_params_t* tx_cfg, + lr11xx_system_reg_mode_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_LP ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_LP_MAX_OUTPUT_POWER ) + { + index = LR11XX_LP_MAX_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_LP_MIN_OUTPUT_POWER ) + { + index = LR11XX_LP_MIN_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[index]; + } + else + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[index]; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HP ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VBAT ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_HP_MAX_OUTPUT_POWER ) + { + index = LR11XX_HP_MAX_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_HP_MIN_OUTPUT_POWER ) + { + index = LR11XX_HP_MIN_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[index]; + } + else + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[index]; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HF ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_HF_MAX_OUTPUT_POWER ) + { + index = LR11XX_HF_MAX_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_HF_MIN_OUTPUT_POWER ) + { + index = LR11XX_HF_MIN_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[index]; + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_lr11xx_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + lr11xx_system_reg_mode_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_GFSK_RX_CONSUMPTION_DCDC; + } + else + { + // TODO: find the good values + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_GFSK_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_lr11xx_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + lr11xx_system_reg_mode_t radio_reg_mode, + const bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_LORA_RX_CONSUMPTION_DCDC; + } + else + { + // TODO: find the good values + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_LORA_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/ral_sx126x_bsp.c b/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/ral_sx126x_bsp.c index 25b939f..efcb717 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/ral_sx126x_bsp.c +++ b/lbm_applications/1_thread_x_on_stm32_u5/radio_hal/ral_sx126x_bsp.c @@ -47,11 +47,175 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +#define SX126X_LP_MIN_OUTPUT_POWER -17 +#define SX126X_LP_MAX_OUTPUT_POWER 15 + +#define SX126X_HP_MIN_OUTPUT_POWER -9 +#define SX126X_HP_MAX_OUTPUT_POWER 22 + +#define SX126X_LP_CONVERT_TABLE_INDEX_OFFSET 17 +#define SX126X_HP_CONVERT_TABLE_INDEX_OFFSET 9 + +// TODO: check values +#define SX126X_GFSK_RX_CONSUMPTION_DCDC 4200 +#define SX126X_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 4800 + +#define SX126X_GFSK_RX_CONSUMPTION_LDO 8000 +#define SX126X_GFSK_RX_BOOSTED_CONSUMPTION_LDO 9300 + +#define SX126X_LORA_RX_CONSUMPTION_DCDC 4600 +#define SX126X_LORA_RX_BOOSTED_CONSUMPTION_DCDC 5300 + +#define SX126X_LORA_RX_CONSUMPTION_LDO 8880 +#define SX126X_LORA_RX_BOOSTED_CONSUMPTION_LDO 10100 + /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_lp[] = { + 5200, // -17 dBm + 5400, // -16 dBm + 5600, // -15 dBm + 5700, // -14 dBm + 5800, // -13 dBm + 6000, // -12 dBm + 6100, // -11 dBm + 6200, // -10 dBm + 6500, // -9 dBm + 6800, // -8 dBm + 7000, // -7 dBm + 7300, // -6 dBm + 7500, // -5 dBm + 7900, // -4 dBm + 8300, // -3 dBm + 8800, // -2 dBm + 9300, // -1 dBm + 9800, // 0 dBm + 10600, // 1 dBm + 11400, // 2 dBm + 12200, // 3 dBm + 12900, // 4 dBm + 13800, // 5 dBm + 14700, // 6 dBm + 15700, // 7 dBm + 16600, // 8 dBm + 17900, // 9 dBm + 18500, // 10 dBm + 20500, // 11 dBm + 21900, // 12 dBm + 23500, // 13 dBm + 25500, // 14 dBm + 32500, // 15 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_lp[] = { + 9800, // -17 dBm + 10300, // -16 dBm + 10500, // -15 dBm + 10800, // -14 dBm + 11100, // -13 dBm + 11300, // -12 dBm + 11600, // -11 dBm + 11900, // -10 dBm + 12400, // -9 dBm + 12900, // -8 dBm + 13400, // -7 dBm + 13900, // -6 dBm + 14500, // -5 dBm + 15300, // -4 dBm + 16000, // -3 dBm + 17000, // -2 dBm + 18000, // -1 dBm + 19000, // 0 dBm + 20600, // 1 dBm + 22000, // 2 dBm + 23500, // 3 dBm + 24900, // 4 dBm + 26600, // 5 dBm + 28400, // 6 dBm + 30200, // 7 dBm + 32000, // 8 dBm + 34300, // 9 dBm + 36600, // 10 dBm + 39200, // 11 dBm + 41700, // 12 dBm + 44700, // 13 dBm + 48200, // 14 dBm + 52200, // 15 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_hp[] = { + 24000, // -9 dBm + 25400, // -8 dBm + 26700, // -7 dBm + 28000, // -6 dBm + 30600, // -5 dBm + 31900, // -4 dBm + 33200, // -3 dBm + 35700, // -2 dBm + 38200, // -1 dBm + 40600, // 0 dBm + 42900, // 1 dBm + 46200, // 2 dBm + 48200, // 3 dBm + 51800, // 4 dBm + 54100, // 5 dBm + 57000, // 6 dBm + 60300, // 7 dBm + 63500, // 8 dBm + 67100, // 9 dBm + 70500, // 10 dBm + 74200, // 11 dBm + 78400, // 12 dBm + 83500, // 13 dBm + 89300, // 14 dBm + 92400, // 15 dBm + 94500, // 16 dBm + 95400, // 17 dBm + 97500, // 18 dBm + 100100, // 19 dBm + 103800, // 20 dBm + 109100, // 21 dBm + 117900, // 22 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_hp[] = { + 25900, // -9 dBm + 27400, // -8 dBm + 28700, // -7 dBm + 30000, // -6 dBm + 32600, // -5 dBm + 33900, // -4 dBm + 35200, // -3 dBm + 37700, // -2 dBm + 40100, // -1 dBm + 42600, // 0 dBm + 44900, // 1 dBm + 48200, // 2 dBm + 50200, // 3 dBm + 53800, // 4 dBm + 56100, // 5 dBm + 59000, // 6 dBm + 62300, // 7 dBm + 65500, // 8 dBm + 69000, // 9 dBm + 72500, // 10 dBm + 76200, // 11 dBm + 80400, // 12 dBm + 85400, // 13 dBm + 90200, // 14 dBm + 94400, // 15 dBm + 96500, // 16 dBm + 97700, // 17 dBm + 99500, // 18 dBm + 102100, // 19 dBm + 105800, // 20 dBm + 111000, // 21 dBm + 119800, // 22 dBm +}; + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -172,10 +336,118 @@ void ral_sx126x_bsp_get_ocp_value( const void* context, uint8_t* ocp_in_step_of_ // Do nothing, let the driver choose the default values } -void ral_sx126x_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_sx126x_bsp_get_lora_cad_det_peak( const void *context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed } +ral_status_t ral_sx126x_bsp_get_instantaneous_tx_power_consumption( const void *context, + const ral_sx126x_bsp_tx_cfg_output_params_t* tx_cfg_output_params, sx126x_reg_mod_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + // SX1261 + if( tx_cfg_output_params->pa_cfg.device_sel == 0x01 ) + { + uint8_t index = 0; + + if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected > SX126X_LP_MAX_OUTPUT_POWER ) + { + index = SX126X_LP_MAX_OUTPUT_POWER + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected < SX126X_LP_MIN_OUTPUT_POWER ) + { + index = SX126X_LP_MIN_OUTPUT_POWER + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg_output_params->chip_output_pwr_in_dbm_expected + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_lp[index]; + } + else + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_lp[index]; + } + } + // SX1262 + else if( tx_cfg_output_params->pa_cfg.device_sel == 0x00 ) + { + uint8_t index = 0; + + if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected > SX126X_HP_MAX_OUTPUT_POWER ) + { + index = SX126X_HP_MAX_OUTPUT_POWER + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected < SX126X_HP_MIN_OUTPUT_POWER ) + { + index = SX126X_HP_MIN_OUTPUT_POWER + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg_output_params->chip_output_pwr_in_dbm_expected + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_hp[index]; + } + else + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_hp[index]; + } + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_sx126x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + sx126x_reg_mod_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + // TODO: find the br/bw dependent values + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : SX126X_GFSK_RX_CONSUMPTION_DCDC; + } + else + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_GFSK_RX_BOOSTED_CONSUMPTION_LDO : SX126X_GFSK_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_sx126x_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + sx126x_reg_mod_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + // TODO: find the bw dependent values + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_LORA_RX_BOOSTED_CONSUMPTION_DCDC : SX126X_LORA_RX_CONSUMPTION_DCDC; + } + else + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_LORA_RX_BOOSTED_CONSUMPTION_LDO : SX126X_LORA_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/modem_pinout.h b/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/modem_pinout.h index 0fddbf6..513056e 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/modem_pinout.h +++ b/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/modem_pinout.h @@ -39,30 +39,31 @@ #endif */ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/* - * ----------------------------------------------------------------------------- - * --- DEPENDENCIES ------------------------------------------------------------ - */ + /* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ #include "smtc_hal_gpio_pin_names.h" -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC MACROS ----------------------------------------------------------- - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC MACROS ----------------------------------------------------------- + */ -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC CONSTANTS -------------------------------------------------------- - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC CONSTANTS -------------------------------------------------------- + */ -/********************************************************************************/ -/* Application dependant */ -/********************************************************************************/ -// clang-format off + /********************************************************************************/ + /* Application dependant */ + /********************************************************************************/ + /* clang-format off */ //Debug uart specific pinout for debug print #define DEBUG_UART_TX PA_9 @@ -90,7 +91,7 @@ extern "C" { #define EXTI_BUTTON PC_13 -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- @@ -105,4 +106,4 @@ extern "C" { } #endif -#endif //__MODEM_PIN_NAMES_H__ +#endif //__MODEM_PIN_NAMES_H__ diff --git a/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/smtc_hal_dbg_trace.h b/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/smtc_hal_dbg_trace.h index f2b42ed..f961b8c 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/smtc_hal_dbg_trace.h +++ b/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/smtc_hal_dbg_trace.h @@ -35,23 +35,24 @@ #define __SMTC_HAL_DBG_TRACE_H__ #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /* * ----------------------------------------------------------------------------- * --- DEPENDENCIES ------------------------------------------------------------ */ -#include // C99 types -#include // bool type +#include // C99 types +#include // bool type #include "smtc_hal_trace.h" -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC CONSTANTS -------------------------------------------------------- - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC CONSTANTS -------------------------------------------------------- + */ -// clang-format off + /* clang-format off */ #define HAL_FEATURE_OFF 0 #define HAL_FEATURE_ON !HAL_FEATURE_OFF @@ -67,14 +68,14 @@ extern "C" { #ifndef HAL_DBG_TRACE_RP #define HAL_DBG_TRACE_RP HAL_FEATURE_OFF #endif -// clang-format on + /* clang-format on */ -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC MACROS ----------------------------------------------------------- - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC MACROS ----------------------------------------------------------- + */ -// clang-format off + /* clang-format off */ #if ( HAL_DBG_TRACE_COLOR == HAL_FEATURE_ON ) #define HAL_DBG_TRACE_COLOR_BLACK "\x1B[0;30m" #define HAL_DBG_TRACE_COLOR_RED "\x1B[0;31m" @@ -170,27 +171,27 @@ extern "C" { #endif -// clang-format on + /* clang-format on */ -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC CONSTANTS -------------------------------------------------------- - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC CONSTANTS -------------------------------------------------------- + */ -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC TYPES ------------------------------------------------------------ - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC TYPES ------------------------------------------------------------ + */ -/* - * ----------------------------------------------------------------------------- - * --- PUBLIC FUNCTIONS PROTOTYPES --------------------------------------------- - */ + /* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS PROTOTYPES --------------------------------------------- + */ #ifdef __cplusplus } #endif -#endif // __SMTC_HAL_DBG_TRACE_H__ +#endif // __SMTC_HAL_DBG_TRACE_H__ /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/smtc_hal_rtc.c b/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/smtc_hal_rtc.c index c35f8ef..20ad011 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/smtc_hal_rtc.c +++ b/lbm_applications/1_thread_x_on_stm32_u5/smtc_hal_u5/smtc_hal_rtc.c @@ -59,7 +59,7 @@ * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -// clang-format off +/* clang-format off */ // MCU Wake Up Time #define MIN_ALARM_DELAY_IN_TICKS 3U // in ticks @@ -101,7 +101,7 @@ #define DAYS_IN_MONTH_CORRECTION_NORM ( ( uint32_t ) 0x99AAA0 ) #define DAYS_IN_MONTH_CORRECTION_LEAP ( ( uint32_t ) 0x445550 ) -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_applications/1_thread_x_on_stm32_u5/smtc_modem_hal/smtc_modem_hal.c b/lbm_applications/1_thread_x_on_stm32_u5/smtc_modem_hal/smtc_modem_hal.c index 8e80a58..80bfeee 100644 --- a/lbm_applications/1_thread_x_on_stm32_u5/smtc_modem_hal/smtc_modem_hal.c +++ b/lbm_applications/1_thread_x_on_stm32_u5/smtc_modem_hal/smtc_modem_hal.c @@ -272,10 +272,11 @@ void smtc_modem_hal_crashlog_set_status(bool available) { crashlog_available_noinit = available; } - +volatile static bool temp = 0x1; // solve new behaviour introduce with gcc11 compilo bool smtc_modem_hal_crashlog_get_status(void) { - return crashlog_available_noinit; + bool temp2 = crashlog_available_noinit & temp; + return temp2; } /* ------------ assert management ------------*/ @@ -319,11 +320,6 @@ void smtc_modem_hal_software_radio_irq(void) radio_dio_irq.callback(radio_dio_irq.context); } -void smtc_modem_hal_radio_irq_clear_pending(void) -{ - hal_gpio_clear_pending_irq(RADIO_DIOX); -} - void smtc_modem_hal_start_radio_tcxo(void) { // put here the code that will start the tcxo if needed diff --git a/lbm_applications/2_porting_nrf_52840/main_examples/example_options.h b/lbm_applications/2_porting_nrf_52840/main_examples/example_options.h index fa52bd3..e32880a 100644 --- a/lbm_applications/2_porting_nrf_52840/main_examples/example_options.h +++ b/lbm_applications/2_porting_nrf_52840/main_examples/example_options.h @@ -83,8 +83,6 @@ extern "C" { #define MODEM_EXAMPLE_REGION SMTC_MODEM_REGION_WW2G4 #endif -// clang-format on - #ifdef __cplusplus } #endif diff --git a/lbm_applications/2_porting_nrf_52840/main_examples/main_porting_tests.c b/lbm_applications/2_porting_nrf_52840/main_examples/main_porting_tests.c index 8f7895e..ed340d0 100644 --- a/lbm_applications/2_porting_nrf_52840/main_examples/main_porting_tests.c +++ b/lbm_applications/2_porting_nrf_52840/main_examples/main_porting_tests.c @@ -183,7 +183,8 @@ static ralf_params_lora_t tx_lora_param = { .sync_word = S .pkt_params.invert_iq_is_on = false, .pkt_params.preamble_len_in_symb = 8 }; #if( ENABLE_TEST_FLASH != 0 ) -static const char* name_context_type[] = { "MODEM", "LR1MAC", "DEVNONCE", "SECURE_ELEMENT" }; +static const char* name_context_type[] = { "MODEM", "KEY_MODEM", "LORAWAN_STACK", + "FUOTA", "SECURE_ELEMENT", "STORE_AND_FORWARD" }; #endif /* @@ -1448,7 +1449,6 @@ static bool porting_test_flash( void ) SMTC_HAL_TRACE_MSG( "----------------------------------------\n porting_test_flash : \n" ); SMTC_HAL_TRACE_MSG_COLOR( " !! TEST TO BE LAUNCH TWICE !! To check writing after MCU reset \n", HAL_DBG_TRACE_COLOR_BLUE ); - /* LORAWAN */ ret = test_context_store_restore( CONTEXT_LORAWAN_STACK ); if( ret == false ) diff --git a/lbm_applications/2_porting_nrf_52840/radio_hal/lr11xx_hal.c b/lbm_applications/2_porting_nrf_52840/radio_hal/lr11xx_hal.c index bfde51b..13434b4 100644 --- a/lbm_applications/2_porting_nrf_52840/radio_hal/lr11xx_hal.c +++ b/lbm_applications/2_porting_nrf_52840/radio_hal/lr11xx_hal.c @@ -111,7 +111,19 @@ lr11xx_hal_status_t lr11xx_hal_write( const void* context, const uint8_t* comman hal_gpio_set_value( RADIO_NSS, 0 ); hal_spi_in_out( RADIO_SPI_ID, command, command_length, NULL, 0 ); - hal_spi_in_out( RADIO_SPI_ID, data, data_length, NULL, 0 ); + // data write to the radio could be more than 255 bytes but not more than 512 bytes + if( data_length > 255 ) + { + hal_spi_in_out( RADIO_SPI_ID, data, 255, NULL, 0 ); + hal_spi_in_out( RADIO_SPI_ID, &data[255], data_length - 255, NULL, 0 ); + } + else + { + if( data_length > 0 ) + { + hal_spi_in_out( RADIO_SPI_ID, data, data_length, NULL, 0 ); + } + } #if defined( USE_LR11XX_CRC_OVER_SPI ) // Add crc byte at the end of the transaction @@ -167,8 +179,16 @@ lr11xx_hal_status_t lr11xx_hal_read( const void* context, const uint8_t* command #else hal_spi_in_out( RADIO_SPI_ID, 0, 0, NULL, 0 ); #endif - - hal_spi_in_out( RADIO_SPI_ID, 0, 0, data, data_length ); + // data read from the radio could be more than 255 bytes but not more than 512 bytes + if( data_length > 255 ) + { + hal_spi_in_out( RADIO_SPI_ID, 0, 0, data, 255 ); + hal_spi_in_out( RADIO_SPI_ID, 0, 0, &data[255], data_length - 255 ); + } + else + { + hal_spi_in_out( RADIO_SPI_ID, 0, 0, data, data_length ); + } #if defined( USE_LR11XX_CRC_OVER_SPI ) // read crc sent by lr11xx at the end of the transaction @@ -199,7 +219,17 @@ lr11xx_hal_status_t lr11xx_hal_direct_read( const void* context, uint8_t* data, // Put NSS low to start spi transaction hal_gpio_set_value( RADIO_NSS, 0 ); - hal_spi_in_out( RADIO_SPI_ID, 0, 0, data, data_length ); + + // data read from the radio could be more than 255 bytes but not more than 512 bytes + if( data_length > 255 ) + { + hal_spi_in_out( RADIO_SPI_ID, 0, 0, data, 255 ); + hal_spi_in_out( RADIO_SPI_ID, 0, 0, &data[255], data_length - 255 ); + } + else + { + hal_spi_in_out( RADIO_SPI_ID, 0, 0, data, data_length ); + } #if defined( USE_LR11XX_CRC_OVER_SPI ) // read crc sent by lr11xx by sending one more NOP diff --git a/lbm_applications/2_porting_nrf_52840/radio_hal/radio_utilities.c b/lbm_applications/2_porting_nrf_52840/radio_hal/radio_utilities.c index fb961d0..78bf549 100644 --- a/lbm_applications/2_porting_nrf_52840/radio_hal/radio_utilities.c +++ b/lbm_applications/2_porting_nrf_52840/radio_hal/radio_utilities.c @@ -3,11 +3,12 @@ * * @brief User radio utilities implementations * - * Revised BSD License - * Copyright Semtech Corporation 2022. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* diff --git a/lbm_applications/2_porting_nrf_52840/radio_hal/radio_utilities.h b/lbm_applications/2_porting_nrf_52840/radio_hal/radio_utilities.h index 57a38e9..1dcd447 100644 --- a/lbm_applications/2_porting_nrf_52840/radio_hal/radio_utilities.h +++ b/lbm_applications/2_porting_nrf_52840/radio_hal/radio_utilities.h @@ -3,11 +3,12 @@ * * @brief User radio utilities definitions * - * Revised BSD License - * Copyright Semtech Corporation 2022. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef RADIO_UTILITIES_H @@ -78,7 +81,6 @@ int8_t radio_utilities_get_tx_power_offset( void ); */ void radio_utilities_set_tx_power_offset( int8_t tx_pwr_offset_db ); - #ifdef __cplusplus } #endif diff --git a/lbm_applications/2_porting_nrf_52840/radio_hal/ral_lr11xx_bsp.c b/lbm_applications/2_porting_nrf_52840/radio_hal/ral_lr11xx_bsp.c index 133c440..23b286f 100644 --- a/lbm_applications/2_porting_nrf_52840/radio_hal/ral_lr11xx_bsp.c +++ b/lbm_applications/2_porting_nrf_52840/radio_hal/ral_lr11xx_bsp.c @@ -52,6 +52,34 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +// TODO: check values +#define LR11XX_GFSK_RX_CONSUMPTION_DCDC 5400 +#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 7500 + +#define LR11XX_GFSK_RX_CONSUMPTION_LDO 5400 +#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO 7500 + +#define LR11XX_LORA_RX_CONSUMPTION_DCDC 5700 +#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC 7800 + +#define LR11XX_LORA_RX_CONSUMPTION_LDO 5700 +#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO 7800 + +#define LR11XX_LP_MIN_OUTPUT_POWER -17 +#define LR11XX_LP_MAX_OUTPUT_POWER 15 + +#define LR11XX_HP_MIN_OUTPUT_POWER -9 +#define LR11XX_HP_MAX_OUTPUT_POWER 22 + +#define LR11XX_HF_MIN_OUTPUT_POWER -18 +#define LR11XX_HF_MAX_OUTPUT_POWER 13 + +#define LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET 17 +#define LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET 9 +#define LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET 18 + +#define LR11XX_PWR_VREG_VBAT_SWITCH 8 + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -77,21 +105,187 @@ typedef struct lr11xx_pa_pwr_cfg_s * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define LR11XX_PWR_VREG_VBAT_SWITCH 8 - -#define LR11XX_MIN_PWR_LP_LF -17 -#define LR11XX_MAX_PWR_LP_LF 15 - -#define LR11XX_MIN_PWR_HP_LF -9 -#define LR11XX_MAX_PWR_HP_LF 22 - -#define LR11XX_MIN_PWR_PA_HF -18 -#define LR11XX_MAX_PWR_PA_HF 13 - -const lr11xx_pa_pwr_cfg_t pa_lp_cfg_table[LR11XX_MAX_PWR_LP_LF - LR11XX_MIN_PWR_LP_LF + 1] = LR11XX_PA_LP_LF_CFG_TABLE; -const lr11xx_pa_pwr_cfg_t pa_hp_cfg_table[LR11XX_MAX_PWR_HP_LF - LR11XX_MIN_PWR_HP_LF + 1] = LR11XX_PA_HP_LF_CFG_TABLE; - -const lr11xx_pa_pwr_cfg_t pa_hf_cfg_table[LR11XX_MAX_PWR_PA_HF - LR11XX_MIN_PWR_PA_HF + 1] = LR11XX_PA_HF_CFG_TABLE; +const lr11xx_pa_pwr_cfg_t pa_lp_cfg_table[LR11XX_LP_MAX_OUTPUT_POWER - LR11XX_LP_MIN_OUTPUT_POWER + 1] = LR11XX_PA_LP_LF_CFG_TABLE; +const lr11xx_pa_pwr_cfg_t pa_hp_cfg_table[LR11XX_HP_MAX_OUTPUT_POWER - LR11XX_HP_MIN_OUTPUT_POWER + 1] = LR11XX_PA_HP_LF_CFG_TABLE; + +const lr11xx_pa_pwr_cfg_t pa_hf_cfg_table[LR11XX_HF_MAX_OUTPUT_POWER - LR11XX_HF_MIN_OUTPUT_POWER + 1] = LR11XX_PA_HF_CFG_TABLE; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[] = { + 10820, // -17 dBm + 10980, // -16 dBm + 11060, // -15 dBm + 11160, // -14 dBm + 11300, // -13 dBm + 11430, // -12 dBm + 11550, // -11 dBm + 11680, // -10 dBm + 11930, // -9 dBm + 12170, // -8 dBm + 12420, // -7 dBm + 12650, // -6 dBm + 12900, // -5 dBm + 13280, // -4 dBm + 13600, // -3 dBm + 14120, // -2 dBm + 14600, // -1 dBm + 15090, // 0 dBm + 15780, // 1 dBm + 16490, // 2 dBm + 17250, // 3 dBm + 17850, // 4 dBm + 18720, // 5 dBm + 19640, // 6 dBm + 20560, // 7 dBm + 21400, // 8 dBm + 22620, // 9 dBm + 23720, // 10 dBm + 25050, // 11 dBm + 26350, // 12 dBm + 27870, // 13 dBm + 28590, // 14 dBm + 37820, // 15 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[] = { + 14950, // -17 dBm + 15280, // -16 dBm + 15530, // -15 dBm + 15770, // -14 dBm + 16020, // -13 dBm + 16290, // -12 dBm + 16550, // -11 dBm + 16760, // -10 dBm + 17280, // -9 dBm + 17770, // -8 dBm + 18250, // -7 dBm + 18750, // -6 dBm + 19250, // -5 dBm + 19960, // -4 dBm + 20710, // -3 dBm + 21620, // -2 dBm + 22570, // -1 dBm + 23570, // 0 dBm + 24990, // 1 dBm + 26320, // 2 dBm + 27830, // 3 dBm + 29070, // 4 dBm + 30660, // 5 dBm + 32490, // 6 dBm + 34220, // 7 dBm + 35820, // 8 dBm + 38180, // 9 dBm + 40220, // 10 dBm + 42800, // 11 dBm + 45030, // 12 dBm + 47900, // 13 dBm + 51220, // 14 dBm + 66060, // 15 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[] = { + 27750, // -9 dBm + 29100, // -8 dBm + 30320, // -7 dBm + 31650, // -6 dBm + 34250, // -5 dBm + 35550, // -4 dBm + 36770, // -3 dBm + 39250, // -2 dBm + 41480, // -1 dBm + 43820, // 0 dBm + 46000, // 1 dBm + 49020, // 2 dBm + 50900, // 3 dBm + 54200, // 4 dBm + 56330, // 5 dBm + 59050, // 6 dBm + 62210, // 7 dBm + 65270, // 8 dBm + 68600, // 9 dBm + 71920, // 10 dBm + 75500, // 11 dBm + 79500, // 12 dBm + 84130, // 13 dBm + 88470, // 14 dBm + 92200, // 15 dBm + 94340, // 16 dBm + 96360, // 17 dBm + 98970, // 18 dBm + 102220, // 19 dBm + 106250, // 20 dBm + 111300, // 21 dBm + 113040, // 22 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[] = { + 31310, // -9 dBm + 32700, // -8 dBm + 33970, // -7 dBm + 35270, // -6 dBm + 37900, // -5 dBm + 39140, // -4 dBm + 40380, // -3 dBm + 42860, // -2 dBm + 45150, // -1 dBm + 47400, // 0 dBm + 49600, // 1 dBm + 52600, // 2 dBm + 54460, // 3 dBm + 57690, // 4 dBm + 59840, // 5 dBm + 62550, // 6 dBm + 65750, // 7 dBm + 68520, // 8 dBm + 72130, // 9 dBm + 75230, // 10 dBm + 78600, // 11 dBm + 82770, // 12 dBm + 87450, // 13 dBm + 91700, // 14 dBm + 95330, // 15 dBm + 97520, // 16 dBm + 99520, // 17 dBm + 102080, // 18 dBm + 105140, // 19 dBm + 109300, // 20 dBm + 114460, // 21 dBm + 116530, // 22 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[] = { + 11800, // -18 dBm + 11800, // -17 dBm + 11800, // -16 dBm + 11900, // -15 dBm + 12020, // -14 dBm + 12120, // -13 dBm + 12230, // -12 dBm + 12390, // -11 dBm + 12540, // -10 dBm + 12740, // -9 dBm + 12960, // -8 dBm + 13150, // -7 dBm + 13460, // -6 dBm + 13770, // -5 dBm + 14070, // -4 dBm + 14460, // -3 dBm + 15030, // -2 dBm + 15440, // -1 dBm + 16030, // 0 dBm + 16980, // 1 dBm + 17590, // 2 dBm + 18270, // 3 dBm + 19060, // 4 dBm + 19900, // 5 dBm + 20740, // 6 dBm + 21610, // 7 dBm + 22400, // 8 dBm + 23370, // 9 dBm + 24860, // 10 dBm + 26410, // 11 dBm + 26430, // 12 dBm + 27890, // 13 dBm +}; /* * ----------------------------------------------------------------------------- @@ -252,8 +446,8 @@ void ral_lr11xx_bsp_get_rssi_calibration_table( const void* context, const uint3 } } -void ral_lr11xx_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_lr11xx_bsp_get_lora_cad_det_peak( const void *context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed } @@ -290,32 +484,32 @@ void lr11xx_get_tx_cfg( lr11xx_pa_type_t pa_type, int8_t expected_output_pwr_in_ case LR11XX_WITH_LF_LP_PA: { // Check power boundaries for LP LF PA: The output power must be in range [ -17 , +15 ] dBm - if( power < LR11XX_MIN_PWR_LP_LF ) + if( power < LR11XX_LP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_LP_LF; + power = LR11XX_LP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_LP_LF ) + else if( power > LR11XX_LP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_LP_LF; + power = LR11XX_LP_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_LP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].power; output_params->chip_output_pwr_in_dbm_expected = power; break; } case LR11XX_WITH_LF_HP_PA: { // Check power boundaries for HP LF PA: The output power must be in range [ -9 , +22 ] dBm - if( power < LR11XX_MIN_PWR_HP_LF ) + if( power < LR11XX_HP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_HP_LF; + power = LR11XX_HP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_HP_LF ) + else if( power > LR11XX_HP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_HP_LF; + power = LR11XX_HP_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HP; output_params->chip_output_pwr_in_dbm_expected = power; @@ -330,62 +524,214 @@ void lr11xx_get_tx_cfg( lr11xx_pa_type_t pa_type, int8_t expected_output_pwr_in_ output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT; } - output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].power; break; } case LR11XX_WITH_LF_LP_HP_PA: { // Check power boundaries for LP/HP LF PA: The output power must be in range [ -17 , +22 ] dBm - if( power < LR11XX_MIN_PWR_LP_LF ) + if( power < LR11XX_LP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_LP_LF; + power = LR11XX_LP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_HP_LF ) + else if( power > LR11XX_HP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_HP_LF; + power = LR11XX_HP_MAX_OUTPUT_POWER; } output_params->chip_output_pwr_in_dbm_expected = power; - if( power <= LR11XX_MAX_PWR_LP_LF ) + if( power <= LR11XX_LP_MAX_OUTPUT_POWER ) { output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_LP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].power; } else { output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT; - output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].power; } break; } case LR11XX_WITH_HF_PA: { // Check power boundaries for HF PA: The output power must be in range [ -18 , +13 ] dBm - if( power < LR11XX_MIN_PWR_PA_HF ) + if( power < LR11XX_HF_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_PA_HF; + power = LR11XX_HF_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_PA_HF ) + else if( power > LR11XX_HF_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_PA_HF; + power = LR11XX_HF_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HF; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].power; output_params->chip_output_pwr_in_dbm_expected = power; break; } } } +ral_status_t ral_lr11xx_bsp_get_instantaneous_tx_power_consumption( const void *context, + const ral_lr11xx_bsp_tx_cfg_output_params_t* tx_cfg, + lr11xx_system_reg_mode_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_LP ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_LP_MAX_OUTPUT_POWER ) + { + index = LR11XX_LP_MAX_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_LP_MIN_OUTPUT_POWER ) + { + index = LR11XX_LP_MIN_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[index]; + } + else + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[index]; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HP ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VBAT ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_HP_MAX_OUTPUT_POWER ) + { + index = LR11XX_HP_MAX_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_HP_MIN_OUTPUT_POWER ) + { + index = LR11XX_HP_MIN_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[index]; + } + else + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[index]; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HF ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_HF_MAX_OUTPUT_POWER ) + { + index = LR11XX_HF_MAX_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_HF_MIN_OUTPUT_POWER ) + { + index = LR11XX_HF_MIN_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[index]; + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_lr11xx_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + lr11xx_system_reg_mode_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_GFSK_RX_CONSUMPTION_DCDC; + } + else + { + // TODO: find the good values + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_GFSK_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_lr11xx_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + lr11xx_system_reg_mode_t radio_reg_mode, + const bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_LORA_RX_CONSUMPTION_DCDC; + } + else + { + // TODO: find the good values + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_LORA_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_applications/2_porting_nrf_52840/radio_hal/ral_sx126x_bsp.c b/lbm_applications/2_porting_nrf_52840/radio_hal/ral_sx126x_bsp.c index 25b939f..efcb717 100644 --- a/lbm_applications/2_porting_nrf_52840/radio_hal/ral_sx126x_bsp.c +++ b/lbm_applications/2_porting_nrf_52840/radio_hal/ral_sx126x_bsp.c @@ -47,11 +47,175 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +#define SX126X_LP_MIN_OUTPUT_POWER -17 +#define SX126X_LP_MAX_OUTPUT_POWER 15 + +#define SX126X_HP_MIN_OUTPUT_POWER -9 +#define SX126X_HP_MAX_OUTPUT_POWER 22 + +#define SX126X_LP_CONVERT_TABLE_INDEX_OFFSET 17 +#define SX126X_HP_CONVERT_TABLE_INDEX_OFFSET 9 + +// TODO: check values +#define SX126X_GFSK_RX_CONSUMPTION_DCDC 4200 +#define SX126X_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 4800 + +#define SX126X_GFSK_RX_CONSUMPTION_LDO 8000 +#define SX126X_GFSK_RX_BOOSTED_CONSUMPTION_LDO 9300 + +#define SX126X_LORA_RX_CONSUMPTION_DCDC 4600 +#define SX126X_LORA_RX_BOOSTED_CONSUMPTION_DCDC 5300 + +#define SX126X_LORA_RX_CONSUMPTION_LDO 8880 +#define SX126X_LORA_RX_BOOSTED_CONSUMPTION_LDO 10100 + /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_lp[] = { + 5200, // -17 dBm + 5400, // -16 dBm + 5600, // -15 dBm + 5700, // -14 dBm + 5800, // -13 dBm + 6000, // -12 dBm + 6100, // -11 dBm + 6200, // -10 dBm + 6500, // -9 dBm + 6800, // -8 dBm + 7000, // -7 dBm + 7300, // -6 dBm + 7500, // -5 dBm + 7900, // -4 dBm + 8300, // -3 dBm + 8800, // -2 dBm + 9300, // -1 dBm + 9800, // 0 dBm + 10600, // 1 dBm + 11400, // 2 dBm + 12200, // 3 dBm + 12900, // 4 dBm + 13800, // 5 dBm + 14700, // 6 dBm + 15700, // 7 dBm + 16600, // 8 dBm + 17900, // 9 dBm + 18500, // 10 dBm + 20500, // 11 dBm + 21900, // 12 dBm + 23500, // 13 dBm + 25500, // 14 dBm + 32500, // 15 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_lp[] = { + 9800, // -17 dBm + 10300, // -16 dBm + 10500, // -15 dBm + 10800, // -14 dBm + 11100, // -13 dBm + 11300, // -12 dBm + 11600, // -11 dBm + 11900, // -10 dBm + 12400, // -9 dBm + 12900, // -8 dBm + 13400, // -7 dBm + 13900, // -6 dBm + 14500, // -5 dBm + 15300, // -4 dBm + 16000, // -3 dBm + 17000, // -2 dBm + 18000, // -1 dBm + 19000, // 0 dBm + 20600, // 1 dBm + 22000, // 2 dBm + 23500, // 3 dBm + 24900, // 4 dBm + 26600, // 5 dBm + 28400, // 6 dBm + 30200, // 7 dBm + 32000, // 8 dBm + 34300, // 9 dBm + 36600, // 10 dBm + 39200, // 11 dBm + 41700, // 12 dBm + 44700, // 13 dBm + 48200, // 14 dBm + 52200, // 15 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_hp[] = { + 24000, // -9 dBm + 25400, // -8 dBm + 26700, // -7 dBm + 28000, // -6 dBm + 30600, // -5 dBm + 31900, // -4 dBm + 33200, // -3 dBm + 35700, // -2 dBm + 38200, // -1 dBm + 40600, // 0 dBm + 42900, // 1 dBm + 46200, // 2 dBm + 48200, // 3 dBm + 51800, // 4 dBm + 54100, // 5 dBm + 57000, // 6 dBm + 60300, // 7 dBm + 63500, // 8 dBm + 67100, // 9 dBm + 70500, // 10 dBm + 74200, // 11 dBm + 78400, // 12 dBm + 83500, // 13 dBm + 89300, // 14 dBm + 92400, // 15 dBm + 94500, // 16 dBm + 95400, // 17 dBm + 97500, // 18 dBm + 100100, // 19 dBm + 103800, // 20 dBm + 109100, // 21 dBm + 117900, // 22 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_hp[] = { + 25900, // -9 dBm + 27400, // -8 dBm + 28700, // -7 dBm + 30000, // -6 dBm + 32600, // -5 dBm + 33900, // -4 dBm + 35200, // -3 dBm + 37700, // -2 dBm + 40100, // -1 dBm + 42600, // 0 dBm + 44900, // 1 dBm + 48200, // 2 dBm + 50200, // 3 dBm + 53800, // 4 dBm + 56100, // 5 dBm + 59000, // 6 dBm + 62300, // 7 dBm + 65500, // 8 dBm + 69000, // 9 dBm + 72500, // 10 dBm + 76200, // 11 dBm + 80400, // 12 dBm + 85400, // 13 dBm + 90200, // 14 dBm + 94400, // 15 dBm + 96500, // 16 dBm + 97700, // 17 dBm + 99500, // 18 dBm + 102100, // 19 dBm + 105800, // 20 dBm + 111000, // 21 dBm + 119800, // 22 dBm +}; + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -172,10 +336,118 @@ void ral_sx126x_bsp_get_ocp_value( const void* context, uint8_t* ocp_in_step_of_ // Do nothing, let the driver choose the default values } -void ral_sx126x_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_sx126x_bsp_get_lora_cad_det_peak( const void *context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed } +ral_status_t ral_sx126x_bsp_get_instantaneous_tx_power_consumption( const void *context, + const ral_sx126x_bsp_tx_cfg_output_params_t* tx_cfg_output_params, sx126x_reg_mod_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + // SX1261 + if( tx_cfg_output_params->pa_cfg.device_sel == 0x01 ) + { + uint8_t index = 0; + + if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected > SX126X_LP_MAX_OUTPUT_POWER ) + { + index = SX126X_LP_MAX_OUTPUT_POWER + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected < SX126X_LP_MIN_OUTPUT_POWER ) + { + index = SX126X_LP_MIN_OUTPUT_POWER + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg_output_params->chip_output_pwr_in_dbm_expected + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_lp[index]; + } + else + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_lp[index]; + } + } + // SX1262 + else if( tx_cfg_output_params->pa_cfg.device_sel == 0x00 ) + { + uint8_t index = 0; + + if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected > SX126X_HP_MAX_OUTPUT_POWER ) + { + index = SX126X_HP_MAX_OUTPUT_POWER + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected < SX126X_HP_MIN_OUTPUT_POWER ) + { + index = SX126X_HP_MIN_OUTPUT_POWER + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg_output_params->chip_output_pwr_in_dbm_expected + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_hp[index]; + } + else + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_hp[index]; + } + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_sx126x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + sx126x_reg_mod_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + // TODO: find the br/bw dependent values + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : SX126X_GFSK_RX_CONSUMPTION_DCDC; + } + else + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_GFSK_RX_BOOSTED_CONSUMPTION_LDO : SX126X_GFSK_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_sx126x_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + sx126x_reg_mod_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + // TODO: find the bw dependent values + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_LORA_RX_BOOSTED_CONSUMPTION_DCDC : SX126X_LORA_RX_CONSUMPTION_DCDC; + } + else + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_LORA_RX_BOOSTED_CONSUMPTION_LDO : SX126X_LORA_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_applications/2_porting_nrf_52840/radio_hal/ral_sx128x_bsp.c b/lbm_applications/2_porting_nrf_52840/radio_hal/ral_sx128x_bsp.c index 575503f..161f251 100644 --- a/lbm_applications/2_porting_nrf_52840/radio_hal/ral_sx128x_bsp.c +++ b/lbm_applications/2_porting_nrf_52840/radio_hal/ral_sx128x_bsp.c @@ -48,11 +48,106 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +#define SX128X_CONVERT_TABLE_INDEX_OFFSET 18 + +#define SX128X_LORA_RX_CONSUMPTION_BW_200_DCDC 5500 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_DCDC 6200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_400_DCDC 6000 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_DCDC 6700 + +#define SX128X_LORA_RX_CONSUMPTION_BW_800_DCDC 7000 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_DCDC 7700 + +#define SX128X_LORA_RX_CONSUMPTION_BW_1600_DCDC 7500 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_DCDC 8200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_200_LDO 10800 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_LDO 12200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_400_LDO 11800 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_LDO 13200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_800_LDO 13700 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_LDO 15200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_1600_LDO 14800 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_LDO 16300 /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ +static const uint32_t ral_sx128x_convert_tx_dbm_to_ua_reg_mode_dcdc[] = { + 6200, // -18 dBm + 6300, // -17 dBm + 6400, // -16 dBm + 6500, // -15 dBm + 6600, // -14 dBm + 6700, // -13 dBm + 6800, // -12 dBm + 7000, // -11 dBm + 7100, // -10 dBm + 7300, // -9 dBm + 7400, // -8 dBm + 7700, // -7 dBm + 7900, // -6 dBm + 8100, // -5 dBm + 8500, // -4 dBm + 8800, // -3 dBm + 9200, // -2 dBm + 9700, // -1 dBm + 10100, // 0 dBm + 10700, // 1 dBm + 11300, // 2 dBm + 12000, // 3 dBm + 12700, // 4 dBm + 13600, // 5 dBm + 14500, // 6 dBm + 15500, // 7 dBm + 16800, // 8 dBm + 17700, // 9 dBm + 18600, // 10 dBm + 20300, // 11 dBm + 22000, // 12 dBm + 24000, // 13 dBm +}; + +static const uint32_t ral_sx128x_convert_tx_dbm_to_ua_reg_mode_ldo[] = { + 11800, // -18 dBm + 12000, // -17 dBm + 12200, // -16 dBm + 12400, // -15 dBm + 12600, // -14 dBm + 12800, // -13 dBm + 13000, // -12 dBm + 13300, // -11 dBm + 13500, // -10 dBm + 14000, // -9 dBm + 14200, // -8 dBm + 14700, // -7 dBm + 15200, // -6 dBm + 15600, // -5 dBm + 16300, // -4 dBm + 17000, // -3 dBm + 17700, // -2 dBm + 18600, // -1 dBm + 19600, // 0 dBm + 20700, // 1 dBm + 21900, // 2 dBm + 23200, // 3 dBm + 24600, // 4 dBm + 26300, // 5 dBm + 28000, // 6 dBm + 30000, // 7 dBm + 32200, // 8 dBm + 34500, // 9 dBm + 36800, // 10 dBm + 39200, // 11 dBm + 41900, // 12 dBm + 45500, // 13 dBm +}; + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -104,8 +199,134 @@ void ral_sx128x_bsp_get_tx_cfg( const void* context, const ral_sx128x_bsp_tx_cfg output_params->pa_ramp_time = SX128X_RAMP_20_US; } -void ral_sx128x_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_sx128x_bsp_get_lora_cad_det_peak( const void *context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed -} \ No newline at end of file +} + +ral_status_t ral_sx128x_bsp_get_instantaneous_tx_power_consumption( const void *context, + ral_sx128x_bsp_tx_cfg_output_params_t tx_cfg_output_params_local, sx128x_reg_mod_t reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + const ral_sx128x_bsp_tx_cfg_output_params_t tx_cfg_output_params = tx_cfg_output_params_local; + uint8_t index = 0; + + if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected > SX128X_PWR_MAX ) + { + index = SX128X_PWR_MAX + SX128X_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected < SX128X_PWR_MIN ) + { + index = SX128X_PWR_MIN + SX128X_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg_output_params.chip_output_pwr_in_dbm_expected + SX128X_CONVERT_TABLE_INDEX_OFFSET; + } + + if( reg_mode == SX128X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_sx128x_convert_tx_dbm_to_ua_reg_mode_dcdc[index]; + } + else if( reg_mode == SX128X_REG_MODE_LDO ) + { + *pwr_consumption_in_ua = ral_sx128x_convert_tx_dbm_to_ua_reg_mode_ldo[index]; + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_sx128x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + sx128x_reg_mod_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + return RAL_STATUS_UNSUPPORTED_FEATURE; +} + +ral_status_t ral_sx128x_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + sx128x_reg_mod_t reg_mode, ral_lora_bw_t bw, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + switch( reg_mode ) + { + case SX128X_REG_MODE_DCDC: + { + switch( bw ) + { + case RAL_LORA_BW_200_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_DCDC + : SX128X_LORA_RX_CONSUMPTION_BW_200_DCDC; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_400_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_DCDC + : SX128X_LORA_RX_CONSUMPTION_BW_400_DCDC; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_800_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_DCDC + : SX128X_LORA_RX_CONSUMPTION_BW_800_DCDC; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_1600_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_DCDC + : SX128X_LORA_RX_CONSUMPTION_BW_1600_DCDC; + return RAL_STATUS_OK; + } + default: + return RAL_STATUS_UNKNOWN_VALUE; + } + break; + } + case SX128X_REG_MODE_LDO: + { + switch( bw ) + { + case RAL_LORA_BW_200_KHZ: + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_LDO : SX128X_LORA_RX_CONSUMPTION_BW_200_LDO; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_400_KHZ: + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_LDO : SX128X_LORA_RX_CONSUMPTION_BW_400_LDO; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_800_KHZ: + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_LDO : SX128X_LORA_RX_CONSUMPTION_BW_800_LDO; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_1600_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_LDO + : SX128X_LORA_RX_CONSUMPTION_BW_1600_LDO; + return RAL_STATUS_OK; + } + default: + { + return RAL_STATUS_UNKNOWN_VALUE; + } + } + break; + } + default: + { + return RAL_STATUS_UNKNOWN_VALUE; + } + } +} diff --git a/lbm_applications/2_porting_nrf_52840/smtc_hal_nrf52840/modem_pinout.h b/lbm_applications/2_porting_nrf_52840/smtc_hal_nrf52840/modem_pinout.h index afacd33..4030d22 100644 --- a/lbm_applications/2_porting_nrf_52840/smtc_hal_nrf52840/modem_pinout.h +++ b/lbm_applications/2_porting_nrf_52840/smtc_hal_nrf52840/modem_pinout.h @@ -57,7 +57,7 @@ extern "C" { /********************************************************************************/ /* Application dependant */ /********************************************************************************/ -// clang-format off +/* clang-format off */ //Debug uart specific pinout for debug print #define DEBUG_UART_TX P0_6 @@ -85,7 +85,7 @@ extern "C" { #define EXTI_BUTTON P0_25 // BP4 -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_applications/2_porting_nrf_52840/smtc_hal_nrf52840/smtc_hal_dbg_trace.h b/lbm_applications/2_porting_nrf_52840/smtc_hal_nrf52840/smtc_hal_dbg_trace.h index 26a9218..7d4cb88 100644 --- a/lbm_applications/2_porting_nrf_52840/smtc_hal_nrf52840/smtc_hal_dbg_trace.h +++ b/lbm_applications/2_porting_nrf_52840/smtc_hal_nrf52840/smtc_hal_dbg_trace.h @@ -52,7 +52,7 @@ extern "C" { * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define HAL_FEATURE_OFF 0 #define HAL_FEATURE_ON !HAL_FEATURE_OFF @@ -68,14 +68,14 @@ extern "C" { #ifndef HAL_DBG_TRACE_RP #define HAL_DBG_TRACE_RP HAL_FEATURE_OFF #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #if ( HAL_DBG_TRACE_COLOR == HAL_FEATURE_ON ) #define HAL_DBG_TRACE_COLOR_BLACK "\x1B[0;30m" #define HAL_DBG_TRACE_COLOR_RED "\x1B[0;31m" @@ -171,7 +171,7 @@ extern "C" { #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_applications/2_porting_nrf_52840/smtc_modem_hal/smtc_modem_hal.c b/lbm_applications/2_porting_nrf_52840/smtc_modem_hal/smtc_modem_hal.c index a3c4204..d3dfb12 100644 --- a/lbm_applications/2_porting_nrf_52840/smtc_modem_hal/smtc_modem_hal.c +++ b/lbm_applications/2_porting_nrf_52840/smtc_modem_hal/smtc_modem_hal.c @@ -142,7 +142,7 @@ uint32_t smtc_modem_hal_get_time_in_ms( void ) void smtc_modem_hal_start_timer( const uint32_t milliseconds, void ( *callback )( void* context ), void* context ) { - hal_lp_timer_start( milliseconds, &( hal_lp_timer_irq_t ){ .context = context, .callback = callback } ); + hal_lp_timer_start( milliseconds, &( hal_lp_timer_irq_t ) { .context = context, .callback = callback } ); } void smtc_modem_hal_stop_timer( void ) @@ -278,9 +278,11 @@ void smtc_modem_hal_crashlog_set_status( bool available ) crashlog_available_noinit = available; } -bool smtc_modem_hal_crashlog_get_status( void ) +volatile bool temp = 0x1; // solve new behaviour introduce with gcc11 compilo +bool smtc_modem_hal_crashlog_get_status( void ) { - return crashlog_available_noinit; + bool temp2 = crashlog_available_noinit & temp; + return temp2; } /* ------------ assert management ------------*/ @@ -319,11 +321,6 @@ void smtc_modem_hal_irq_config_radio_irq( void ( *callback )( void* context ), v hal_gpio_irq_attach( &radio_dio_irq ); } -void smtc_modem_hal_radio_irq_clear_pending( void ) -{ - hal_gpio_clear_pending_irq( RADIO_DIOX ); -} - void smtc_modem_hal_start_radio_tcxo( void ) { // put here the code that will start the tcxo if needed diff --git a/lbm_applications/3_geolocation_on_lora_edge/main_geolocation/example_options.h b/lbm_applications/3_geolocation_on_lora_edge/main_geolocation/example_options.h index f387b6a..1b03dec 100644 --- a/lbm_applications/3_geolocation_on_lora_edge/main_geolocation/example_options.h +++ b/lbm_applications/3_geolocation_on_lora_edge/main_geolocation/example_options.h @@ -75,8 +75,6 @@ extern "C" { */ #define MODEM_EXAMPLE_REGION SMTC_MODEM_REGION_EU_868 -// clang-format on - #ifdef __cplusplus } #endif diff --git a/lbm_applications/3_geolocation_on_lora_edge/radio_hal/radio_utilities.c b/lbm_applications/3_geolocation_on_lora_edge/radio_hal/radio_utilities.c index fb961d0..78bf549 100644 --- a/lbm_applications/3_geolocation_on_lora_edge/radio_hal/radio_utilities.c +++ b/lbm_applications/3_geolocation_on_lora_edge/radio_hal/radio_utilities.c @@ -3,11 +3,12 @@ * * @brief User radio utilities implementations * - * Revised BSD License - * Copyright Semtech Corporation 2022. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* diff --git a/lbm_applications/3_geolocation_on_lora_edge/radio_hal/radio_utilities.h b/lbm_applications/3_geolocation_on_lora_edge/radio_hal/radio_utilities.h index 57a38e9..f787cf4 100644 --- a/lbm_applications/3_geolocation_on_lora_edge/radio_hal/radio_utilities.h +++ b/lbm_applications/3_geolocation_on_lora_edge/radio_hal/radio_utilities.h @@ -3,11 +3,12 @@ * * @brief User radio utilities definitions * - * Revised BSD License - * Copyright Semtech Corporation 2022. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef RADIO_UTILITIES_H diff --git a/lbm_applications/3_geolocation_on_lora_edge/radio_hal/ral_lr11xx_bsp.c b/lbm_applications/3_geolocation_on_lora_edge/radio_hal/ral_lr11xx_bsp.c index 4e6f7b2..7a366f8 100644 --- a/lbm_applications/3_geolocation_on_lora_edge/radio_hal/ral_lr11xx_bsp.c +++ b/lbm_applications/3_geolocation_on_lora_edge/radio_hal/ral_lr11xx_bsp.c @@ -52,6 +52,34 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +// TODO: check values +#define LR11XX_GFSK_RX_CONSUMPTION_DCDC 5400 +#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 7500 + +#define LR11XX_GFSK_RX_CONSUMPTION_LDO 5400 +#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO 7500 + +#define LR11XX_LORA_RX_CONSUMPTION_DCDC 5700 +#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC 7800 + +#define LR11XX_LORA_RX_CONSUMPTION_LDO 5700 +#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO 7800 + +#define LR11XX_LP_MIN_OUTPUT_POWER -17 +#define LR11XX_LP_MAX_OUTPUT_POWER 15 + +#define LR11XX_HP_MIN_OUTPUT_POWER -9 +#define LR11XX_HP_MAX_OUTPUT_POWER 22 + +#define LR11XX_HF_MIN_OUTPUT_POWER -18 +#define LR11XX_HF_MAX_OUTPUT_POWER 13 + +#define LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET 17 +#define LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET 9 +#define LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET 18 + +#define LR11XX_PWR_VREG_VBAT_SWITCH 8 + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -77,21 +105,187 @@ typedef struct lr11xx_pa_pwr_cfg_s * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define LR11XX_PWR_VREG_VBAT_SWITCH 8 - -#define LR11XX_MIN_PWR_LP_LF -17 -#define LR11XX_MAX_PWR_LP_LF 15 - -#define LR11XX_MIN_PWR_HP_LF -9 -#define LR11XX_MAX_PWR_HP_LF 22 - -#define LR11XX_MIN_PWR_PA_HF -18 -#define LR11XX_MAX_PWR_PA_HF 13 - -const lr11xx_pa_pwr_cfg_t pa_lp_cfg_table[LR11XX_MAX_PWR_LP_LF - LR11XX_MIN_PWR_LP_LF + 1] = LR11XX_PA_LP_LF_CFG_TABLE; -const lr11xx_pa_pwr_cfg_t pa_hp_cfg_table[LR11XX_MAX_PWR_HP_LF - LR11XX_MIN_PWR_HP_LF + 1] = LR11XX_PA_HP_LF_CFG_TABLE; - -const lr11xx_pa_pwr_cfg_t pa_hf_cfg_table[LR11XX_MAX_PWR_PA_HF - LR11XX_MIN_PWR_PA_HF + 1] = LR11XX_PA_HF_CFG_TABLE; +const lr11xx_pa_pwr_cfg_t pa_lp_cfg_table[LR11XX_LP_MAX_OUTPUT_POWER - LR11XX_LP_MIN_OUTPUT_POWER + 1] = LR11XX_PA_LP_LF_CFG_TABLE; +const lr11xx_pa_pwr_cfg_t pa_hp_cfg_table[LR11XX_HP_MAX_OUTPUT_POWER - LR11XX_HP_MIN_OUTPUT_POWER + 1] = LR11XX_PA_HP_LF_CFG_TABLE; + +const lr11xx_pa_pwr_cfg_t pa_hf_cfg_table[LR11XX_HF_MAX_OUTPUT_POWER - LR11XX_HF_MIN_OUTPUT_POWER + 1] = LR11XX_PA_HF_CFG_TABLE; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[] = { + 10820, // -17 dBm + 10980, // -16 dBm + 11060, // -15 dBm + 11160, // -14 dBm + 11300, // -13 dBm + 11430, // -12 dBm + 11550, // -11 dBm + 11680, // -10 dBm + 11930, // -9 dBm + 12170, // -8 dBm + 12420, // -7 dBm + 12650, // -6 dBm + 12900, // -5 dBm + 13280, // -4 dBm + 13600, // -3 dBm + 14120, // -2 dBm + 14600, // -1 dBm + 15090, // 0 dBm + 15780, // 1 dBm + 16490, // 2 dBm + 17250, // 3 dBm + 17850, // 4 dBm + 18720, // 5 dBm + 19640, // 6 dBm + 20560, // 7 dBm + 21400, // 8 dBm + 22620, // 9 dBm + 23720, // 10 dBm + 25050, // 11 dBm + 26350, // 12 dBm + 27870, // 13 dBm + 28590, // 14 dBm + 37820, // 15 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[] = { + 14950, // -17 dBm + 15280, // -16 dBm + 15530, // -15 dBm + 15770, // -14 dBm + 16020, // -13 dBm + 16290, // -12 dBm + 16550, // -11 dBm + 16760, // -10 dBm + 17280, // -9 dBm + 17770, // -8 dBm + 18250, // -7 dBm + 18750, // -6 dBm + 19250, // -5 dBm + 19960, // -4 dBm + 20710, // -3 dBm + 21620, // -2 dBm + 22570, // -1 dBm + 23570, // 0 dBm + 24990, // 1 dBm + 26320, // 2 dBm + 27830, // 3 dBm + 29070, // 4 dBm + 30660, // 5 dBm + 32490, // 6 dBm + 34220, // 7 dBm + 35820, // 8 dBm + 38180, // 9 dBm + 40220, // 10 dBm + 42800, // 11 dBm + 45030, // 12 dBm + 47900, // 13 dBm + 51220, // 14 dBm + 66060, // 15 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[] = { + 27750, // -9 dBm + 29100, // -8 dBm + 30320, // -7 dBm + 31650, // -6 dBm + 34250, // -5 dBm + 35550, // -4 dBm + 36770, // -3 dBm + 39250, // -2 dBm + 41480, // -1 dBm + 43820, // 0 dBm + 46000, // 1 dBm + 49020, // 2 dBm + 50900, // 3 dBm + 54200, // 4 dBm + 56330, // 5 dBm + 59050, // 6 dBm + 62210, // 7 dBm + 65270, // 8 dBm + 68600, // 9 dBm + 71920, // 10 dBm + 75500, // 11 dBm + 79500, // 12 dBm + 84130, // 13 dBm + 88470, // 14 dBm + 92200, // 15 dBm + 94340, // 16 dBm + 96360, // 17 dBm + 98970, // 18 dBm + 102220, // 19 dBm + 106250, // 20 dBm + 111300, // 21 dBm + 113040, // 22 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[] = { + 31310, // -9 dBm + 32700, // -8 dBm + 33970, // -7 dBm + 35270, // -6 dBm + 37900, // -5 dBm + 39140, // -4 dBm + 40380, // -3 dBm + 42860, // -2 dBm + 45150, // -1 dBm + 47400, // 0 dBm + 49600, // 1 dBm + 52600, // 2 dBm + 54460, // 3 dBm + 57690, // 4 dBm + 59840, // 5 dBm + 62550, // 6 dBm + 65750, // 7 dBm + 68520, // 8 dBm + 72130, // 9 dBm + 75230, // 10 dBm + 78600, // 11 dBm + 82770, // 12 dBm + 87450, // 13 dBm + 91700, // 14 dBm + 95330, // 15 dBm + 97520, // 16 dBm + 99520, // 17 dBm + 102080, // 18 dBm + 105140, // 19 dBm + 109300, // 20 dBm + 114460, // 21 dBm + 116530, // 22 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[] = { + 11800, // -18 dBm + 11800, // -17 dBm + 11800, // -16 dBm + 11900, // -15 dBm + 12020, // -14 dBm + 12120, // -13 dBm + 12230, // -12 dBm + 12390, // -11 dBm + 12540, // -10 dBm + 12740, // -9 dBm + 12960, // -8 dBm + 13150, // -7 dBm + 13460, // -6 dBm + 13770, // -5 dBm + 14070, // -4 dBm + 14460, // -3 dBm + 15030, // -2 dBm + 15440, // -1 dBm + 16030, // 0 dBm + 16980, // 1 dBm + 17590, // 2 dBm + 18270, // 3 dBm + 19060, // 4 dBm + 19900, // 5 dBm + 20740, // 6 dBm + 21610, // 7 dBm + 22400, // 8 dBm + 23370, // 9 dBm + 24860, // 10 dBm + 26410, // 11 dBm + 26430, // 12 dBm + 27890, // 13 dBm +}; /* * ----------------------------------------------------------------------------- @@ -250,8 +444,8 @@ void ral_lr11xx_bsp_get_rssi_calibration_table( const void* context, const uint3 } } -void ral_lr11xx_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_lr11xx_bsp_get_lora_cad_det_peak( const void *context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed } @@ -284,32 +478,32 @@ void lr11xx_get_tx_cfg( lr11xx_pa_type_t pa_type, int8_t expected_output_pwr_in_ case LR11XX_WITH_LF_LP_PA: { // Check power boundaries for LP LF PA: The output power must be in range [ -17 , +15 ] dBm - if( power < LR11XX_MIN_PWR_LP_LF ) + if( power < LR11XX_LP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_LP_LF; + power = LR11XX_LP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_LP_LF ) + else if( power > LR11XX_LP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_LP_LF; + power = LR11XX_LP_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_LP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].power; output_params->chip_output_pwr_in_dbm_expected = power; break; } case LR11XX_WITH_LF_HP_PA: { // Check power boundaries for HP LF PA: The output power must be in range [ -9 , +22 ] dBm - if( power < LR11XX_MIN_PWR_HP_LF ) + if( power < LR11XX_HP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_HP_LF; + power = LR11XX_HP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_HP_LF ) + else if( power > LR11XX_HP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_HP_LF; + power = LR11XX_HP_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HP; output_params->chip_output_pwr_in_dbm_expected = power; @@ -324,62 +518,214 @@ void lr11xx_get_tx_cfg( lr11xx_pa_type_t pa_type, int8_t expected_output_pwr_in_ output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT; } - output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].power; break; } case LR11XX_WITH_LF_LP_HP_PA: { // Check power boundaries for LP/HP LF PA: The output power must be in range [ -17 , +22 ] dBm - if( power < LR11XX_MIN_PWR_LP_LF ) + if( power < LR11XX_LP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_LP_LF; + power = LR11XX_LP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_HP_LF ) + else if( power > LR11XX_HP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_HP_LF; + power = LR11XX_HP_MAX_OUTPUT_POWER; } output_params->chip_output_pwr_in_dbm_expected = power; - if( power <= LR11XX_MAX_PWR_LP_LF ) + if( power <= LR11XX_LP_MAX_OUTPUT_POWER ) { output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_LP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].power; } else { output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT; - output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].power; } break; } case LR11XX_WITH_HF_PA: { // Check power boundaries for HF PA: The output power must be in range [ -18 , +13 ] dBm - if( power < LR11XX_MIN_PWR_PA_HF ) + if( power < LR11XX_HF_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_PA_HF; + power = LR11XX_HF_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_PA_HF ) + else if( power > LR11XX_HF_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_PA_HF; + power = LR11XX_HF_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HF; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].power; output_params->chip_output_pwr_in_dbm_expected = power; break; } } } +ral_status_t ral_lr11xx_bsp_get_instantaneous_tx_power_consumption( const void *context, + const ral_lr11xx_bsp_tx_cfg_output_params_t* tx_cfg, + lr11xx_system_reg_mode_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_LP ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_LP_MAX_OUTPUT_POWER ) + { + index = LR11XX_LP_MAX_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_LP_MIN_OUTPUT_POWER ) + { + index = LR11XX_LP_MIN_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[index]; + } + else + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[index]; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HP ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VBAT ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_HP_MAX_OUTPUT_POWER ) + { + index = LR11XX_HP_MAX_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_HP_MIN_OUTPUT_POWER ) + { + index = LR11XX_HP_MIN_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[index]; + } + else + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[index]; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HF ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_HF_MAX_OUTPUT_POWER ) + { + index = LR11XX_HF_MAX_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_HF_MIN_OUTPUT_POWER ) + { + index = LR11XX_HF_MIN_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[index]; + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_lr11xx_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + lr11xx_system_reg_mode_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_GFSK_RX_CONSUMPTION_DCDC; + } + else + { + // TODO: find the good values + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_GFSK_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_lr11xx_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + lr11xx_system_reg_mode_t radio_reg_mode, + const bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_LORA_RX_CONSUMPTION_DCDC; + } + else + { + // TODO: find the good values + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_LORA_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/modem_pinout.h b/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/modem_pinout.h index 7dfdcbb..6c1de17 100644 --- a/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/modem_pinout.h +++ b/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/modem_pinout.h @@ -58,7 +58,7 @@ extern "C" { /********************************************************************************/ /* Application dependant */ /********************************************************************************/ -// clang-format off +/* clang-format off */ //Debug uart specific pinout for debug print #define DEBUG_UART_TX PA_2 @@ -93,7 +93,7 @@ extern "C" { #define EXTI_BUTTON PC_13 -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/smtc_hal_dbg_trace.h b/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/smtc_hal_dbg_trace.h index f2b42ed..ca027d8 100644 --- a/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/smtc_hal_dbg_trace.h +++ b/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/smtc_hal_dbg_trace.h @@ -51,7 +51,7 @@ extern "C" { * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define HAL_FEATURE_OFF 0 #define HAL_FEATURE_ON !HAL_FEATURE_OFF @@ -67,14 +67,14 @@ extern "C" { #ifndef HAL_DBG_TRACE_RP #define HAL_DBG_TRACE_RP HAL_FEATURE_OFF #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #if ( HAL_DBG_TRACE_COLOR == HAL_FEATURE_ON ) #define HAL_DBG_TRACE_COLOR_BLACK "\x1B[0;30m" #define HAL_DBG_TRACE_COLOR_RED "\x1B[0;31m" @@ -170,7 +170,7 @@ extern "C" { #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/smtc_hal_rtc.c b/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/smtc_hal_rtc.c index bd68134..df6f723 100644 --- a/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/smtc_hal_rtc.c +++ b/lbm_applications/3_geolocation_on_lora_edge/smtc_hal_l4/smtc_hal_rtc.c @@ -52,14 +52,14 @@ /*! * Calculates ceiling( X / N ) */ -#define DIVC( X, N ) ( ( ( X ) + ( N ) -1 ) / ( N ) ) +#define DIVC( X, N ) ( ( ( X ) + ( N ) - 1 ) / ( N ) ) /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -// clang-format off +/* clang-format off */ // MCU Wake Up Time #define MIN_ALARM_DELAY_IN_TICKS 3U // in ticks @@ -101,7 +101,7 @@ #define DAYS_IN_MONTH_CORRECTION_NORM ( ( uint32_t ) 0x99AAA0 ) #define DAYS_IN_MONTH_CORRECTION_LEAP ( ( uint32_t ) 0x445550 ) -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_applications/3_geolocation_on_lora_edge/smtc_modem_hal/smtc_modem_hal.c b/lbm_applications/3_geolocation_on_lora_edge/smtc_modem_hal/smtc_modem_hal.c index 55619be..f698c56 100644 --- a/lbm_applications/3_geolocation_on_lora_edge/smtc_modem_hal/smtc_modem_hal.c +++ b/lbm_applications/3_geolocation_on_lora_edge/smtc_modem_hal/smtc_modem_hal.c @@ -140,7 +140,7 @@ uint32_t smtc_modem_hal_get_time_in_ms( void ) void smtc_modem_hal_start_timer( const uint32_t milliseconds, void ( *callback )( void* context ), void* context ) { hal_lp_timer_start( HAL_LP_TIMER_ID_1, milliseconds, - &( hal_lp_timer_irq_t ){ .context = context, .callback = callback } ); + &( hal_lp_timer_irq_t ) { .context = context, .callback = callback } ); } void smtc_modem_hal_stop_timer( void ) @@ -270,9 +270,11 @@ void smtc_modem_hal_crashlog_set_status( bool available ) crashlog_available_noinit = available; } -bool smtc_modem_hal_crashlog_get_status( void ) +volatile static bool temp = 0x1; // solve new behaviour introduce with gcc11 compilo +bool smtc_modem_hal_crashlog_get_status( void ) { - return crashlog_available_noinit; + bool temp2 = crashlog_available_noinit & temp; + return temp2; } /* ------------ assert management ------------*/ @@ -311,11 +313,6 @@ void smtc_modem_hal_irq_config_radio_irq( void ( *callback )( void* context ), v hal_gpio_irq_attach( &radio_dio_irq ); } -void smtc_modem_hal_radio_irq_clear_pending( void ) -{ - hal_gpio_clear_pending_irq( RADIO_DIOX ); -} - void smtc_modem_hal_start_radio_tcxo( void ) { // put here the code that will start the tcxo if needed diff --git a/lbm_examples/Makefile b/lbm_examples/Makefile index 07caa86..58a8202 100644 --- a/lbm_examples/Makefile +++ b/lbm_examples/Makefile @@ -48,6 +48,8 @@ help: $(call echo_help, " * - LR11XX_WITH_CREDENTIALS (only for lr1110 and lr1120 targets)") $(call echo_help, " * LBM_TRACE=yes/no : choose to enable or disable modem trace print (default: trace is ON)") $(call echo_help, " * APP_TRACE=yes/no : choose to enable or disable application trace print (default: trace is ON)") + $(call echo_help, " * ALLOW_RELAY_TX=yes/no : choose to enable or disable RelayTx (default: no)") + $(call echo_help, " * ALLOW_RELAY_RX=yes/no : choose to enable or disable RelayRx (default: no)") $(call echo_help_b, "-------------------- Optional makefile parameters --------------------------") $(call echo_help, " * MULTITHREAD=no : Disable multithreaded build") $(call echo_help, " * VERBOSE=yes : Increase build verbosity") diff --git a/lbm_examples/README.md b/lbm_examples/README.md index 7741c7f..b42da36 100644 --- a/lbm_examples/README.md +++ b/lbm_examples/README.md @@ -72,15 +72,17 @@ Build command example for lr1110 radio make lr1110 MODEM_APP=LCTT_CERTIF ``` -### Relay TX +### Relay -This example provides an application where the relay TX feature is enabled. +#### Relay Tx -This exemple reuse the Periodical Uplink main exemple. +This example provides an application where the Relay Tx feature is enabled. -The end-device is configured in **DYNAMIC** mode (refer to TS011-1.0.0 table 40). After the reset, the end-device will enable the relay tx feature and add a WOR frame before every LoRaWAN uplink. The relay feature will be automatically disable if the end-device receive a downlink on RX1 or RX2. +This example uses the Periodical Uplink main example. -In this exemple, the CSMA is compiled and enabled by default. +The end-device is configured in **ENABLE** mode (refer to TS011-1.0.1 table 40). After the reset, the end-device will enable the Relay Tx feature and add a WOR frame before every LoRaWAN uplink. The relay feature will be automatically disable if the end-device receive a downlink on Rx1 or Rx2. + +In this example, the CSMA is compiled and enabled by default. LoRaWAN credentials shall be provided in [example_options.h](main_examples/example_options.h) @@ -88,7 +90,38 @@ Build command example for lr1110 radio ```bash -make full_lr1110 MODEM_APP=RELAY_TX ALLOW_RELAY_TX=yes +make full_lr1110 MODEM_APP=PERIODICAL_UPLINK ALLOW_RELAY_TX=yes +``` + +Or to be tested with the LCTT + +```bash + +make full_lr1110 MODEM_APP=LCTT_CERTIF ALLOW_RELAY_TX=yes +``` + +#### Relay Rx + +This example provides an application where the relay Rx feature is enabled. + +This example uses the Periodical Uplink main example. + +In this example, the CSMA is compiled and enabled by default. + +LoRaWAN credentials shall be provided in [example_options.h](main_examples/example_options.h) + +Build command example for lr1110 radio + +```bash + +make full_lr1110 MODEM_APP=PERIODICAL_UPLINK ALLOW_RELAY_RX=yes +``` + +Or to be tested with the LCTT + +```bash + +make full_lr1110 MODEM_APP=LCTT_CERTIF ALLOW_RELAY_RX=yes ``` ### MCU Porting @@ -111,5 +144,3 @@ Any smtc_modem_hal function will be mapped with corresponding mcu porting functi ## Fuota support Once the Fuota services are enabled (refer to the main readme for instructions on how to activate Fuota), the periodical example is sufficient to launch a Fuota campaign. However, you will need to enable the flag `ALLOW_FUOTA` to "yes" in the `app_options.mk` file. - - diff --git a/lbm_examples/app_makefiles/app_common.mk b/lbm_examples/app_makefiles/app_common.mk index 0b030eb..ced4b7d 100644 --- a/lbm_examples/app_makefiles/app_common.mk +++ b/lbm_examples/app_makefiles/app_common.mk @@ -215,14 +215,15 @@ COMMON_C_DEFS += \ LBM_BUILD_OPTIONS += LBM_FUOTA=yes LBM_FUOTA_VERSION=$(FUOTA_VERSION) endif - ifeq ($(ALLOW_RELAY_TX),yes) -LBM_BUILD_OPTIONS += RELAY_TX_ENABLE=yes -BUILD_TARGET := $(BUILD_TARGET) -COMMON_C_DEFS += \ - -DUSE_RELAY_TX\ - -DADD_CSMA\ - -DENABLE_CSMA_BY_DEFAULT +LBM_BUILD_OPTIONS += LBM_RELAY_TX_ENABLE=yes LBM_CSMA=yes USE_CSMA_BY_DEFAULT=yes +COMMON_C_DEFS += -DUSE_RELAY_TX +BUILD_TARGET := $(BUILD_TARGET)_relay_tx +endif + +ifeq ($(ALLOW_RELAY_RX),yes) +LBM_BUILD_OPTIONS += LBM_RELAY_RX_ENABLE=yes +BUILD_TARGET := $(BUILD_TARGET)_relay_rx endif ifeq ($(ALLOW_STORE_AND_FORWARD),yes) @@ -283,13 +284,6 @@ APP_C_SOURCES += \ main_examples/main_periodical_uplink.c endif -ifeq ($(MODEM_APP),RELAY_TX) -APP_C_SOURCES += \ - main_examples/main_periodical_uplink.c - -LBM_BUILD_OPTIONS += RELAY_TX_ENABLE=yes -endif - ifeq ($(MODEM_APP),PORTING_TESTS) APP_C_SOURCES += \ main_examples/main_porting_tests.c @@ -316,7 +310,7 @@ COMMON_C_INCLUDES += \ -Ihw_modem endif -# For this specific example, a radio access is needed to mimic modem behavior, exceptionnaly include internal folder of lbm +# For this specific example, a radio access is needed to mimic modem behavior, exceptionally include internal folder of lbm ifeq ($(MODEM_APP),PORTING_TESTS) MODEM_C_INCLUDES += \ -I$(LORA_BASICS_MODEM)/smtc_modem_core/smtc_ralf/src diff --git a/lbm_examples/app_makefiles/app_options.mk b/lbm_examples/app_makefiles/app_options.mk index 0cf05e1..fc79157 100644 --- a/lbm_examples/app_makefiles/app_options.mk +++ b/lbm_examples/app_makefiles/app_options.mk @@ -29,7 +29,7 @@ MODEM_APP_REGION ?= nc ALLOW_FUOTA ?= no FUOTA_VERSION ?= 1 -# USE LBM Store and forward (take more RAM on STML4, due to read_modify_write feature) +# USE LBM Store and forward (take more RAM on STM32L4, due to read_modify_write feature) ALLOW_STORE_AND_FORWARD ?= no #TRACE @@ -55,7 +55,7 @@ CRYPTO ?= SOFT LBM_NB_OF_STACK ?= 1 # Add any lbm build options (ex: LBM_BUILD_OPTIONS ?= LBM_CLASS_B=yes REGION=ALL) -LBM_BUILD_OPTIONS ?= +LBM_BUILD_OPTIONS ?= LBM_CSMA=yes USE_CSMA_BY_DEFAULT=yes #----------------------------------------------------------------------------- # Optimization diff --git a/lbm_examples/hw_modem/cmd_parser.c b/lbm_examples/hw_modem/cmd_parser.c index adf2a0d..df10609 100644 --- a/lbm_examples/hw_modem/cmd_parser.c +++ b/lbm_examples/hw_modem/cmd_parser.c @@ -138,108 +138,108 @@ static cmd_serial_rc_code_t gnss_scan_done_rc = CMD_RC_FAIL; * */ static const uint8_t host_cmd_tab[CMD_MAX][HOST_CMD_TAB_IDX_COUNT] = { -// [CMD_xxx] = {availability, len_min, len_max} - [CMD_RESET] = { 1, 0, 0 }, - [CMD_SET_REGION] = { 1, 1, 1 }, - [CMD_GET_REGION] = { 1, 0, 0 }, - [CMD_JOIN_NETWORK] = { 1, 0, 0 }, - [CMD_REQUEST_UPLINK] = { 1, 2, 244 }, - [CMD_GET_EVENT] = { 1, 0, 0 }, - [CMD_GET_DOWNLINK_DATA] = { 1, 0, 0 }, - [CMD_GET_DOWNLINK_METADATA] = { 1, 0, 0 }, - [CMD_GET_JOIN_EUI] = { 1, 0, 0 }, - [CMD_SET_JOIN_EUI] = { 1, 8, 8 }, - [CMD_GET_DEV_EUI] = { 1, 0, 0 }, - [CMD_SET_DEV_EUI] = { 1, 8, 8 }, - [CMD_SET_NWKKEY] = { 1, 16, 16 }, - [CMD_GET_PIN] = { 1, 0, 0 }, - [CMD_GET_CHIP_EUI] = { 1, 0, 0 }, - [CMD_DERIVE_KEYS] = { 1, 0, 0 }, - [CMD_GET_MODEM_VERSION] = { 1, 0, 0 }, - [CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER] = { 1, 0, 0 }, - [CMD_SET_CERTIFICATION_MODE] = { 1, 1, 1 }, - [CMD_EMERGENCY_UPLINK] = { 1, 2, 244 }, - [CMD_REQUEST_EMPTY_UPLINK] = { 1, 3, 3 }, - [CMD_LEAVE_NETWORK] = { 1, 0, 0 }, - [CMD_ALARM_START_TIMER] = { 1, 4, 4 }, - [CMD_ALARM_CLEAR_TIMER] = { 1, 0, 0 }, - [CMD_ALARM_GET_REMAINING_TIME] = { 1, 0, 0 }, - [CMD_GET_NEXT_TX_MAX_PAYLOAD] = { 1, 0, 0 }, - [CMD_GET_DUTY_CYCLE_STATUS] = { 1, 0, 0 }, - [CMD_SET_NETWORK_TYPE] = { 1, 1, 1 }, - [CMD_SET_JOIN_DR_DISTRIBUTION] = { 1, 16, 16 }, - [CMD_SET_ADR_PROFILE] = { 1, 1, 17 }, - [CMD_SET_NB_TRANS] = { 1, 1, 1 }, - [CMD_GET_NB_TRANS] = { 1, 0, 0 }, - [CMD_GET_ENABLED_DATARATE] = { 1, 0, 0 }, - [CMD_SET_ADR_ACK_LIMIT_DELAY] = { 1, 2, 2}, - [CMD_GET_ADR_ACK_LIMIT_DELAY] = { 1, 0, 0}, - [CMD_SET_CRYSTAL_ERR] = { 1, 4, 4 }, - [CMD_LBT_SET_PARAMS] = { 1, 10, 10 }, - [CMD_LBT_GET_PARAMS] = { 1, 0, 0 }, - [CMD_LBT_SET_STATE] = { 1, 1, 1 }, - [CMD_LBT_GET_STATE] = { 1, 0, 0 }, - [CMD_GET_CHARGE] = { 1, 0, 0 }, - [CMD_RESET_CHARGE] = { 1, 0, 0 }, - [CMD_SET_CLASS] = { 1, 1, 1 }, - [CMD_CLASS_B_SET_PING_SLOT_PERIODICITY] = { 1, 1, 1, }, - [CMD_CLASS_B_GET_PING_SLOT_PERIODICITY] = { 1, 0, 0, }, - [CMD_MULTICAST_SET_GROUP_CONFIG] = { 1, 37, 37 }, - [CMD_MULTICAST_GET_GROUP_CONFIG] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_C_START_SESSION] = { 1, 6, 6 }, - [CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_C_STOP_SESSION] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS] = { 1, 0, 0 }, - [CMD_MULTICAST_CLASS_B_START_SESSION] = { 1, 7, 7 }, - [CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_B_STOP_SESSION] = { 1, 1, 1 }, - [CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS] = { 1, 0, 0 }, - [CMD_START_ALCSYNC_SERVICE] = { 1, 0, 0 }, - [CMD_STOP_ALCSYNC_SERVICE] = { 1, 0, 0 }, - [CMD_GET_ALCSYNC_TIME] = { 1, 0, 0 }, - [CMD_TRIG_ALCSYNC_REQUEST] = { 1, 0, 0 }, - [CMD_LORAWAN_MAC_REQUEST] = { 1, 1, 1 }, - [CMD_GET_LORAWAN_TIME] = { 1, 0, 0}, - [CMD_GET_LINK_CHECK_DATA] = { 1, 0, 0 }, - [CMD_SET_DUTY_CYCLE_STATE] = { 1, 1, 1 }, - [CMD_DEBUG_CONNECT_WITH_ABP] = { 1, 36, 36 }, - [CMD_TEST] = { 1, 1, 255 }, - [CMD_GET_TX_POWER_OFFSET] = { 1, 0, 0 }, - [CMD_SET_TX_POWER_OFFSET] = { 1, 1, 1 }, - [CMD_CSMA_SET_STATE] = { 1, 1, 1 }, - [CMD_CSMA_GET_STATE] = { 1, 0, 0 }, - [CMD_CSMA_SET_PARAMETERS] = { 1, 3, 3 }, - [CMD_CSMA_GET_PARAMETERS] = { 1, 0, 0 }, - [CMD_STREAM_INIT] = { 1, 3, 3 }, - [CMD_STREAM_ADD_DATA] = { 1, 1, 255 }, - [CMD_STREAM_STATUS] = { 1, 0, 0 }, - [CMD_LFU_INIT] = { 1, 6, 6 }, - [CMD_LFU_DATA] = { 1, 0, 255 }, - [CMD_LFU_START] = { 1, 4, 4 }, - [CMD_LFU_RESET] = { 1, 0, 0 }, - [CMD_DM_ENABLE] = { 1, 1, 1 }, - [CMD_DM_GET_PORT] = { 1, 0, 0 }, - [CMD_DM_SET_PORT] = { 1, 1, 1 }, - [CMD_DM_GET_INFO_INTERVAL] = { 1, 0, 0 }, - [CMD_DM_SET_INFO_INTERVAL] = { 1, 1, 1 }, - [CMD_DM_GET_PERIODIC_INFO_FIELDS] = { 1, 0, 0 }, - [CMD_DM_SET_PERIODIC_INFO_FIELDS] = { 1, 0, MODEM_MAX_INFO_FIELD_SIZE }, - [CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS] = { 1, 0, MODEM_MAX_INFO_FIELD_SIZE }, - [CMD_DM_SET_USER_DATA] = { 1, SMTC_MODEM_DM_USER_DATA_LENGTH, SMTC_MODEM_DM_USER_DATA_LENGTH }, - [CMD_DM_GET_USER_DATA] = { 1, 0, 0 }, - [CMD_GET_STATUS] = { 1, 0, 0 }, - [CMD_SUSPEND_RADIO_COMMUNICATIONS] = { 1, 1, 1 }, - [CMD_GET_SUSPEND_RADIO_COMMUNICATIONS] = { 1, 0, 0 }, - [CMD_DM_HANDLE_ALCSYNC] = { 1, 1, 1 }, - [CMD_SET_APPKEY] = { 1, 16, 16 }, - [CMD_GET_ADR_PROFILE] = { 1, 0, 0 }, - [CMD_GET_CERTIFICATION_MODE] = { 1, 0, 0 }, + // [CMD_xxx] = {availability, len_min, len_max} + [CMD_RESET] = { 1, 0, 0 }, + [CMD_SET_REGION] = { 1, 1, 1 }, + [CMD_GET_REGION] = { 1, 0, 0 }, + [CMD_JOIN_NETWORK] = { 1, 0, 0 }, + [CMD_REQUEST_UPLINK] = { 1, 2, 244 }, + [CMD_GET_EVENT] = { 1, 0, 0 }, + [CMD_GET_DOWNLINK_DATA] = { 1, 0, 0 }, + [CMD_GET_DOWNLINK_METADATA] = { 1, 0, 0 }, + [CMD_GET_JOIN_EUI] = { 1, 0, 0 }, + [CMD_SET_JOIN_EUI] = { 1, 8, 8 }, + [CMD_GET_DEV_EUI] = { 1, 0, 0 }, + [CMD_SET_DEV_EUI] = { 1, 8, 8 }, + [CMD_SET_NWKKEY] = { 1, 16, 16 }, + [CMD_GET_PIN] = { 1, 0, 0 }, + [CMD_GET_CHIP_EUI] = { 1, 0, 0 }, + [CMD_DERIVE_KEYS] = { 1, 0, 0 }, + [CMD_GET_MODEM_VERSION] = { 1, 0, 0 }, + [CMD_LORAWAN_GET_LOST_CONNECTION_COUNTER] = { 1, 0, 0 }, + [CMD_SET_CERTIFICATION_MODE] = { 1, 1, 1 }, + [CMD_EMERGENCY_UPLINK] = { 1, 2, 244 }, + [CMD_REQUEST_EMPTY_UPLINK] = { 1, 3, 3 }, + [CMD_LEAVE_NETWORK] = { 1, 0, 0 }, + [CMD_ALARM_START_TIMER] = { 1, 4, 4 }, + [CMD_ALARM_CLEAR_TIMER] = { 1, 0, 0 }, + [CMD_ALARM_GET_REMAINING_TIME] = { 1, 0, 0 }, + [CMD_GET_NEXT_TX_MAX_PAYLOAD] = { 1, 0, 0 }, + [CMD_GET_DUTY_CYCLE_STATUS] = { 1, 0, 0 }, + [CMD_SET_NETWORK_TYPE] = { 1, 1, 1 }, + [CMD_SET_JOIN_DR_DISTRIBUTION] = { 1, 16, 16 }, + [CMD_SET_ADR_PROFILE] = { 1, 1, 17 }, + [CMD_SET_NB_TRANS] = { 1, 1, 1 }, + [CMD_GET_NB_TRANS] = { 1, 0, 0 }, + [CMD_GET_ENABLED_DATARATE] = { 1, 0, 0 }, + [CMD_SET_ADR_ACK_LIMIT_DELAY] = { 1, 2, 2 }, + [CMD_GET_ADR_ACK_LIMIT_DELAY] = { 1, 0, 0 }, + [CMD_SET_CRYSTAL_ERR] = { 1, 4, 4 }, + [CMD_LBT_SET_PARAMS] = { 1, 10, 10 }, + [CMD_LBT_GET_PARAMS] = { 1, 0, 0 }, + [CMD_LBT_SET_STATE] = { 1, 1, 1 }, + [CMD_LBT_GET_STATE] = { 1, 0, 0 }, + [CMD_GET_CHARGE] = { 1, 0, 0 }, + [CMD_RESET_CHARGE] = { 1, 0, 0 }, + [CMD_SET_CLASS] = { 1, 1, 1 }, + [CMD_CLASS_B_SET_PING_SLOT_PERIODICITY] = { 1, 1, 1 }, + [CMD_CLASS_B_GET_PING_SLOT_PERIODICITY] = { 1, 0, 0 }, + [CMD_MULTICAST_SET_GROUP_CONFIG] = { 1, 37, 37 }, + [CMD_MULTICAST_GET_GROUP_CONFIG] = { 1, 1, 1 }, + [CMD_MULTICAST_CLASS_C_START_SESSION] = { 1, 6, 6 }, + [CMD_MULTICAST_CLASS_C_GET_SESSION_STATUS] = { 1, 1, 1 }, + [CMD_MULTICAST_CLASS_C_STOP_SESSION] = { 1, 1, 1 }, + [CMD_MULTICAST_CLASS_C_STOP_ALL_SESSIONS] = { 1, 0, 0 }, + [CMD_MULTICAST_CLASS_B_START_SESSION] = { 1, 7, 7 }, + [CMD_MULTICAST_CLASS_B_GET_SESSION_STATUS] = { 1, 1, 1 }, + [CMD_MULTICAST_CLASS_B_STOP_SESSION] = { 1, 1, 1 }, + [CMD_MULTICAST_CLASS_B_STOP_ALL_SESSIONS] = { 1, 0, 0 }, + [CMD_START_ALCSYNC_SERVICE] = { 1, 0, 0 }, + [CMD_STOP_ALCSYNC_SERVICE] = { 1, 0, 0 }, + [CMD_GET_ALCSYNC_TIME] = { 1, 0, 0 }, + [CMD_TRIG_ALCSYNC_REQUEST] = { 1, 0, 0 }, + [CMD_LORAWAN_MAC_REQUEST] = { 1, 1, 1 }, + [CMD_GET_LORAWAN_TIME] = { 1, 0, 0 }, + [CMD_GET_LINK_CHECK_DATA] = { 1, 0, 0 }, + [CMD_SET_DUTY_CYCLE_STATE] = { 1, 1, 1 }, + [CMD_DEBUG_CONNECT_WITH_ABP] = { 1, 36, 36 }, + [CMD_TEST] = { 1, 1, 255 }, + [CMD_GET_TX_POWER_OFFSET] = { 1, 0, 0 }, + [CMD_SET_TX_POWER_OFFSET] = { 1, 1, 1 }, + [CMD_CSMA_SET_STATE] = { 1, 1, 1 }, + [CMD_CSMA_GET_STATE] = { 1, 0, 0 }, + [CMD_CSMA_SET_PARAMETERS] = { 1, 3, 3 }, + [CMD_CSMA_GET_PARAMETERS] = { 1, 0, 0 }, + [CMD_STREAM_INIT] = { 1, 3, 3 }, + [CMD_STREAM_ADD_DATA] = { 1, 1, 255 }, + [CMD_STREAM_STATUS] = { 1, 0, 0 }, + [CMD_LFU_INIT] = { 1, 6, 6 }, + [CMD_LFU_DATA] = { 1, 0, 255 }, + [CMD_LFU_START] = { 1, 4, 4 }, + [CMD_LFU_RESET] = { 1, 0, 0 }, + [CMD_DM_ENABLE] = { 1, 1, 1 }, + [CMD_DM_GET_PORT] = { 1, 0, 0 }, + [CMD_DM_SET_PORT] = { 1, 1, 1 }, + [CMD_DM_GET_INFO_INTERVAL] = { 1, 0, 0 }, + [CMD_DM_SET_INFO_INTERVAL] = { 1, 1, 1 }, + [CMD_DM_GET_PERIODIC_INFO_FIELDS] = { 1, 0, 0 }, + [CMD_DM_SET_PERIODIC_INFO_FIELDS] = { 1, 0, MODEM_MAX_INFO_FIELD_SIZE }, + [CMD_DM_REQUEST_IMMEDIATE_INFO_FIELDS] = { 1, 0, MODEM_MAX_INFO_FIELD_SIZE }, + [CMD_DM_SET_USER_DATA] = { 1, SMTC_MODEM_DM_USER_DATA_LENGTH, SMTC_MODEM_DM_USER_DATA_LENGTH }, + [CMD_DM_GET_USER_DATA] = { 1, 0, 0 }, + [CMD_GET_STATUS] = { 1, 0, 0 }, + [CMD_SUSPEND_RADIO_COMMUNICATIONS] = { 1, 1, 1 }, + [CMD_GET_SUSPEND_RADIO_COMMUNICATIONS] = { 1, 0, 0 }, + [CMD_DM_HANDLE_ALCSYNC] = { 1, 1, 1 }, + [CMD_SET_APPKEY] = { 1, 16, 16 }, + [CMD_GET_ADR_PROFILE] = { 1, 0, 0 }, + [CMD_GET_CERTIFICATION_MODE] = { 1, 0, 0 }, #if defined( STM32L476xx ) - [CMD_STORE_AND_FORWARD_SET_STATE] = { 1, 1, 1 }, - [CMD_STORE_AND_FORWARD_GET_STATE] = { 1, 0, 0 }, - [CMD_STORE_AND_FORWARD_ADD_DATA] = { 1, 2, 244 }, - [CMD_STORE_AND_FORWARD_CLEAR_DATA] = { 1, 0, 0 }, - [CMD_STORE_AND_FORWARD_GET_FREE_SLOT] = { 1, 0, 0 }, + [CMD_STORE_AND_FORWARD_SET_STATE] = { 1, 1, 1 }, + [CMD_STORE_AND_FORWARD_GET_STATE] = { 1, 0, 0 }, + [CMD_STORE_AND_FORWARD_ADD_DATA] = { 1, 2, 244 }, + [CMD_STORE_AND_FORWARD_CLEAR_DATA] = { 1, 0, 0 }, + [CMD_STORE_AND_FORWARD_GET_FREE_SLOT] = { 1, 0, 0 }, #endif // STM32L476xx #if defined( ADD_APP_GEOLOCATION ) && defined( STM32L476xx ) [CMD_GNSS_SCAN] = { 1, 5, 5 }, @@ -267,15 +267,18 @@ static const uint8_t host_cmd_tab[CMD_MAX][HOST_CMD_TAB_IDX_COUNT] = { [CMD_WIFI_SET_PAYLOAD_FORMAT] = { 1, 1, 1 }, [CMD_LR11XX_RADIO_READ] = { 1, 0, 255 }, [CMD_LR11XX_RADIO_WRITE] = { 1, 0, 255 }, - #endif // ADD_APP_GEOLOCATION && STM32L476xx - [CMD_SET_RTC_OFFSET] ={1,4,4}, + + [CMD_SET_RTC_OFFSET] = { 1, 4, 4 }, + #if defined( USE_RELAY_TX ) - [CMD_SET_RELAY_CONFIG] ={1,10,24}, - [CMD_GET_RELAY_CONFIG] ={1,0,0}, -#endif // ADD_RELAY_TX_CMD - [CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = { 1, 0, 0 }, - [CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = { 1, 1, 1 }, + [CMD_SET_RELAY_CONFIG] = { 1, 10, 24 }, + [CMD_GET_RELAY_CONFIG] = { 1, 0, 0 }, +#endif // USE_RELAY_TX + + [CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = { 1, 0, 0 }, + [CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = { 1, 1, 1 }, + [CMD_MODEM_GET_CRASHLOG] = { 1, 0, 0 }, }; /** @@ -284,25 +287,25 @@ static const uint8_t host_cmd_tab[CMD_MAX][HOST_CMD_TAB_IDX_COUNT] = { */ static const uint8_t host_cmd_test_tab[CMD_TST_MAX][HOST_CMD_TAB_IDX_COUNT] = { // [CMD_xxx] = {availability, len_min, len_max} - [CMD_TST_START] = { 1, 8, 8 }, - [CMD_TST_NOP] = { 1, 0, 0 }, - [CMD_TST_TX_SINGLE] = { 1, 9, 9 }, - [CMD_TST_TX_CONT] = { 1, 9, 9 }, - [CMD_TST_TX_HOP] = { 1, 4, 4 }, - [CMD_TST_NA_1] = { 1, 0, 0 }, - [CMD_TST_TX_CW] = { 1, 5, 5 }, - [CMD_TST_RX_CONT] = { 1, 7, 7 }, - [CMD_TST_RSSI] = { 1, 7, 7 }, - [CMD_TST_RADIO_RST] = { 1, 0, 0 }, - [CMD_TST_EXIT] = { 1, 0, 0 }, - [CMD_TST_BUSYLOOP] = { 1, 0, 0 }, - [CMD_TST_PANIC] = { 1, 0, 0 }, - [CMD_TST_WATCHDOG] = { 1, 0, 0 }, - [CMD_TST_RADIO_READ] = { 1, 0, 255 }, - [CMD_TST_RADIO_WRITE] = { 1, 0, 255 }, - [CMD_TST_TX_SINGLE_PREAM] = { 1, 11, 11 }, - [CMD_TST_RSSI_GET] = { 1, 0, 0 }, - [CMD_TST_READ_NB_PKTS_RX_CONT] = { 1, 0, 0 }, + [CMD_TST_START] = { 1, 8, 8 }, // + [CMD_TST_EXIT] = { 1, 0, 0 }, // + [CMD_TST_NOP] = { 1, 0, 0 }, // + [CMD_TST_TX_LORA] = { 1, 25, 25 }, // + [CMD_TST_TX_FSK] = { 1, 14, 14 }, // + [CMD_TST_TX_LRFHSS] = { 1, 18, 18 }, // + [CMD_TST_TX_CW] = { 1, 5, 5 }, // + [CMD_TST_RX_LORA] = { 1, 16, 16 }, // + [CMD_TST_RX_FSK_CONT] = { 1, 4, 4 }, // + [CMD_TST_READ_NB_PKTS_RX] = { 1, 0, 0 }, // + [CMD_TST_READ_LAST_RX_PKT] = { 1, 0, 0 }, // + [CMD_TST_RSSI] = { 1, 10, 10 }, // + [CMD_TST_RSSI_GET] = { 1, 0, 0 }, // + [CMD_TST_RADIO_RST] = { 1, 0, 0 }, // + [CMD_TST_BUSYLOOP] = { 1, 0, 0 }, // + [CMD_TST_PANIC] = { 1, 0, 0 }, // + [CMD_TST_WATCHDOG] = { 1, 0, 0 }, // + [CMD_TST_RADIO_READ] = { 1, 0, 255 }, // + [CMD_TST_RADIO_WRITE] = { 1, 0, 255 }, // }; #if HAL_DBG_TRACE == HAL_FEATURE_ON @@ -439,15 +442,15 @@ static const char* host_cmd_str[CMD_MAX] = { [CMD_WIFI_SET_PAYLOAD_FORMAT] = "CMD_MODEM_WIFI_SET_PAYLOAD_FORMAT", [CMD_LR11XX_RADIO_READ] = "CMD_LR11XX_RADIO_READ", [CMD_LR11XX_RADIO_WRITE] = "CMD_LR11XX_RADIO_WRITE", - [CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = "CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF", - [CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = "CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF", - #endif // ADD_APP_GEOLOCATION && STM32L476xx [CMD_SET_RTC_OFFSET] = "CMD_SET_RTC_OFFSET", #if defined( USE_RELAY_TX ) [CMD_SET_RELAY_CONFIG] = "CMD_SET_RELAY_CONFIG", [CMD_GET_RELAY_CONFIG] = "CMD_GET_RELAY_CONFIG", #endif + [CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = "CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF", + [CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF] = "CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF", + [CMD_MODEM_GET_CRASHLOG] = "CMD_GET_CRASHLOG", }; #endif @@ -457,82 +460,38 @@ static const char* host_cmd_str[CMD_MAX] = { * */ static const char* host_cmd_test_str[CMD_TST_MAX] = { - [CMD_TST_START] = "START", - [CMD_TST_NOP] = "NOP", - [CMD_TST_TX_SINGLE] = "TX_SINGLE", - [CMD_TST_TX_CONT] = "TX_CONT", - [CMD_TST_TX_HOP] = "TX_HOP", - [CMD_TST_NA_1] = "NA_1", - [CMD_TST_TX_CW] = "TX_CW", - [CMD_TST_RX_CONT] = "RX_CONT", - [CMD_TST_RSSI] = "RSSI", - [CMD_TST_RADIO_RST] = "RADIO_RST", - [CMD_TST_EXIT] = "EXIT", - [CMD_TST_BUSYLOOP] = "BUSYLOOP", - [CMD_TST_PANIC] = "PANIC", - [CMD_TST_WATCHDOG] = "WATCHDOG", - [CMD_TST_RADIO_READ] = "RADIO_READ", - [CMD_TST_RADIO_WRITE] = "RADIO_WRITE", - [CMD_TST_TX_SINGLE_PREAM] = "TX_SINGLE_PREAM", - [CMD_TST_RSSI_GET] = "TST_RSSI_GET", - [CMD_TST_READ_NB_PKTS_RX_CONT] = "READ_NB_PKTS_RX_CONT", + [CMD_TST_START] = "START", + [CMD_TST_EXIT] = "EXIT", + [CMD_TST_NOP] = "NOP", + [CMD_TST_TX_LORA] = "TX_LORA", + [CMD_TST_TX_FSK] = "TX_FSK", + [CMD_TST_TX_LRFHSS] = "TX_LRFHSS", + [CMD_TST_TX_CW] = "TX_CW", + [CMD_TST_RX_LORA] = "RX_LORA", + [CMD_TST_RX_FSK_CONT] = "RX_FSK_CONT", + [CMD_TST_READ_NB_PKTS_RX] = "READ_NB_PKTS_RX", + [CMD_TST_READ_LAST_RX_PKT] = "READ_LAST_RX_PKT", + [CMD_TST_RSSI] = "RSSI", + [CMD_TST_RSSI_GET] = "TST_RSSI_GET", + [CMD_TST_RADIO_RST] = "RADIO_RST", + [CMD_TST_BUSYLOOP] = "BUSYLOOP", + [CMD_TST_PANIC] = "PANIC", + [CMD_TST_WATCHDOG] = "WATCHDOG", + [CMD_TST_RADIO_READ] = "RADIO_READ", + [CMD_TST_RADIO_WRITE] = "RADIO_WRITE", }; #endif /* clang-format off */ -/** - * @brief Spreading factor conversion table from hw modem command format to test modem api - * - */ -static const smtc_modem_test_sf_t cmd_test_sf_table[SMTC_MODEM_TEST_LORA_SF_COUNT] = { - SMTC_MODEM_TEST_FSK, - SMTC_MODEM_TEST_LORA_SF7, - SMTC_MODEM_TEST_LORA_SF8, - SMTC_MODEM_TEST_LORA_SF9, - SMTC_MODEM_TEST_LORA_SF10, - SMTC_MODEM_TEST_LORA_SF11, - SMTC_MODEM_TEST_LORA_SF12, - SMTC_MODEM_TEST_LORA_SF5, - SMTC_MODEM_TEST_LORA_SF6 -}; - -/** - * @brief Bandwidth conversion table from hw modem command format to test modem api - * - */ -static const smtc_modem_test_bw_t cmd_test_bw_table[SMTC_MODEM_TEST_BW_COUNT] = { - SMTC_MODEM_TEST_BW_125_KHZ, - SMTC_MODEM_TEST_BW_250_KHZ, - SMTC_MODEM_TEST_BW_500_KHZ, - SMTC_MODEM_TEST_BW_200_KHZ, - SMTC_MODEM_TEST_BW_400_KHZ, - SMTC_MODEM_TEST_BW_800_KHZ, - SMTC_MODEM_TEST_BW_1600_KHZ, -}; - -/** - * @brief Coding rate conversion table from hw modem command format to test modem api - * - */ -static const smtc_modem_test_cr_t cmd_test_cr_table[SMTC_MODEM_TEST_CR_COUNT] = { - SMTC_MODEM_TEST_CR_4_5, - SMTC_MODEM_TEST_CR_4_6, - SMTC_MODEM_TEST_CR_4_7, - SMTC_MODEM_TEST_CR_4_8, - SMTC_MODEM_TEST_CR_LI_4_5, - SMTC_MODEM_TEST_CR_LI_4_6, - SMTC_MODEM_TEST_CR_LI_4_8 -}; - /** * @brief Modem class conversion table from hw modem command format to modem api * */ -static const smtc_modem_class_t cmd_modem_class_table[]={ +static const smtc_modem_class_t cmd_modem_class_table[] = { SMTC_MODEM_CLASS_A, SMTC_MODEM_CLASS_C, - SMTC_MODEM_CLASS_B, + SMTC_MODEM_CLASS_B }; /** @@ -569,9 +528,13 @@ static const uint8_t events_lut[SMTC_MODEM_EVENT_MAX] = { [SMTC_MODEM_EVENT_RELAY_TX_DYNAMIC] = 0x30, [SMTC_MODEM_EVENT_RELAY_TX_MODE] = 0x31, [SMTC_MODEM_EVENT_RELAY_TX_SYNC] = 0x32, + [SMTC_MODEM_EVENT_RELAY_RX_RUNNING] = 0x33, + [SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE] = 0x34, + [SMTC_MODEM_EVENT_TEST_MODE] = 0x35, //!< Test mode event }; + /** * @brief Look Up Table for hw modem return code opcodes * @@ -612,16 +575,6 @@ static cmd_length_valid_t cmd_parser_check_cmd_size( host_cmd_id_t cmd_id, uint8 */ static cmd_length_valid_t cmd_test_parser_check_cmd_size( host_cmd_test_id_t test_id, uint8_t length ); -/** - * @brief Check if received sf, bw and cr are acceptable - * - * @param [in] sf Received spreading factor - * @param [in] bw Received bandwidth - * @param [in] cr Received coding rate - * @return cmd_parse_status_t - */ -static cmd_parse_status_t cmd_test_parser_check_sf_bw_cr( uint8_t sf, uint8_t bw, uint8_t cr ); - /** * @brief Crc function used for LFU (Large File Upload) * @@ -754,7 +707,18 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output cmd_output->buffer[2] = current_event.event_data.relay_tx.status; cmd_output->length = 3; break; - + case SMTC_MODEM_EVENT_RELAY_RX_RUNNING: + cmd_output->buffer[2] = current_event.event_data.relay_rx.status; + cmd_output->length = 3; + break; + case SMTC_MODEM_EVENT_TEST_MODE: + cmd_output->buffer[2] = current_event.event_data.test_mode_status.status; + cmd_output->length = 3; + break; + case SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE: + cmd_output->buffer[2] = current_event.event_data.regional_duty_cycle.status; + cmd_output->length = 3; + break; default: cmd_output->length = 0; break; @@ -1873,6 +1837,22 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output rc_lut[smtc_modem_set_join_duty_cycle_backoff_bypass( STACK_ID, cmd_input->buffer[0] )]; break; } + case CMD_MODEM_GET_CRASHLOG: + { + uint8_t crash_string_length = 0; + + cmd_output->buffer[0] = smtc_modem_hal_crashlog_get_status( ); + smtc_modem_hal_crashlog_restore( &cmd_output->buffer[1], &crash_string_length ); + + memset( &cmd_output->buffer[crash_string_length + 1], 0, CRASH_LOG_SIZE - crash_string_length ); + + // clear status but not the data to be read if needed + smtc_modem_hal_crashlog_set_status( false ); + + cmd_output->length = CRASH_LOG_SIZE + 1; // +1 crashlog status + cmd_output->return_code = CMD_RC_OK; + break; + } #if defined( STM32L476xx ) case CMD_STORE_AND_FORWARD_SET_STATE: { @@ -2219,7 +2199,7 @@ cmd_parse_status_t parse_cmd( cmd_input_t* cmd_input, cmd_response_t* cmd_output for( uint8_t scan_index = 0; scan_index < wifi_scan_done_data.nbr_results; scan_index++ ) { - // copy LR11XX_WIFI_MAC_ADDRESS_LENGTH bytes of mac adress + // copy LR11XX_WIFI_MAC_ADDRESS_LENGTH bytes of mac address memcpy( &cmd_output->buffer[index], wifi_scan_done_data.results[scan_index].mac_address, LR11XX_WIFI_MAC_ADDRESS_LENGTH ); index += LR11XX_WIFI_MAC_ADDRESS_LENGTH; @@ -2391,79 +2371,133 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp break; } + case CMD_TST_EXIT: + { + cmd_tst_output->return_code = rc_lut[smtc_modem_test_stop( )]; + if( cmd_tst_output->return_code == CMD_RC_OK ) + { + modem_in_test_mode = false; + } + break; + } case CMD_TST_NOP: { - cmd_tst_output->return_code = rc_lut[smtc_modem_test_nop( )]; + cmd_tst_output->return_code = rc_lut[smtc_modem_test_nop( true )]; break; } - case CMD_TST_TX_SINGLE: + case CMD_TST_TX_LORA: { - uint8_t raw_sf = cmd_tst_input->buffer[5]; - uint8_t raw_bw = cmd_tst_input->buffer[6]; - uint8_t raw_cr = cmd_tst_input->buffer[7]; - - // integrity of the data shall be tested here as we perform a data change using LUT before calling api - // function - if( cmd_test_parser_check_sf_bw_cr( raw_sf, raw_bw, raw_cr ) == PARSE_OK ) - { - smtc_modem_test_sf_t sf = cmd_test_sf_table[raw_sf]; - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; - smtc_modem_test_cr_t cr = cmd_test_cr_table[raw_cr]; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; - int8_t pw = cmd_tst_input->buffer[4]; - uint8_t len = cmd_tst_input->buffer[8]; + int8_t pw = cmd_tst_input->buffer[4]; + uint8_t len = cmd_tst_input->buffer[5]; - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; + uint8_t sf = cmd_tst_input->buffer[6]; + uint8_t bw = cmd_tst_input->buffer[7]; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx( NULL, len, freq, pw, sf, bw, cr, 8, false )]; + if( bw < RAL_LORA_BW_010_KHZ ) + { + cmd_tst_output->return_code = CMD_RC_INVALID; } else { - // one of the data is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; + uint8_t cr = cmd_tst_input->buffer[8]; + + uint8_t invert_iq = cmd_tst_input->buffer[9] & 0x01; + uint8_t crc_is_on = cmd_tst_input->buffer[10] & 0x01; + ral_lora_pkt_len_modes_t header_type = cmd_tst_input->buffer[11] & 0x01; + + uint32_t preamble_size = 0; + preamble_size |= cmd_tst_input->buffer[12] << 24; + preamble_size |= cmd_tst_input->buffer[13] << 16; + preamble_size |= cmd_tst_input->buffer[14] << 8; + preamble_size |= cmd_tst_input->buffer[15]; + + uint32_t nb_of_tx = 0; + nb_of_tx |= cmd_tst_input->buffer[16] << 24; + nb_of_tx |= cmd_tst_input->buffer[17] << 16; + nb_of_tx |= cmd_tst_input->buffer[18] << 8; + nb_of_tx |= cmd_tst_input->buffer[19]; + + uint32_t delay_ms = 0; + delay_ms |= cmd_tst_input->buffer[20] << 24; + delay_ms |= cmd_tst_input->buffer[21] << 16; + delay_ms |= cmd_tst_input->buffer[22] << 8; + delay_ms |= cmd_tst_input->buffer[23]; + + uint8_t sync_word = cmd_tst_input->buffer[24]; + + cmd_tst_output->return_code = + rc_lut[smtc_modem_test_tx_lora( NULL, len, freq, pw, sf, bw, cr, sync_word, invert_iq, crc_is_on, + header_type, preamble_size, nb_of_tx, delay_ms )]; } break; } - case CMD_TST_TX_CONT: + case CMD_TST_TX_FSK: { - uint8_t raw_sf = cmd_tst_input->buffer[5]; - uint8_t raw_bw = cmd_tst_input->buffer[6]; - uint8_t raw_cr = cmd_tst_input->buffer[7]; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; - // integrity of the data shall be tested here as we perform a data change using LUT before calling api - // function - if( cmd_test_parser_check_sf_bw_cr( raw_sf, raw_bw, raw_cr ) == PARSE_OK ) - { - smtc_modem_test_sf_t sf = cmd_test_sf_table[raw_sf]; - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; - smtc_modem_test_cr_t cr = cmd_test_cr_table[raw_cr]; + int8_t pw = cmd_tst_input->buffer[4]; + uint8_t len = cmd_tst_input->buffer[5]; - int8_t pw = cmd_tst_input->buffer[4]; - uint8_t len = cmd_tst_input->buffer[8]; + uint32_t nb_of_tx = 0; + nb_of_tx |= cmd_tst_input->buffer[6] << 24; + nb_of_tx |= cmd_tst_input->buffer[7] << 16; + nb_of_tx |= cmd_tst_input->buffer[8] << 8; + nb_of_tx |= cmd_tst_input->buffer[9]; - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; + uint32_t delay_ms = 0; + delay_ms |= cmd_tst_input->buffer[10] << 24; + delay_ms |= cmd_tst_input->buffer[11] << 16; + delay_ms |= cmd_tst_input->buffer[12] << 8; + delay_ms |= cmd_tst_input->buffer[13]; + + cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx_fsk( NULL, len, freq, pw, nb_of_tx, delay_ms )]; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx( NULL, len, freq, pw, sf, bw, cr, 8, true )]; - } - else - { - // one of the data is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; - } break; } - case CMD_TST_TX_HOP: + case CMD_TST_TX_LRFHSS: { - cmd_tst_output->return_code = CMD_RC_NOT_IMPLEMENTED; - cmd_tst_output->length = 0; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; + + int8_t pw = cmd_tst_input->buffer[4]; + uint8_t len = cmd_tst_input->buffer[5]; + + uint8_t grid = cmd_tst_input->buffer[6]; + uint8_t bw = cmd_tst_input->buffer[7]; + uint8_t cr = cmd_tst_input->buffer[8]; + + SMTC_HAL_TRACE_PRINTF( "grid:%u, bw:%u,cr:%u\n", grid, bw, cr ); + + uint32_t nb_of_tx = 0; + nb_of_tx |= cmd_tst_input->buffer[9] << 24; + nb_of_tx |= cmd_tst_input->buffer[10] << 16; + nb_of_tx |= cmd_tst_input->buffer[11] << 8; + nb_of_tx |= cmd_tst_input->buffer[12]; + + uint32_t delay_ms = 0; + delay_ms |= cmd_tst_input->buffer[13] << 24; + delay_ms |= cmd_tst_input->buffer[14] << 16; + delay_ms |= cmd_tst_input->buffer[15] << 8; + delay_ms |= cmd_tst_input->buffer[16]; + + bool enable_hopping = cmd_tst_input->buffer[17] & 0x01; + + cmd_tst_output->return_code = + rc_lut[smtc_modem_test_tx_lrfhss( NULL, len, freq, pw, cr, bw, grid, enable_hopping, nb_of_tx, delay_ms )]; + break; } case CMD_TST_TX_CW: @@ -2479,36 +2513,48 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp cmd_tst_output->return_code = rc_lut[smtc_modem_test_tx_cw( freq, pw )]; break; } - case CMD_TST_RX_CONT: + case CMD_TST_RX_LORA: { - uint8_t raw_sf = cmd_tst_input->buffer[4]; - uint8_t raw_bw = cmd_tst_input->buffer[5]; - uint8_t raw_cr = cmd_tst_input->buffer[6]; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; - // integrity of the data shall be tested here as we perform a data change using LUT before calling api - // function - if( cmd_test_parser_check_sf_bw_cr( raw_sf, raw_bw, raw_cr ) == PARSE_OK ) - { - smtc_modem_test_sf_t sf = cmd_test_sf_table[raw_sf]; - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; - smtc_modem_test_cr_t cr = cmd_test_cr_table[raw_cr]; + uint8_t sf = cmd_tst_input->buffer[4]; + uint8_t bw = cmd_tst_input->buffer[5]; + uint8_t cr = cmd_tst_input->buffer[6]; - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; + uint8_t sync_word = cmd_tst_input->buffer[7]; + uint8_t invert_iq = cmd_tst_input->buffer[8] & 0x01; + uint8_t crc_is_on = cmd_tst_input->buffer[9] & 0x01; + ral_lora_pkt_len_modes_t header_type = cmd_tst_input->buffer[10] & 0x01; + + uint32_t preamble_size = 0; + preamble_size |= cmd_tst_input->buffer[11] << 24; + preamble_size |= cmd_tst_input->buffer[12] << 16; + preamble_size |= cmd_tst_input->buffer[13] << 8; + preamble_size |= cmd_tst_input->buffer[14]; + + uint8_t nb_symb_timeout = cmd_tst_input->buffer[15]; + cmd_tst_output->return_code = rc_lut[smtc_modem_test_rx_lora( freq, sf, bw, cr, sync_word, invert_iq, crc_is_on, + header_type, preamble_size, nb_symb_timeout )]; + + break; + } + case CMD_TST_RX_FSK_CONT: + { + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; + + cmd_tst_output->return_code = rc_lut[smtc_modem_test_rx_fsk_continuous( freq )]; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_rx_continuous( freq, sf, bw, cr )]; - } - else - { - // one of the data is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; - } break; } - case CMD_TST_READ_NB_PKTS_RX_CONT: + case CMD_TST_READ_NB_PKTS_RX: { uint32_t nb_read_pkt = 0; cmd_tst_output->return_code = rc_lut[smtc_modem_test_get_nb_rx_packets( &nb_read_pkt )]; @@ -2519,30 +2565,39 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp cmd_tst_output->length = 4; break; } + case CMD_TST_READ_LAST_RX_PKT: + { + int16_t rssi; + int16_t snr; + uint8_t rx_payload_length; + cmd_tst_output->return_code = + rc_lut[smtc_modem_test_get_last_rx_packets( &rssi, &snr, &cmd_tst_output->buffer[4], &rx_payload_length )]; + cmd_tst_output->buffer[0] = ( snr >> 8 ) & 0xFF; + cmd_tst_output->buffer[1] = ( snr & 0xFF ); + cmd_tst_output->buffer[2] = ( rssi >> 8 ) & 0xFF; + cmd_tst_output->buffer[3] = ( rssi & 0xFF ); + cmd_tst_output->length = 4 + rx_payload_length; + break; + } case CMD_TST_RSSI: { - uint8_t raw_bw = cmd_tst_input->buffer[6]; - if( raw_bw < SMTC_MODEM_TEST_BW_COUNT ) - { - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; + uint32_t freq = 0; + freq |= cmd_tst_input->buffer[0] << 24; + freq |= cmd_tst_input->buffer[1] << 16; + freq |= cmd_tst_input->buffer[2] << 8; + freq |= cmd_tst_input->buffer[3]; - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; + uint16_t time_ms = 0; + time_ms |= cmd_tst_input->buffer[4] << 8; + time_ms |= cmd_tst_input->buffer[5]; - uint16_t time_ms = 0; - time_ms |= cmd_tst_input->buffer[4] << 8; - time_ms |= cmd_tst_input->buffer[5]; + uint32_t bw = 0; + bw |= cmd_tst_input->buffer[6] << 24; + bw |= cmd_tst_input->buffer[7] << 16; + bw |= cmd_tst_input->buffer[8] << 8; + bw |= cmd_tst_input->buffer[9]; - cmd_tst_output->return_code = rc_lut[smtc_modem_test_rssi( freq, bw, time_ms )]; - } - else - { - // bw is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; - } + cmd_tst_output->return_code = rc_lut[smtc_modem_test_rssi_lbt( freq, bw, time_ms )]; break; } case CMD_TST_RSSI_GET: @@ -2558,15 +2613,6 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp cmd_tst_output->return_code = rc_lut[smtc_modem_test_radio_reset( )]; break; } - case CMD_TST_EXIT: - { - cmd_tst_output->return_code = rc_lut[smtc_modem_test_stop( )]; - if( cmd_tst_output->return_code == CMD_RC_OK ) - { - modem_in_test_mode = false; - } - break; - } case CMD_TST_BUSYLOOP: { // First check if modem is in test mode @@ -2623,10 +2669,19 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp uint8_t data_length = cmd_tst_input->buffer[command_length + 1]; uint8_t data[255] = { 0 }; - cmd_tst_output->return_code = - rc_lut[smtc_modem_test_direct_radio_read( command, command_length, data, data_length )]; - memcpy( cmd_tst_output->buffer, data, data_length ); - cmd_tst_output->length = data_length; + smtc_modem_return_code_t rc = smtc_modem_test_direct_radio_read( command, command_length, data, data_length ); + cmd_tst_output->return_code = rc_lut[rc]; + + if( rc != SMTC_MODEM_RC_OK ) + { + cmd_tst_output->length = 0; + } + else + { + memcpy( cmd_tst_output->buffer, data, data_length ); + cmd_tst_output->length = data_length; + } + break; } case CMD_TST_RADIO_WRITE: @@ -2644,42 +2699,6 @@ cmd_parse_status_t cmd_test_parser( cmd_tst_input_t* cmd_tst_input, cmd_tst_resp cmd_tst_output->length = 0; break; } - case CMD_TST_TX_SINGLE_PREAM: - { - uint8_t raw_sf = cmd_tst_input->buffer[5]; - uint8_t raw_bw = cmd_tst_input->buffer[6]; - uint8_t raw_cr = cmd_tst_input->buffer[7]; - - // integrity of the data shall be tested here as we perform a data change using LUT before calling api - // function - if( cmd_test_parser_check_sf_bw_cr( raw_sf, raw_bw, raw_cr ) == PARSE_OK ) - { - smtc_modem_test_sf_t sf = cmd_test_sf_table[raw_sf]; - smtc_modem_test_bw_t bw = cmd_test_bw_table[raw_bw]; - smtc_modem_test_cr_t cr = cmd_test_cr_table[raw_cr]; - int8_t pw = cmd_tst_input->buffer[4]; - uint8_t len = cmd_tst_input->buffer[8]; - - uint32_t freq = 0; - freq |= cmd_tst_input->buffer[0] << 24; - freq |= cmd_tst_input->buffer[1] << 16; - freq |= cmd_tst_input->buffer[2] << 8; - freq |= cmd_tst_input->buffer[3]; - - uint16_t preamble_length = 0; - preamble_length |= cmd_tst_input->buffer[9] << 8; - preamble_length |= cmd_tst_input->buffer[10]; - - cmd_tst_output->return_code = - rc_lut[smtc_modem_test_tx( NULL, len, freq, pw, sf, bw, cr, preamble_length, false )]; - } - else - { - // one of the data is not in the accepted range => reject command - cmd_tst_output->return_code = CMD_RC_INVALID; - } - break; - } default: { cmd_tst_output->return_code = CMD_RC_UNKNOWN; @@ -2734,26 +2753,6 @@ static cmd_length_valid_t cmd_test_parser_check_cmd_size( host_cmd_test_id_t tst return CMD_LENGTH_VALID; } -static cmd_parse_status_t cmd_test_parser_check_sf_bw_cr( uint8_t sf, uint8_t bw, uint8_t cr ) -{ - if( sf >= SMTC_MODEM_TEST_LORA_SF_COUNT ) - { - return PARSE_ERROR; - } - else if( bw >= SMTC_MODEM_TEST_BW_COUNT ) - { - return PARSE_ERROR; - } - else if( cr >= SMTC_MODEM_TEST_CR_COUNT ) - { - return PARSE_ERROR; - } - else - { - return PARSE_OK; - } -} - uint32_t cmd_parser_crc( const uint8_t* buf, int len ) { uint32_t crc = 0xFFFFFFFF; diff --git a/lbm_examples/hw_modem/cmd_parser.h b/lbm_examples/hw_modem/cmd_parser.h index ba789c2..2cd554c 100644 --- a/lbm_examples/hw_modem/cmd_parser.h +++ b/lbm_examples/hw_modem/cmd_parser.h @@ -204,6 +204,7 @@ typedef enum host_cmd_id_e CMD_GET_SUSPEND_RADIO_COMMUNICATIONS = 0x95, CMD_GET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF = 0x96, CMD_SET_BYPASS_JOIN_DUTY_CYCLE_BACKOFF = 0x97, + CMD_MODEM_GET_CRASHLOG = 0x98, CMD_MAX } host_cmd_id_t; @@ -212,25 +213,25 @@ typedef enum host_cmd_id_e */ typedef enum host_cmd_test_id_e { - CMD_TST_START = 0x00, - CMD_TST_NOP = 0x01, - CMD_TST_TX_SINGLE = 0x02, - CMD_TST_TX_CONT = 0x03, - CMD_TST_TX_HOP = 0x04, - CMD_TST_NA_1 = 0x05, - CMD_TST_TX_CW = 0x06, - CMD_TST_RX_CONT = 0x07, - CMD_TST_RSSI = 0x08, - CMD_TST_RADIO_RST = 0x09, - CMD_TST_EXIT = 0x0B, - CMD_TST_BUSYLOOP = 0x0C, - CMD_TST_PANIC = 0x0D, - CMD_TST_WATCHDOG = 0x0E, - CMD_TST_RADIO_READ = 0x0F, - CMD_TST_RADIO_WRITE = 0x10, - CMD_TST_TX_SINGLE_PREAM = 0x14, - CMD_TST_RSSI_GET = 0x15, - CMD_TST_READ_NB_PKTS_RX_CONT = 0x18, + CMD_TST_START = 0x00, + CMD_TST_EXIT = 0x01, + CMD_TST_NOP = 0x02, + CMD_TST_TX_LORA = 0x03, + CMD_TST_TX_FSK = 0x04, + CMD_TST_TX_LRFHSS = 0x05, + CMD_TST_TX_CW = 0x06, + CMD_TST_RX_LORA = 0x07, + CMD_TST_RX_FSK_CONT = 0x08, + CMD_TST_READ_NB_PKTS_RX = 0x09, + CMD_TST_READ_LAST_RX_PKT = 0x0A, + CMD_TST_RSSI = 0x0B, + CMD_TST_RSSI_GET = 0x0C, + CMD_TST_RADIO_RST = 0x0D, + CMD_TST_BUSYLOOP = 0x0E, + CMD_TST_PANIC = 0x0F, + CMD_TST_WATCHDOG = 0x10, + CMD_TST_RADIO_READ = 0x11, + CMD_TST_RADIO_WRITE = 0x12, CMD_TST_MAX } host_cmd_test_id_t; diff --git a/lbm_examples/hw_modem/geoloc_bsp.c b/lbm_examples/hw_modem/geoloc_bsp.c index 6f2026f..aa0a2b3 100644 --- a/lbm_examples/hw_modem/geoloc_bsp.c +++ b/lbm_examples/hw_modem/geoloc_bsp.c @@ -79,21 +79,22 @@ void geolocation_bsp_get_lr11xx_reg_mode( const void* context, lr11xx_system_reg *reg_mode = LR11XX_SYSTEM_REG_MODE_DCDC; } -void geolocation_bsp_gnss_get_consumption( lr11xx_gnss_instantaneous_power_consumption_ua_t* instantaneous_power_consumption_ua ) +void geolocation_bsp_gnss_get_consumption( + lr11xx_gnss_instantaneous_power_consumption_ua_t* instantaneous_power_consumption_ua ) { /* These value are for EVK board in DC DC mode with Xtal 32KHz and a TCXO 32MHz*/ - instantaneous_power_consumption_ua->board_voltage_mv = 3300; - instantaneous_power_consumption_ua->init_ua = 3150; - instantaneous_power_consumption_ua->phase1_gps_capture_ua = 11900; - instantaneous_power_consumption_ua->phase1_gps_process_ua = 3340; - instantaneous_power_consumption_ua->multiscan_gps_capture_ua = 10700; - instantaneous_power_consumption_ua->multiscan_gps_process_ua = 4180; - instantaneous_power_consumption_ua->phase1_beidou_capture_ua = 13500; - instantaneous_power_consumption_ua->phase1_beidou_process_ua = 3190; - instantaneous_power_consumption_ua->multiscan_beidou_capture_ua = 12600; - instantaneous_power_consumption_ua->multiscan_beidou_process_ua = 3430; - instantaneous_power_consumption_ua->sleep_32k_ua = 1210; - instantaneous_power_consumption_ua->demod_sleep_32m_ua = 2530; + instantaneous_power_consumption_ua->board_voltage_mv = 3300; + instantaneous_power_consumption_ua->init_ua = 3150; + instantaneous_power_consumption_ua->phase1_gps_capture_ua = 11900; + instantaneous_power_consumption_ua->phase1_gps_process_ua = 3340; + instantaneous_power_consumption_ua->multiscan_gps_capture_ua = 10700; + instantaneous_power_consumption_ua->multiscan_gps_process_ua = 4180; + instantaneous_power_consumption_ua->phase1_beidou_capture_ua = 13500; + instantaneous_power_consumption_ua->phase1_beidou_process_ua = 3190; + instantaneous_power_consumption_ua->multiscan_beidou_capture_ua = 12600; + instantaneous_power_consumption_ua->multiscan_beidou_process_ua = 3430; + instantaneous_power_consumption_ua->sleep_32k_ua = 1210; + instantaneous_power_consumption_ua->demod_sleep_32m_ua = 2530; } /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_examples/hw_modem/hw_modem.c b/lbm_examples/hw_modem/hw_modem.c index 66543d8..b1e33d4 100644 --- a/lbm_examples/hw_modem/hw_modem.c +++ b/lbm_examples/hw_modem/hw_modem.c @@ -57,7 +57,7 @@ * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define HW_MODEM_RX_BUFF_MAX_LENGTH 259 +#define HW_MODEM_RX_BUFF_MAX_LENGTH 261 /* * ----------------------------------------------------------------------------- diff --git a/lbm_examples/main.c b/lbm_examples/main.c index 0547cfd..ff386d1 100644 --- a/lbm_examples/main.c +++ b/lbm_examples/main.c @@ -92,8 +92,6 @@ int main( void ) main_porting_tests( ); #elif MAKEFILE_APP == LCTT_CERTIF main_lctt_certif( ); -#elif MAKEFILE_APP == RELAY_TX - main_periodical_uplink( ); #else #error "Unknown application" ## MAKEFILE_APP #endif diff --git a/lbm_examples/main.h b/lbm_examples/main.h index 14b4f23..5ee6ab6 100644 --- a/lbm_examples/main.h +++ b/lbm_examples/main.h @@ -69,7 +69,6 @@ extern "C" { #define HW_MODEM 1 #define PORTING_TESTS 2 #define LCTT_CERTIF 3 -#define RELAY_TX 4 /* * ----------------------------------------------------------------------------- diff --git a/lbm_examples/main_examples/example_options.h b/lbm_examples/main_examples/example_options.h index 646f8c1..2900c52 100644 --- a/lbm_examples/main_examples/example_options.h +++ b/lbm_examples/main_examples/example_options.h @@ -38,7 +38,6 @@ #ifdef __cplusplus extern "C" { #endif - /* * ----------------------------------------------------------------------------- * --- DEPENDENCIES ------------------------------------------------------------ @@ -59,19 +58,19 @@ extern "C" { */ #define USER_LORAWAN_DEVICE_EUI \ { \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 \ } #define USER_LORAWAN_JOIN_EUI \ { \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 \ } #define USER_LORAWAN_GEN_APP_KEY \ { \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 \ } #define USER_LORAWAN_APP_KEY \ { \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 \ } /** @@ -84,7 +83,6 @@ extern "C" { #define MODEM_EXAMPLE_REGION SMTC_MODEM_REGION_WW2G4 #endif #endif // MODEM_EXAMPLE_REGION -// clang-format on #ifdef __cplusplus } diff --git a/lbm_examples/main_examples/main_lctt_certif.c b/lbm_examples/main_examples/main_lctt_certif.c index 38a70b1..5e37ae9 100644 --- a/lbm_examples/main_examples/main_lctt_certif.c +++ b/lbm_examples/main_examples/main_lctt_certif.c @@ -224,10 +224,7 @@ static void send_uplink_counter_on_port( uint8_t port ); * @brief Example enable/disable certification mode by pushing blue button * */ -#if defined( USE_RELAY_TX ) -static smtc_modem_relay_tx_config_t relay_config = { 0 }; -#endif -void main_lctt_certif( void ) +void main_lctt_certif( void ) { uint32_t sleep_time_ms = 0; @@ -320,14 +317,6 @@ static void modem_event_callback( void ) #endif // Set user region ASSERT_SMTC_MODEM_RC( smtc_modem_set_region( stack_id, MODEM_EXAMPLE_REGION ) ); - #if defined( USE_RELAY_TX ) - relay_config.second_ch_enable = false; - relay_config.activation = SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ED_CONTROLED; - relay_config.number_of_miss_wor_ack_to_switch_in_nosync_mode = 1; - relay_config.smart_level = 5; - relay_config.backoff = 4; - ASSERT_SMTC_MODEM_RC( smtc_modem_relay_tx_enable( stack_id, &relay_config ) ); - #endif ASSERT_SMTC_MODEM_RC( smtc_modem_get_certification_mode( stack_id, &certif_running ) ); if( certif_running == false ) { @@ -452,6 +441,40 @@ static void modem_event_callback( void ) SMTC_HAL_TRACE_INFO( "Event received: MUTE\n" ); break; + case SMTC_MODEM_EVENT_RELAY_TX_DYNAMIC: //!< Relay TX dynamic mode has enable or disable the WOR protocol + SMTC_HAL_TRACE_INFO( "Event received: RELAY_TX_DYNAMIC\n" ); + break; + + case SMTC_MODEM_EVENT_RELAY_TX_MODE: //!< Relay TX activation has been updated + SMTC_HAL_TRACE_INFO( "Event received: RELAY_TX_MODE\n" ); + break; + + case SMTC_MODEM_EVENT_RELAY_TX_SYNC: //!< Relay TX synchronisation has changed + SMTC_HAL_TRACE_INFO( "Event received: RELAY_TX_SYNC\n" ); + break; + case SMTC_MODEM_EVENT_RELAY_RX_RUNNING: + SMTC_HAL_TRACE_INFO( "Event received: RELAY_RX_RUNNING\n" ); +#if defined( ADD_CSMA ) + bool csma_state = false; + ASSERT_SMTC_MODEM_RC( smtc_modem_csma_get_state( STACK_ID, &csma_state ) ); + if( ( current_event.event_data.relay_rx.status == true ) && ( csma_state == true ) ) + { + // Disable CSMA when Relay Rx Is enabled by network + ASSERT_SMTC_MODEM_RC( smtc_modem_csma_set_state( STACK_ID, false ) ); + } +#if defined( ENABLE_CSMA_BY_DEFAULT ) + if( current_event.event_data.relay_rx.status == false ) + { + ASSERT_SMTC_MODEM_RC( smtc_modem_csma_set_state( STACK_ID, true ) ); + } +#endif // ENABLE_CSMA_BY_DEFAULT +#endif // ADD_CSMA + + break; + case SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE: + SMTC_HAL_TRACE_INFO( "Event received: DUTY_CYCLE\n" ); + break; + default: SMTC_HAL_TRACE_ERROR( "Unknown event %u\n", current_event.event_type ); break; diff --git a/lbm_examples/main_examples/main_periodical_uplink.c b/lbm_examples/main_examples/main_periodical_uplink.c index 30a3594..821dadd 100644 --- a/lbm_examples/main_examples/main_periodical_uplink.c +++ b/lbm_examples/main_examples/main_periodical_uplink.c @@ -41,6 +41,7 @@ #include "main.h" +#include "smtc_modem_test_api.h" #include "smtc_modem_api.h" #include "smtc_modem_utilities.h" @@ -333,7 +334,8 @@ static void modem_event_callback( void ) relay_config.second_ch_enable = false; // The RelayModeActivation field indicates how the end-device SHOULD manage the relay mode. - relay_config.activation = SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_DYNAMIC; + relay_config.activation = + SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ENABLE; // SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_DYNAMIC; // number_of_miss_wor_ack_to_switch_in_nosync_mode field indicates that the // relay mode SHALL be restart in no sync mode when it does not receive a WOR ACK frame after @@ -350,9 +352,10 @@ static void modem_event_callback( void ) // BackOff Description // 0 Always send a LoRaWAN uplink // 1..63 Send a LoRaWAN uplink after X WOR frames without a WOR ACK - relay_config.backoff = 4; + relay_config.backoff = 0; // 4; ASSERT_SMTC_MODEM_RC( smtc_modem_relay_tx_enable( stack_id, &relay_config ) ); #endif + ASSERT_SMTC_MODEM_RC( smtc_modem_join_network( stack_id ) ); break; @@ -474,6 +477,49 @@ static void modem_event_callback( void ) case SMTC_MODEM_EVENT_RELAY_TX_SYNC: //!< Relay TX synchronisation has changed SMTC_HAL_TRACE_INFO( "Event received: RELAY_TX_SYNC\n" ); break; + case SMTC_MODEM_EVENT_RELAY_RX_RUNNING: + SMTC_HAL_TRACE_INFO( "Event received: RELAY_RX_RUNNING\n" ); +#if defined( ADD_CSMA ) + bool csma_state = false; + ASSERT_SMTC_MODEM_RC( smtc_modem_csma_get_state( STACK_ID, &csma_state ) ); + if( ( current_event.event_data.relay_rx.status == true ) && ( csma_state == true ) ) + { + // Disable CSMA when Relay Rx Is enabled by network + ASSERT_SMTC_MODEM_RC( smtc_modem_csma_set_state( STACK_ID, false ) ); + } +#if defined( ENABLE_CSMA_BY_DEFAULT ) + if( current_event.event_data.relay_rx.status == false ) + { + ASSERT_SMTC_MODEM_RC( smtc_modem_csma_set_state( STACK_ID, true ) ); + } +#endif // ENABLE_CSMA_BY_DEFAULT +#endif // ADD_CSMA + + break; + case SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE: + SMTC_HAL_TRACE_INFO( "Event received: DUTY_CYCLE\n" ); + break; + case SMTC_MODEM_EVENT_TEST_MODE: + { + uint8_t status_test_mode = current_event.event_data.test_mode_status.status; +#if MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON + char* status_name[] = { "SMTC_MODEM_EVENT_TEST_MODE_ENDED", "SMTC_MODEM_EVENT_TEST_MODE_TX_COMPLETED", + "SMTC_MODEM_EVENT_TEST_MODE_TX_DONE", "SMTC_MODEM_EVENT_TEST_MODE_RX_DONE" }; + SMTC_HAL_TRACE_INFO( "Event received: TEST_MODE : %s\n", status_name[status_test_mode] ); +#endif + if( status_test_mode == SMTC_MODEM_EVENT_TEST_MODE_RX_DONE ) + { + int16_t rssi; + int16_t snr; + uint8_t rx_payload_length; + smtc_modem_test_get_last_rx_packets( &rssi, &snr, rx_payload, &rx_payload_length ); + SMTC_HAL_TRACE_ARRAY( "rx_payload", rx_payload, rx_payload_length ); + SMTC_HAL_TRACE_PRINTF( "rssi: %d, snr: %d\n", rssi, snr ); + } + + break; + } + default: SMTC_HAL_TRACE_ERROR( "Unknown event %u\n", current_event.event_type ); break; diff --git a/lbm_examples/main_examples/main_porting_tests.c b/lbm_examples/main_examples/main_porting_tests.c index 75b9b09..55cea29 100644 --- a/lbm_examples/main_examples/main_porting_tests.c +++ b/lbm_examples/main_examples/main_porting_tests.c @@ -183,7 +183,8 @@ static ralf_params_lora_t tx_lora_param = { .sync_word = S .pkt_params.invert_iq_is_on = false, .pkt_params.preamble_len_in_symb = 8 }; #if( ENABLE_TEST_FLASH != 0 ) -static const char* name_context_type[] = { "MODEM", "LR1MAC", "DEVNONCE", "SECURE_ELEMENT" }; +static const char* name_context_type[] = { "MODEM", "KEY_MODEM", "LORAWAN_STACK", + "FUOTA", "SECURE_ELEMENT", "STORE_AND_FORWARD" }; #endif /* diff --git a/lbm_examples/modem_pinout.h b/lbm_examples/modem_pinout.h index 549aa2f..edb9420 100644 --- a/lbm_examples/modem_pinout.h +++ b/lbm_examples/modem_pinout.h @@ -58,7 +58,7 @@ extern "C" { /********************************************************************************/ /* Application dependant */ /********************************************************************************/ -// clang-format off +/* clang-format off */ //Debug uart specific pinout for debug print #define DEBUG_UART_TX PA_2 @@ -110,7 +110,7 @@ extern "C" { #define HW_MODEM_BUSY_PIN PC_8 #define HW_MODEM_TX_LINE PC_10 #define HW_MODEM_RX_LINE PC_11 -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_examples/my_app_venv/lib64 b/lbm_examples/my_app_venv/lib64 deleted file mode 120000 index 7951405..0000000 --- a/lbm_examples/my_app_venv/lib64 +++ /dev/null @@ -1 +0,0 @@ -lib \ No newline at end of file diff --git a/lbm_examples/my_app_venv/pyvenv.cfg b/lbm_examples/my_app_venv/pyvenv.cfg deleted file mode 100644 index 9b19d30..0000000 --- a/lbm_examples/my_app_venv/pyvenv.cfg +++ /dev/null @@ -1,3 +0,0 @@ -home = /usr/local/bin -include-system-site-packages = false -version = 3.8.2 diff --git a/lbm_examples/radio_hal/radio_utilities.c b/lbm_examples/radio_hal/radio_utilities.c index fb961d0..78bf549 100644 --- a/lbm_examples/radio_hal/radio_utilities.c +++ b/lbm_examples/radio_hal/radio_utilities.c @@ -3,11 +3,12 @@ * * @brief User radio utilities implementations * - * Revised BSD License - * Copyright Semtech Corporation 2022. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* diff --git a/lbm_examples/radio_hal/radio_utilities.h b/lbm_examples/radio_hal/radio_utilities.h index 57a38e9..1dcd447 100644 --- a/lbm_examples/radio_hal/radio_utilities.h +++ b/lbm_examples/radio_hal/radio_utilities.h @@ -3,11 +3,12 @@ * * @brief User radio utilities definitions * - * Revised BSD License - * Copyright Semtech Corporation 2022. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef RADIO_UTILITIES_H @@ -78,7 +81,6 @@ int8_t radio_utilities_get_tx_power_offset( void ); */ void radio_utilities_set_tx_power_offset( int8_t tx_pwr_offset_db ); - #ifdef __cplusplus } #endif diff --git a/lbm_examples/radio_hal/ral_lr11xx_bsp.c b/lbm_examples/radio_hal/ral_lr11xx_bsp.c index 133c440..23b286f 100644 --- a/lbm_examples/radio_hal/ral_lr11xx_bsp.c +++ b/lbm_examples/radio_hal/ral_lr11xx_bsp.c @@ -52,6 +52,34 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +// TODO: check values +#define LR11XX_GFSK_RX_CONSUMPTION_DCDC 5400 +#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 7500 + +#define LR11XX_GFSK_RX_CONSUMPTION_LDO 5400 +#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO 7500 + +#define LR11XX_LORA_RX_CONSUMPTION_DCDC 5700 +#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC 7800 + +#define LR11XX_LORA_RX_CONSUMPTION_LDO 5700 +#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO 7800 + +#define LR11XX_LP_MIN_OUTPUT_POWER -17 +#define LR11XX_LP_MAX_OUTPUT_POWER 15 + +#define LR11XX_HP_MIN_OUTPUT_POWER -9 +#define LR11XX_HP_MAX_OUTPUT_POWER 22 + +#define LR11XX_HF_MIN_OUTPUT_POWER -18 +#define LR11XX_HF_MAX_OUTPUT_POWER 13 + +#define LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET 17 +#define LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET 9 +#define LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET 18 + +#define LR11XX_PWR_VREG_VBAT_SWITCH 8 + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -77,21 +105,187 @@ typedef struct lr11xx_pa_pwr_cfg_s * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define LR11XX_PWR_VREG_VBAT_SWITCH 8 - -#define LR11XX_MIN_PWR_LP_LF -17 -#define LR11XX_MAX_PWR_LP_LF 15 - -#define LR11XX_MIN_PWR_HP_LF -9 -#define LR11XX_MAX_PWR_HP_LF 22 - -#define LR11XX_MIN_PWR_PA_HF -18 -#define LR11XX_MAX_PWR_PA_HF 13 - -const lr11xx_pa_pwr_cfg_t pa_lp_cfg_table[LR11XX_MAX_PWR_LP_LF - LR11XX_MIN_PWR_LP_LF + 1] = LR11XX_PA_LP_LF_CFG_TABLE; -const lr11xx_pa_pwr_cfg_t pa_hp_cfg_table[LR11XX_MAX_PWR_HP_LF - LR11XX_MIN_PWR_HP_LF + 1] = LR11XX_PA_HP_LF_CFG_TABLE; - -const lr11xx_pa_pwr_cfg_t pa_hf_cfg_table[LR11XX_MAX_PWR_PA_HF - LR11XX_MIN_PWR_PA_HF + 1] = LR11XX_PA_HF_CFG_TABLE; +const lr11xx_pa_pwr_cfg_t pa_lp_cfg_table[LR11XX_LP_MAX_OUTPUT_POWER - LR11XX_LP_MIN_OUTPUT_POWER + 1] = LR11XX_PA_LP_LF_CFG_TABLE; +const lr11xx_pa_pwr_cfg_t pa_hp_cfg_table[LR11XX_HP_MAX_OUTPUT_POWER - LR11XX_HP_MIN_OUTPUT_POWER + 1] = LR11XX_PA_HP_LF_CFG_TABLE; + +const lr11xx_pa_pwr_cfg_t pa_hf_cfg_table[LR11XX_HF_MAX_OUTPUT_POWER - LR11XX_HF_MIN_OUTPUT_POWER + 1] = LR11XX_PA_HF_CFG_TABLE; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[] = { + 10820, // -17 dBm + 10980, // -16 dBm + 11060, // -15 dBm + 11160, // -14 dBm + 11300, // -13 dBm + 11430, // -12 dBm + 11550, // -11 dBm + 11680, // -10 dBm + 11930, // -9 dBm + 12170, // -8 dBm + 12420, // -7 dBm + 12650, // -6 dBm + 12900, // -5 dBm + 13280, // -4 dBm + 13600, // -3 dBm + 14120, // -2 dBm + 14600, // -1 dBm + 15090, // 0 dBm + 15780, // 1 dBm + 16490, // 2 dBm + 17250, // 3 dBm + 17850, // 4 dBm + 18720, // 5 dBm + 19640, // 6 dBm + 20560, // 7 dBm + 21400, // 8 dBm + 22620, // 9 dBm + 23720, // 10 dBm + 25050, // 11 dBm + 26350, // 12 dBm + 27870, // 13 dBm + 28590, // 14 dBm + 37820, // 15 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[] = { + 14950, // -17 dBm + 15280, // -16 dBm + 15530, // -15 dBm + 15770, // -14 dBm + 16020, // -13 dBm + 16290, // -12 dBm + 16550, // -11 dBm + 16760, // -10 dBm + 17280, // -9 dBm + 17770, // -8 dBm + 18250, // -7 dBm + 18750, // -6 dBm + 19250, // -5 dBm + 19960, // -4 dBm + 20710, // -3 dBm + 21620, // -2 dBm + 22570, // -1 dBm + 23570, // 0 dBm + 24990, // 1 dBm + 26320, // 2 dBm + 27830, // 3 dBm + 29070, // 4 dBm + 30660, // 5 dBm + 32490, // 6 dBm + 34220, // 7 dBm + 35820, // 8 dBm + 38180, // 9 dBm + 40220, // 10 dBm + 42800, // 11 dBm + 45030, // 12 dBm + 47900, // 13 dBm + 51220, // 14 dBm + 66060, // 15 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[] = { + 27750, // -9 dBm + 29100, // -8 dBm + 30320, // -7 dBm + 31650, // -6 dBm + 34250, // -5 dBm + 35550, // -4 dBm + 36770, // -3 dBm + 39250, // -2 dBm + 41480, // -1 dBm + 43820, // 0 dBm + 46000, // 1 dBm + 49020, // 2 dBm + 50900, // 3 dBm + 54200, // 4 dBm + 56330, // 5 dBm + 59050, // 6 dBm + 62210, // 7 dBm + 65270, // 8 dBm + 68600, // 9 dBm + 71920, // 10 dBm + 75500, // 11 dBm + 79500, // 12 dBm + 84130, // 13 dBm + 88470, // 14 dBm + 92200, // 15 dBm + 94340, // 16 dBm + 96360, // 17 dBm + 98970, // 18 dBm + 102220, // 19 dBm + 106250, // 20 dBm + 111300, // 21 dBm + 113040, // 22 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[] = { + 31310, // -9 dBm + 32700, // -8 dBm + 33970, // -7 dBm + 35270, // -6 dBm + 37900, // -5 dBm + 39140, // -4 dBm + 40380, // -3 dBm + 42860, // -2 dBm + 45150, // -1 dBm + 47400, // 0 dBm + 49600, // 1 dBm + 52600, // 2 dBm + 54460, // 3 dBm + 57690, // 4 dBm + 59840, // 5 dBm + 62550, // 6 dBm + 65750, // 7 dBm + 68520, // 8 dBm + 72130, // 9 dBm + 75230, // 10 dBm + 78600, // 11 dBm + 82770, // 12 dBm + 87450, // 13 dBm + 91700, // 14 dBm + 95330, // 15 dBm + 97520, // 16 dBm + 99520, // 17 dBm + 102080, // 18 dBm + 105140, // 19 dBm + 109300, // 20 dBm + 114460, // 21 dBm + 116530, // 22 dBm +}; + +static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[] = { + 11800, // -18 dBm + 11800, // -17 dBm + 11800, // -16 dBm + 11900, // -15 dBm + 12020, // -14 dBm + 12120, // -13 dBm + 12230, // -12 dBm + 12390, // -11 dBm + 12540, // -10 dBm + 12740, // -9 dBm + 12960, // -8 dBm + 13150, // -7 dBm + 13460, // -6 dBm + 13770, // -5 dBm + 14070, // -4 dBm + 14460, // -3 dBm + 15030, // -2 dBm + 15440, // -1 dBm + 16030, // 0 dBm + 16980, // 1 dBm + 17590, // 2 dBm + 18270, // 3 dBm + 19060, // 4 dBm + 19900, // 5 dBm + 20740, // 6 dBm + 21610, // 7 dBm + 22400, // 8 dBm + 23370, // 9 dBm + 24860, // 10 dBm + 26410, // 11 dBm + 26430, // 12 dBm + 27890, // 13 dBm +}; /* * ----------------------------------------------------------------------------- @@ -252,8 +446,8 @@ void ral_lr11xx_bsp_get_rssi_calibration_table( const void* context, const uint3 } } -void ral_lr11xx_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_lr11xx_bsp_get_lora_cad_det_peak( const void *context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed } @@ -290,32 +484,32 @@ void lr11xx_get_tx_cfg( lr11xx_pa_type_t pa_type, int8_t expected_output_pwr_in_ case LR11XX_WITH_LF_LP_PA: { // Check power boundaries for LP LF PA: The output power must be in range [ -17 , +15 ] dBm - if( power < LR11XX_MIN_PWR_LP_LF ) + if( power < LR11XX_LP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_LP_LF; + power = LR11XX_LP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_LP_LF ) + else if( power > LR11XX_LP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_LP_LF; + power = LR11XX_LP_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_LP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].power; output_params->chip_output_pwr_in_dbm_expected = power; break; } case LR11XX_WITH_LF_HP_PA: { // Check power boundaries for HP LF PA: The output power must be in range [ -9 , +22 ] dBm - if( power < LR11XX_MIN_PWR_HP_LF ) + if( power < LR11XX_HP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_HP_LF; + power = LR11XX_HP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_HP_LF ) + else if( power > LR11XX_HP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_HP_LF; + power = LR11XX_HP_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HP; output_params->chip_output_pwr_in_dbm_expected = power; @@ -330,62 +524,214 @@ void lr11xx_get_tx_cfg( lr11xx_pa_type_t pa_type, int8_t expected_output_pwr_in_ output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT; } - output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].power; break; } case LR11XX_WITH_LF_LP_HP_PA: { // Check power boundaries for LP/HP LF PA: The output power must be in range [ -17 , +22 ] dBm - if( power < LR11XX_MIN_PWR_LP_LF ) + if( power < LR11XX_LP_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_LP_LF; + power = LR11XX_LP_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_HP_LF ) + else if( power > LR11XX_HP_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_HP_LF; + power = LR11XX_HP_MAX_OUTPUT_POWER; } output_params->chip_output_pwr_in_dbm_expected = power; - if( power <= LR11XX_MAX_PWR_LP_LF ) + if( power <= LR11XX_LP_MAX_OUTPUT_POWER ) { output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_LP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_MIN_PWR_LP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_lp_cfg_table[power - LR11XX_LP_MIN_OUTPUT_POWER].power; } else { output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HP; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT; - output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_MIN_PWR_HP_LF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hp_cfg_table[power - LR11XX_HP_MIN_OUTPUT_POWER].power; } break; } case LR11XX_WITH_HF_PA: { // Check power boundaries for HF PA: The output power must be in range [ -18 , +13 ] dBm - if( power < LR11XX_MIN_PWR_PA_HF ) + if( power < LR11XX_HF_MIN_OUTPUT_POWER ) { - power = LR11XX_MIN_PWR_PA_HF; + power = LR11XX_HF_MIN_OUTPUT_POWER; } - else if( power > LR11XX_MAX_PWR_PA_HF ) + else if( power > LR11XX_HF_MAX_OUTPUT_POWER ) { - power = LR11XX_MAX_PWR_PA_HF; + power = LR11XX_HF_MAX_OUTPUT_POWER; } output_params->pa_cfg.pa_sel = LR11XX_RADIO_PA_SEL_HF; output_params->pa_cfg.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG; - output_params->pa_cfg.pa_duty_cycle = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].pa_duty_cycle; - output_params->pa_cfg.pa_hp_sel = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].pa_hp_sel; - output_params->chip_output_pwr_in_dbm_configured = pa_hf_cfg_table[power - LR11XX_MIN_PWR_PA_HF].power; + output_params->pa_cfg.pa_duty_cycle = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].pa_duty_cycle; + output_params->pa_cfg.pa_hp_sel = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].pa_hp_sel; + output_params->chip_output_pwr_in_dbm_configured = pa_hf_cfg_table[power - LR11XX_HF_MIN_OUTPUT_POWER].power; output_params->chip_output_pwr_in_dbm_expected = power; break; } } } +ral_status_t ral_lr11xx_bsp_get_instantaneous_tx_power_consumption( const void *context, + const ral_lr11xx_bsp_tx_cfg_output_params_t* tx_cfg, + lr11xx_system_reg_mode_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_LP ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_LP_MAX_OUTPUT_POWER ) + { + index = LR11XX_LP_MAX_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_LP_MIN_OUTPUT_POWER ) + { + index = LR11XX_LP_MIN_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[index]; + } + else + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[index]; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HP ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VBAT ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_HP_MAX_OUTPUT_POWER ) + { + index = LR11XX_HP_MAX_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_HP_MIN_OUTPUT_POWER ) + { + index = LR11XX_HP_MIN_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[index]; + } + else + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[index]; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else if( tx_cfg->pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HF ) + { + if( tx_cfg->pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) + { + uint8_t index = 0; + + if( tx_cfg->chip_output_pwr_in_dbm_expected > LR11XX_HF_MAX_OUTPUT_POWER ) + { + index = LR11XX_HF_MAX_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg->chip_output_pwr_in_dbm_expected < LR11XX_HF_MIN_OUTPUT_POWER ) + { + index = LR11XX_HF_MIN_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg->chip_output_pwr_in_dbm_expected + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[index]; + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else + { + return RAL_STATUS_UNSUPPORTED_FEATURE; + } + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_lr11xx_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + lr11xx_system_reg_mode_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_GFSK_RX_CONSUMPTION_DCDC; + } + else + { + // TODO: find the good values + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_GFSK_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_lr11xx_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + lr11xx_system_reg_mode_t radio_reg_mode, + const bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_LORA_RX_CONSUMPTION_DCDC; + } + else + { + // TODO: find the good values + *pwr_consumption_in_ua = + ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_LORA_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_examples/radio_hal/ral_sx126x_bsp.c b/lbm_examples/radio_hal/ral_sx126x_bsp.c index 25b939f..34ea512 100644 --- a/lbm_examples/radio_hal/ral_sx126x_bsp.c +++ b/lbm_examples/radio_hal/ral_sx126x_bsp.c @@ -47,11 +47,175 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +#define SX126X_LP_MIN_OUTPUT_POWER -17 +#define SX126X_LP_MAX_OUTPUT_POWER 15 + +#define SX126X_HP_MIN_OUTPUT_POWER -9 +#define SX126X_HP_MAX_OUTPUT_POWER 22 + +#define SX126X_LP_CONVERT_TABLE_INDEX_OFFSET 17 +#define SX126X_HP_CONVERT_TABLE_INDEX_OFFSET 9 + +// TODO: check values +#define SX126X_GFSK_RX_CONSUMPTION_DCDC 4200 +#define SX126X_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 4800 + +#define SX126X_GFSK_RX_CONSUMPTION_LDO 8000 +#define SX126X_GFSK_RX_BOOSTED_CONSUMPTION_LDO 9300 + +#define SX126X_LORA_RX_CONSUMPTION_DCDC 4600 +#define SX126X_LORA_RX_BOOSTED_CONSUMPTION_DCDC 5300 + +#define SX126X_LORA_RX_CONSUMPTION_LDO 8880 +#define SX126X_LORA_RX_BOOSTED_CONSUMPTION_LDO 10100 + /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_lp[] = { + 5200, // -17 dBm + 5400, // -16 dBm + 5600, // -15 dBm + 5700, // -14 dBm + 5800, // -13 dBm + 6000, // -12 dBm + 6100, // -11 dBm + 6200, // -10 dBm + 6500, // -9 dBm + 6800, // -8 dBm + 7000, // -7 dBm + 7300, // -6 dBm + 7500, // -5 dBm + 7900, // -4 dBm + 8300, // -3 dBm + 8800, // -2 dBm + 9300, // -1 dBm + 9800, // 0 dBm + 10600, // 1 dBm + 11400, // 2 dBm + 12200, // 3 dBm + 12900, // 4 dBm + 13800, // 5 dBm + 14700, // 6 dBm + 15700, // 7 dBm + 16600, // 8 dBm + 17900, // 9 dBm + 18500, // 10 dBm + 20500, // 11 dBm + 21900, // 12 dBm + 23500, // 13 dBm + 25500, // 14 dBm + 32500, // 15 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_lp[] = { + 9800, // -17 dBm + 10300, // -16 dBm + 10500, // -15 dBm + 10800, // -14 dBm + 11100, // -13 dBm + 11300, // -12 dBm + 11600, // -11 dBm + 11900, // -10 dBm + 12400, // -9 dBm + 12900, // -8 dBm + 13400, // -7 dBm + 13900, // -6 dBm + 14500, // -5 dBm + 15300, // -4 dBm + 16000, // -3 dBm + 17000, // -2 dBm + 18000, // -1 dBm + 19000, // 0 dBm + 20600, // 1 dBm + 22000, // 2 dBm + 23500, // 3 dBm + 24900, // 4 dBm + 26600, // 5 dBm + 28400, // 6 dBm + 30200, // 7 dBm + 32000, // 8 dBm + 34300, // 9 dBm + 36600, // 10 dBm + 39200, // 11 dBm + 41700, // 12 dBm + 44700, // 13 dBm + 48200, // 14 dBm + 52200, // 15 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_hp[] = { + 24000, // -9 dBm + 25400, // -8 dBm + 26700, // -7 dBm + 28000, // -6 dBm + 30600, // -5 dBm + 31900, // -4 dBm + 33200, // -3 dBm + 35700, // -2 dBm + 38200, // -1 dBm + 40600, // 0 dBm + 42900, // 1 dBm + 46200, // 2 dBm + 48200, // 3 dBm + 51800, // 4 dBm + 54100, // 5 dBm + 57000, // 6 dBm + 60300, // 7 dBm + 63500, // 8 dBm + 67100, // 9 dBm + 70500, // 10 dBm + 74200, // 11 dBm + 78400, // 12 dBm + 83500, // 13 dBm + 89300, // 14 dBm + 92400, // 15 dBm + 94500, // 16 dBm + 95400, // 17 dBm + 97500, // 18 dBm + 100100, // 19 dBm + 103800, // 20 dBm + 109100, // 21 dBm + 117900, // 22 dBm +}; + +static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_hp[] = { + 25900, // -9 dBm + 27400, // -8 dBm + 28700, // -7 dBm + 30000, // -6 dBm + 32600, // -5 dBm + 33900, // -4 dBm + 35200, // -3 dBm + 37700, // -2 dBm + 40100, // -1 dBm + 42600, // 0 dBm + 44900, // 1 dBm + 48200, // 2 dBm + 50200, // 3 dBm + 53800, // 4 dBm + 56100, // 5 dBm + 59000, // 6 dBm + 62300, // 7 dBm + 65500, // 8 dBm + 69000, // 9 dBm + 72500, // 10 dBm + 76200, // 11 dBm + 80400, // 12 dBm + 85400, // 13 dBm + 90200, // 14 dBm + 94400, // 15 dBm + 96500, // 16 dBm + 97700, // 17 dBm + 99500, // 18 dBm + 102100, // 19 dBm + 105800, // 20 dBm + 111000, // 21 dBm + 119800, // 22 dBm +}; + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -172,10 +336,127 @@ void ral_sx126x_bsp_get_ocp_value( const void* context, uint8_t* ocp_in_step_of_ // Do nothing, let the driver choose the default values } -void ral_sx126x_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_sx126x_bsp_get_lora_cad_det_peak( const void* context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed + + // The DetPeak value set in the sx126x Radio Abstraction Layer is too close to the sensitivity for BW500 and SF>=9 + if( bw >= RAL_LORA_BW_500_KHZ ) + { + if( sf >= RAL_LORA_SF9 ) + { + *in_out_cad_det_peak += 11; + } + } +} + +ral_status_t ral_sx126x_bsp_get_instantaneous_tx_power_consumption( const void *context, + const ral_sx126x_bsp_tx_cfg_output_params_t* tx_cfg_output_params, sx126x_reg_mod_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + // SX1261 + if( tx_cfg_output_params->pa_cfg.device_sel == 0x01 ) + { + uint8_t index = 0; + + if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected > SX126X_LP_MAX_OUTPUT_POWER ) + { + index = SX126X_LP_MAX_OUTPUT_POWER + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected < SX126X_LP_MIN_OUTPUT_POWER ) + { + index = SX126X_LP_MIN_OUTPUT_POWER + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg_output_params->chip_output_pwr_in_dbm_expected + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_lp[index]; + } + else + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_lp[index]; + } + } + // SX1262 + else if( tx_cfg_output_params->pa_cfg.device_sel == 0x00 ) + { + uint8_t index = 0; + + if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected > SX126X_HP_MAX_OUTPUT_POWER ) + { + index = SX126X_HP_MAX_OUTPUT_POWER + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg_output_params->chip_output_pwr_in_dbm_expected < SX126X_HP_MIN_OUTPUT_POWER ) + { + index = SX126X_HP_MIN_OUTPUT_POWER + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg_output_params->chip_output_pwr_in_dbm_expected + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; + } + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_hp[index]; + } + else + { + *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_hp[index]; + } + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_sx126x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + sx126x_reg_mod_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + // TODO: find the br/bw dependent values + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : SX126X_GFSK_RX_CONSUMPTION_DCDC; + } + else + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_GFSK_RX_BOOSTED_CONSUMPTION_LDO : SX126X_GFSK_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_sx126x_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + sx126x_reg_mod_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + // TODO: find the bw dependent values + + if( radio_reg_mode == SX126X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_LORA_RX_BOOSTED_CONSUMPTION_DCDC : SX126X_LORA_RX_CONSUMPTION_DCDC; + } + else + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX126X_LORA_RX_BOOSTED_CONSUMPTION_LDO : SX126X_LORA_RX_CONSUMPTION_LDO; + } + + return RAL_STATUS_OK; } /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_examples/radio_hal/ral_sx127x_bsp.c b/lbm_examples/radio_hal/ral_sx127x_bsp.c index 0a5b2b0..6086496 100644 --- a/lbm_examples/radio_hal/ral_sx127x_bsp.c +++ b/lbm_examples/radio_hal/ral_sx127x_bsp.c @@ -3,11 +3,12 @@ * * \brief Implements the HAL functions for SX127X * - * Revised BSD License + * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* @@ -175,6 +178,26 @@ void ral_sx127x_bsp_get_ocp_value( const void* context, uint8_t* ocp_trim_value // Do nothing, let the driver choose the default values } +ral_status_t ral_sx127x_bsp_get_instantaneous_tx_power_consumption( const void *context, + const ral_sx127x_bsp_tx_cfg_output_params_t* tx_cfg_output_params, uint32_t* pwr_consumption_in_ua ) +{ + return RAL_STATUS_UNSUPPORTED_FEATURE; +} + +ral_status_t ral_sx127x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + return RAL_STATUS_UNSUPPORTED_FEATURE; +} + +ral_status_t ral_sx127x_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + return RAL_STATUS_UNSUPPORTED_FEATURE; +} + /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- diff --git a/lbm_examples/radio_hal/ral_sx128x_bsp.c b/lbm_examples/radio_hal/ral_sx128x_bsp.c index 575503f..161f251 100644 --- a/lbm_examples/radio_hal/ral_sx128x_bsp.c +++ b/lbm_examples/radio_hal/ral_sx128x_bsp.c @@ -48,11 +48,106 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ +#define SX128X_CONVERT_TABLE_INDEX_OFFSET 18 + +#define SX128X_LORA_RX_CONSUMPTION_BW_200_DCDC 5500 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_DCDC 6200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_400_DCDC 6000 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_DCDC 6700 + +#define SX128X_LORA_RX_CONSUMPTION_BW_800_DCDC 7000 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_DCDC 7700 + +#define SX128X_LORA_RX_CONSUMPTION_BW_1600_DCDC 7500 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_DCDC 8200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_200_LDO 10800 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_LDO 12200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_400_LDO 11800 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_LDO 13200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_800_LDO 13700 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_LDO 15200 + +#define SX128X_LORA_RX_CONSUMPTION_BW_1600_LDO 14800 +#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_LDO 16300 /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ +static const uint32_t ral_sx128x_convert_tx_dbm_to_ua_reg_mode_dcdc[] = { + 6200, // -18 dBm + 6300, // -17 dBm + 6400, // -16 dBm + 6500, // -15 dBm + 6600, // -14 dBm + 6700, // -13 dBm + 6800, // -12 dBm + 7000, // -11 dBm + 7100, // -10 dBm + 7300, // -9 dBm + 7400, // -8 dBm + 7700, // -7 dBm + 7900, // -6 dBm + 8100, // -5 dBm + 8500, // -4 dBm + 8800, // -3 dBm + 9200, // -2 dBm + 9700, // -1 dBm + 10100, // 0 dBm + 10700, // 1 dBm + 11300, // 2 dBm + 12000, // 3 dBm + 12700, // 4 dBm + 13600, // 5 dBm + 14500, // 6 dBm + 15500, // 7 dBm + 16800, // 8 dBm + 17700, // 9 dBm + 18600, // 10 dBm + 20300, // 11 dBm + 22000, // 12 dBm + 24000, // 13 dBm +}; + +static const uint32_t ral_sx128x_convert_tx_dbm_to_ua_reg_mode_ldo[] = { + 11800, // -18 dBm + 12000, // -17 dBm + 12200, // -16 dBm + 12400, // -15 dBm + 12600, // -14 dBm + 12800, // -13 dBm + 13000, // -12 dBm + 13300, // -11 dBm + 13500, // -10 dBm + 14000, // -9 dBm + 14200, // -8 dBm + 14700, // -7 dBm + 15200, // -6 dBm + 15600, // -5 dBm + 16300, // -4 dBm + 17000, // -3 dBm + 17700, // -2 dBm + 18600, // -1 dBm + 19600, // 0 dBm + 20700, // 1 dBm + 21900, // 2 dBm + 23200, // 3 dBm + 24600, // 4 dBm + 26300, // 5 dBm + 28000, // 6 dBm + 30000, // 7 dBm + 32200, // 8 dBm + 34500, // 9 dBm + 36800, // 10 dBm + 39200, // 11 dBm + 41900, // 12 dBm + 45500, // 13 dBm +}; + /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -104,8 +199,134 @@ void ral_sx128x_bsp_get_tx_cfg( const void* context, const ral_sx128x_bsp_tx_cfg output_params->pa_ramp_time = SX128X_RAMP_20_US; } -void ral_sx128x_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ) +void ral_sx128x_bsp_get_lora_cad_det_peak( const void *context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ) { // Function used to fine tune the cad detection peak, update if needed -} \ No newline at end of file +} + +ral_status_t ral_sx128x_bsp_get_instantaneous_tx_power_consumption( const void *context, + ral_sx128x_bsp_tx_cfg_output_params_t tx_cfg_output_params_local, sx128x_reg_mod_t reg_mode, + uint32_t* pwr_consumption_in_ua ) +{ + const ral_sx128x_bsp_tx_cfg_output_params_t tx_cfg_output_params = tx_cfg_output_params_local; + uint8_t index = 0; + + if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected > SX128X_PWR_MAX ) + { + index = SX128X_PWR_MAX + SX128X_CONVERT_TABLE_INDEX_OFFSET; + } + else if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected < SX128X_PWR_MIN ) + { + index = SX128X_PWR_MIN + SX128X_CONVERT_TABLE_INDEX_OFFSET; + } + else + { + index = tx_cfg_output_params.chip_output_pwr_in_dbm_expected + SX128X_CONVERT_TABLE_INDEX_OFFSET; + } + + if( reg_mode == SX128X_REG_MODE_DCDC ) + { + *pwr_consumption_in_ua = ral_sx128x_convert_tx_dbm_to_ua_reg_mode_dcdc[index]; + } + else if( reg_mode == SX128X_REG_MODE_LDO ) + { + *pwr_consumption_in_ua = ral_sx128x_convert_tx_dbm_to_ua_reg_mode_ldo[index]; + } + else + { + return RAL_STATUS_UNKNOWN_VALUE; + } + + return RAL_STATUS_OK; +} + +ral_status_t ral_sx128x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void *context, + sx128x_reg_mod_t radio_reg_mode, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + return RAL_STATUS_UNSUPPORTED_FEATURE; +} + +ral_status_t ral_sx128x_bsp_get_instantaneous_lora_rx_power_consumption( const void *context, + sx128x_reg_mod_t reg_mode, ral_lora_bw_t bw, + bool rx_boosted, + uint32_t* pwr_consumption_in_ua ) +{ + switch( reg_mode ) + { + case SX128X_REG_MODE_DCDC: + { + switch( bw ) + { + case RAL_LORA_BW_200_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_DCDC + : SX128X_LORA_RX_CONSUMPTION_BW_200_DCDC; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_400_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_DCDC + : SX128X_LORA_RX_CONSUMPTION_BW_400_DCDC; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_800_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_DCDC + : SX128X_LORA_RX_CONSUMPTION_BW_800_DCDC; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_1600_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_DCDC + : SX128X_LORA_RX_CONSUMPTION_BW_1600_DCDC; + return RAL_STATUS_OK; + } + default: + return RAL_STATUS_UNKNOWN_VALUE; + } + break; + } + case SX128X_REG_MODE_LDO: + { + switch( bw ) + { + case RAL_LORA_BW_200_KHZ: + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_LDO : SX128X_LORA_RX_CONSUMPTION_BW_200_LDO; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_400_KHZ: + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_LDO : SX128X_LORA_RX_CONSUMPTION_BW_400_LDO; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_800_KHZ: + { + *pwr_consumption_in_ua = + ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_LDO : SX128X_LORA_RX_CONSUMPTION_BW_800_LDO; + return RAL_STATUS_OK; + } + case RAL_LORA_BW_1600_KHZ: + { + *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_LDO + : SX128X_LORA_RX_CONSUMPTION_BW_1600_LDO; + return RAL_STATUS_OK; + } + default: + { + return RAL_STATUS_UNKNOWN_VALUE; + } + } + break; + } + default: + { + return RAL_STATUS_UNKNOWN_VALUE; + } + } +} diff --git a/lbm_examples/radio_hal/sx127x_hal.c b/lbm_examples/radio_hal/sx127x_hal.c index 960d3dd..fa88c2a 100644 --- a/lbm_examples/radio_hal/sx127x_hal.c +++ b/lbm_examples/radio_hal/sx127x_hal.c @@ -3,11 +3,12 @@ * * \brief Implements the sx127x radio HAL functions * - * Revised BSD License + * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* diff --git a/lbm_examples/smtc_hal_l0_LL/smtc_hal_dbg_trace.h b/lbm_examples/smtc_hal_l0_LL/smtc_hal_dbg_trace.h index 19e304c..00b7435 100644 --- a/lbm_examples/smtc_hal_l0_LL/smtc_hal_dbg_trace.h +++ b/lbm_examples/smtc_hal_l0_LL/smtc_hal_dbg_trace.h @@ -51,7 +51,7 @@ extern "C" { * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define HAL_FEATURE_OFF 0 #define HAL_FEATURE_ON !HAL_FEATURE_OFF @@ -67,14 +67,14 @@ extern "C" { #ifndef HAL_DBG_TRACE_RP #define HAL_DBG_TRACE_RP HAL_FEATURE_OFF #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #if ( HAL_DBG_TRACE_COLOR == HAL_FEATURE_ON ) #define HAL_DBG_TRACE_COLOR_BLACK "\x1B[0;30m" #define HAL_DBG_TRACE_COLOR_RED "\x1B[0;31m" @@ -170,7 +170,7 @@ extern "C" { #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_examples/smtc_hal_l0_LL/smtc_hal_rtc.c b/lbm_examples/smtc_hal_l0_LL/smtc_hal_rtc.c index b741a64..b2a778d 100644 --- a/lbm_examples/smtc_hal_l0_LL/smtc_hal_rtc.c +++ b/lbm_examples/smtc_hal_l0_LL/smtc_hal_rtc.c @@ -54,14 +54,14 @@ /*! * Calculates ceiling( X / N ) */ -#define DIVC( X, N ) ( ( ( X ) + ( N ) -1 ) / ( N ) ) +#define DIVC( X, N ) ( ( ( X ) + ( N ) - 1 ) / ( N ) ) /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -// clang-format off +/* clang-format off */ // MCU Wake Up Time #define MIN_ALARM_DELAY_IN_TICKS 3U // in ticks @@ -117,7 +117,7 @@ RTC_TR_MNT | RTC_TR_MNU| RTC_TR_ST | \ RTC_TR_SU)) -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- @@ -133,7 +133,7 @@ static uint32_t offset_to_test_wrapping = 0; * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -static uint32_t rtc_get_offset_to_test_wrapping (void); +static uint32_t rtc_get_offset_to_test_wrapping( void ); /*! * Converts time in ms to time in wake up timer ticks * Assuming WUCKSEL[2:0] = 000: RTCCLK/16 clock is selected @@ -304,7 +304,8 @@ static uint32_t rtc_get_calendar_time( uint16_t* milliseconds_div_10 ) { uint32_t ticks; - uint64_t timestamp_in_ticks = rtc_get_timestamp_in_ticks( ) + ( uint64_t) ((( uint64_t)rtc_get_offset_to_test_wrapping()) << N_PREDIV_S ); + uint64_t timestamp_in_ticks = rtc_get_timestamp_in_ticks( ) + + ( uint64_t ) ( ( ( uint64_t ) rtc_get_offset_to_test_wrapping( ) ) << N_PREDIV_S ); uint32_t seconds = ( uint32_t ) ( timestamp_in_ticks >> N_PREDIV_S ); @@ -382,8 +383,8 @@ void RTC_IRQHandler( void ) LL_EXTI_ClearFlag_0_31( LL_EXTI_LINE_20 ); } } -static uint32_t rtc_get_offset_to_test_wrapping (void) +static uint32_t rtc_get_offset_to_test_wrapping( void ) { - return offset_to_test_wrapping ; + return offset_to_test_wrapping; } /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_examples/smtc_hal_l4/smtc_hal_dbg_trace.h b/lbm_examples/smtc_hal_l4/smtc_hal_dbg_trace.h index f2b42ed..ca027d8 100644 --- a/lbm_examples/smtc_hal_l4/smtc_hal_dbg_trace.h +++ b/lbm_examples/smtc_hal_l4/smtc_hal_dbg_trace.h @@ -51,7 +51,7 @@ extern "C" { * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define HAL_FEATURE_OFF 0 #define HAL_FEATURE_ON !HAL_FEATURE_OFF @@ -67,14 +67,14 @@ extern "C" { #ifndef HAL_DBG_TRACE_RP #define HAL_DBG_TRACE_RP HAL_FEATURE_OFF #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #if ( HAL_DBG_TRACE_COLOR == HAL_FEATURE_ON ) #define HAL_DBG_TRACE_COLOR_BLACK "\x1B[0;30m" #define HAL_DBG_TRACE_COLOR_RED "\x1B[0;31m" @@ -170,7 +170,7 @@ extern "C" { #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_examples/smtc_hal_l4/smtc_hal_rtc.c b/lbm_examples/smtc_hal_l4/smtc_hal_rtc.c index 0f1e77b..7687f29 100644 --- a/lbm_examples/smtc_hal_l4/smtc_hal_rtc.c +++ b/lbm_examples/smtc_hal_l4/smtc_hal_rtc.c @@ -52,14 +52,14 @@ /*! * Calculates ceiling( X / N ) */ -#define DIVC( X, N ) ( ( ( X ) + ( N ) -1 ) / ( N ) ) +#define DIVC( X, N ) ( ( ( X ) + ( N ) - 1 ) / ( N ) ) /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -// clang-format off +/* clang-format off */ // MCU Wake Up Time #define MIN_ALARM_DELAY_IN_TICKS 3U // in ticks @@ -101,7 +101,7 @@ #define DAYS_IN_MONTH_CORRECTION_NORM ( ( uint32_t ) 0x99AAA0 ) #define DAYS_IN_MONTH_CORRECTION_LEAP ( ( uint32_t ) 0x445550 ) -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- @@ -114,7 +114,7 @@ */ static RTC_HandleTypeDef hal_rtc_handle; -static uint32_t offset_to_test_wrapping = 0; +static uint32_t offset_to_test_wrapping = 0; /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- @@ -156,9 +156,9 @@ static uint64_t rtc_get_timestamp_in_ticks( void ); /*! * Get current offset * - * + * */ -static uint32_t rtc_get_offset_to_test_wrapping (void); +static uint32_t rtc_get_offset_to_test_wrapping( void ); /* * ----------------------------------------------------------------------------- * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- @@ -263,8 +263,9 @@ static uint32_t rtc_ms_2_wakeup_timer_tick( const uint32_t milliseconds ) static uint32_t rtc_get_calendar_time( uint16_t* milliseconds_div_10 ) { uint32_t ticks; - - uint64_t timestamp_in_ticks = rtc_get_timestamp_in_ticks( ) + ( uint64_t) ((( uint64_t)rtc_get_offset_to_test_wrapping()) << N_PREDIV_S ); + + uint64_t timestamp_in_ticks = rtc_get_timestamp_in_ticks( ) + + ( uint64_t ) ( ( ( uint64_t ) rtc_get_offset_to_test_wrapping( ) ) << N_PREDIV_S ); uint32_t seconds = ( uint32_t ) ( timestamp_in_ticks >> N_PREDIV_S ); @@ -332,9 +333,9 @@ void HAL_RTC_MspDeInit( RTC_HandleTypeDef* rtc_handle ) __HAL_RCC_RTC_DISABLE( ); HAL_NVIC_DisableIRQ( RTC_WKUP_IRQn ); } -static uint32_t rtc_get_offset_to_test_wrapping (void) +static uint32_t rtc_get_offset_to_test_wrapping( void ) { - return offset_to_test_wrapping ; + return offset_to_test_wrapping; } /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_examples/smtc_modem_hal/smtc_modem_hal.c b/lbm_examples/smtc_modem_hal/smtc_modem_hal.c index d9f9f04..c89e4d1 100644 --- a/lbm_examples/smtc_modem_hal/smtc_modem_hal.c +++ b/lbm_examples/smtc_modem_hal/smtc_modem_hal.c @@ -166,7 +166,7 @@ void smtc_modem_hal_set_offset_to_test_wrapping( const uint32_t offset_to_test_w void smtc_modem_hal_start_timer( const uint32_t milliseconds, void ( *callback )( void* context ), void* context ) { hal_lp_timer_start( HAL_LP_TIMER_ID_1, milliseconds, - &( hal_lp_timer_irq_t ){ .context = context, .callback = callback } ); + &( hal_lp_timer_irq_t ) { .context = context, .callback = callback } ); } void smtc_modem_hal_stop_timer( void ) @@ -180,7 +180,7 @@ void smtc_modem_hal_disable_modem_irq( void ) { hal_gpio_irq_disable( ); hal_lp_timer_irq_disable( HAL_LP_TIMER_ID_1 ); -#if( SX127X ) +#if ( SX127X ) hal_lp_timer_irq_disable( HAL_LP_TIMER_ID_2 ); #endif } @@ -189,7 +189,7 @@ void smtc_modem_hal_enable_modem_irq( void ) { hal_gpio_irq_enable( ); hal_lp_timer_irq_enable( HAL_LP_TIMER_ID_1 ); -#if( SX127X ) +#if ( SX127X ) hal_lp_timer_irq_enable( HAL_LP_TIMER_ID_2 ); #endif } @@ -351,9 +351,11 @@ void smtc_modem_hal_crashlog_set_status( bool available ) crashlog_available_noinit = available; } -bool smtc_modem_hal_crashlog_get_status( void ) +static volatile bool temp = 0x1; // solve new behaviour introduce with gcc11 compilo +bool smtc_modem_hal_crashlog_get_status( void ) { - return crashlog_available_noinit; + bool temp2 = crashlog_available_noinit & temp; + return temp2; } /* ------------ assert management ------------*/ @@ -398,17 +400,6 @@ void smtc_modem_hal_irq_config_radio_irq( void ( *callback )( void* context ), v #endif } -void smtc_modem_hal_radio_irq_clear_pending( void ) -{ -#if defined( SX127X ) - hal_gpio_clear_pending_irq( RADIO_DIO_0 ); - hal_gpio_clear_pending_irq( RADIO_DIO_1 ); - hal_gpio_clear_pending_irq( RADIO_DIO_2 ); -#else - hal_gpio_clear_pending_irq( RADIO_DIOX ); -#endif -} - void smtc_modem_hal_start_radio_tcxo( void ) { // put here the code that will start the tcxo if needed diff --git a/lbm_lib/Makefile b/lbm_lib/Makefile index 3756a2a..d76c8a3 100644 --- a/lbm_lib/Makefile +++ b/lbm_lib/Makefile @@ -57,6 +57,8 @@ help: $(call echo_help, " * LBM_DEVICE_MANAGEMENT=yes/no : choose to build Cloud Device Management service (default: no)") $(call echo_help, " * LBM_GEOLOCATION=yes/no : choose to build Geolocation service (default: no)") $(call echo_help, " * LBM_STORE_AND_FORWARD=yes/no : choose to build Store and Forward service (default: no)") + $(call echo_help, " * LBM_RELAY_TX_ENABLE=yes/no : choose to build Relay Tx service (default: no)") + $(call echo_help, " * LBM_RELAY_RX_ENABLE=yes/no : choose to build Relay Rx service (default: no)") $(call echo_help, "") $(call echo_help_b, "-------------------- Optional makefile parameters --------------------------") $(call echo_help, " * EXTRAFLAGS=xxx : Add specific compilation flag for LBM lib build") @@ -161,9 +163,16 @@ ifeq ($(RADIO),nc) $(call echo_error,"No radio selected! Please specified the target radio using RADIO=radio_name option") else ifneq ($(CRYPTO),SOFT) -ifeq ($(RELAY_TX_ENABLE),yes) +ifeq ($(LBM_RELAY_TX_ENABLE),yes) $(call echo_error, "------------------------------------------------------------") - $(call echo_error, "When relay feature is enable: only soft crypto can be used") + $(call echo_error, "When Relay Tx feature is enable: only soft crypto can be used") + $(call echo_error, "Please use CRYPTO=SOFT option") + $(call echo_error, "------------------------------------------------------------") + exit 1 +endif +ifeq ($(LBM_RELAY_RX_ENABLE),yes) + $(call echo_error, "------------------------------------------------------------") + $(call echo_error, "When Relay Rx feature is enable: only soft crypto can be used") $(call echo_error, "Please use CRYPTO=SOFT option") $(call echo_error, "------------------------------------------------------------") exit 1 diff --git a/lbm_lib/PORTING_GUIDE.md b/lbm_lib/PORTING_GUIDE.md index 7107e41..877bcd4 100644 --- a/lbm_lib/PORTING_GUIDE.md +++ b/lbm_lib/PORTING_GUIDE.md @@ -3,6 +3,7 @@ ## MCU Requirements LoRa Basics Modem contains a example code for the STMicroelectronics STM32L476 Nucleo board, however, it can be easily ported to other MCUs. The following MCU features are required: + - 32-bit native operation (No specific CPU core needed) - Memory : Minimum 40KB of FLASH memory allowing an end-device to run in Class A mode for a single region; each additional region adds 1.5KB. - Little-endian @@ -35,36 +36,40 @@ The system interrupt priorities must be configured in such a way that the timer Therefore, when designing hardware that will run LoRa Basics Modem, it is recommended that the MCU GPIO lines selected for the transceiver's DIO interrupt request line do not share an MCU interrupt flag with other timing-critical hardware. If MCU interrupt flags are shared, it may not always be possible to react immediately to interrupts originating from these other devices. -No radio operations over the transceiver SPI bus are perfomed during timer and radio interrupt service routines. +No radio operations over the transceiver SPI bus are performed during timer and radio interrupt service routines. ## Radio Driver HAL Implementation The LoRa Basics Modem depends on Semtech's radio driver, which, in turn, requires a radio driver HAL implementation. A brief description of the necessary steps for this implementation follows. -The HAL implementation must provide platform-specific read, write, reset, and wakeup implementations. -* Radio driver API functions call the HAL implementation to perform the actual reset, wake, and communication operations needed by the driver. -* For the `LR11xx`, these functions are documented in [lr11xx_hal.h](smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_hal.h). -* For the `SX126x`, these functions are documented in [sx126x_hal.h](smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x_hal.h). -* For the `SX128x`, these functions are documented in [sx128x_hal.h](smtc_modem_core/radio_drivers/sx128x_driver/src/sx128x_hal.h). -* For the `SX127x`, these functions are documented in [sx127x_hal.h](smtc_modem_core/radio_drivers/sx127x_driver/src/sx127x_hal.h). +The HAL implementation must provide platform-specific read, write, reset, and wake-up implementations. + +- Radio driver API functions call the HAL implementation to perform the actual reset, wake, and communication operations needed by the driver. +- For the `LR11xx`, these functions are documented in [lr11xx_hal.h](smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_hal.h). +- For the `SX126x`, these functions are documented in [sx126x_hal.h](smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x_hal.h). +- For the `SX128x`, these functions are documented in [sx128x_hal.h](smtc_modem_core/radio_drivers/sx128x_driver/src/sx128x_hal.h). +- For the `SX127x`, these functions are documented in [sx127x_hal.h](smtc_modem_core/radio_drivers/sx127x_driver/src/sx127x_hal.h). All radio driver API functions take a 'const void* context' argument: -* This argument is opaque to both the radio driver and LoRa Basics Modem. -* It may be used by the HAL implementer to differentiate between different transceivers, which makes it easy to communicate with several radios inside the same application. -* Driver API functions do not use the context argument but pass it directly to the HAL implementation. + +- This argument is opaque to both the radio driver and LoRa Basics Modem. +- It may be used by the HAL implementer to differentiate between different transceivers, which makes it easy to communicate with several radios inside the same application. +- Driver API functions do not use the context argument but pass it directly to the HAL implementation. The LoRa Basics Modem imposes a specific requirement on the radio driver HAL implementation: -* If a radio driver API function is called while the transceiver is in sleep mode, the HAL implementation must properly wake the transceiver and wait until it is ready before initiating any SPI communication. -* This typically requires that the HAL keeps track of whether the radio is awake or asleep, potentially by monitoring any commands sent to the transceiver to detect the SetSleep command. -* For a concrete LR11xx example, see the file: [lr11xx_hal.c](../lbm_examples/radio_hal/lr11xx_hal.c). -* For a concrete SX126x example, see the file: [sx126x_hal.c](../lbm_examples/radio_hal/sx126x_hal.c). -* For a concrete SX128x example, see the file: [sx128x_hal.c](../lbm_examples/radio_hal/sx128x_hal.c). -* For a concrete SX127x example, see the file: [sx127x_hal.c](../lbm_examples/radio_hal/sx127x_hal.c). + +- If a radio driver API function is called while the transceiver is in sleep mode, the HAL implementation must properly wake the transceiver and wait until it is ready before initiating any SPI communication. +- This typically requires that the HAL keeps track of whether the radio is awake or asleep, potentially by monitoring any commands sent to the transceiver to detect the SetSleep command. +- For a concrete LR11xx example, see the file: [lr11xx_hal.c](../lbm_examples/radio_hal/lr11xx_hal.c). +- For a concrete SX126x example, see the file: [sx126x_hal.c](../lbm_examples/radio_hal/sx126x_hal.c). +- For a concrete SX128x example, see the file: [sx128x_hal.c](../lbm_examples/radio_hal/sx128x_hal.c). +- For a concrete SX127x example, see the file: [sx127x_hal.c](../lbm_examples/radio_hal/sx127x_hal.c). When compiling the radio driver HAL implementation, it is necessary to add the radio driver source directory to the include path. For example, for LR11xx: -* `lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src` + +- `lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src` ## RAL BSP Implementation @@ -73,30 +78,34 @@ A brief description of the necessary steps follows. The RAL provides radio-independent API functions that are similar to those provided by each radio driver. The RAL, and a complementary layer called the RALF, are described in the following header functions: -* [ral.h](smtc_modem_core/smtc_ral/src/ral.h) -* [ralf.h](smtc_modem_core/smtc_ralf/src/ralf.h) + +- [ral.h](smtc_modem_core/smtc_ral/src/ral.h) +- [ralf.h](smtc_modem_core/smtc_ralf/src/ralf.h) The RAL requires the implementer to define a few BSP API functions for the selected transceiver, by providing platform or radio-specific information to the RAL. -* For the `LR11xx`, these functions are described in [ral_lr11xx_bsp.h](smtc_modem_core/smtc_ral/src/ral_lr11xx_bsp.h). -* For the `SX126x`, these functions are described in [ral_sx126x_bsp.h](smtc_modem_core/smtc_ral/src/ral_sx126x_bsp.h). -* For the `SX128x`, these functions are described in [ral_sx128x_bsp.h](smtc_modem_core/smtc_ral/src/ral_sx128x_bsp.h). -* For the `SX127x`, these functions are described in [ral_sx127x_bsp.h](smtc_modem_core/smtc_ral/src/ral_sx127x_bsp.h). -* An LR11xx sample implementation is in the file [ral_lr11xx_bsp.c](../lbm_examples/radio_hal/ral_lr11xx_bsp.c). -* An SX126x sample implementation is in the file [ral_sx126x_bsp.c](../lbm_examples/radio_hal/ral_sx126x_bsp.c). -* An SX128x sample implementation is in the file [ral_sx128x_bsp.c](../lbm_examples/radio_hal/ral_sx128x_bsp.c). -* An SX127x sample implementation is in the file [ral_sx127x_bsp.c](../lbm_examples/radio_hal/ral_sx127x_bsp.c). +- For the `LR11xx`, these functions are described in [ral_lr11xx_bsp.h](smtc_modem_core/smtc_ral/src/ral_lr11xx_bsp.h). +- For the `SX126x`, these functions are described in [ral_sx126x_bsp.h](smtc_modem_core/smtc_ral/src/ral_sx126x_bsp.h). +- For the `SX128x`, these functions are described in [ral_sx128x_bsp.h](smtc_modem_core/smtc_ral/src/ral_sx128x_bsp.h). +- For the `SX127x`, these functions are described in [ral_sx127x_bsp.h](smtc_modem_core/smtc_ral/src/ral_sx127x_bsp.h). + +- An LR11xx sample implementation is in the file [ral_lr11xx_bsp.c](../lbm_examples/radio_hal/ral_lr11xx_bsp.c). +- An SX126x sample implementation is in the file [ral_sx126x_bsp.c](../lbm_examples/radio_hal/ral_sx126x_bsp.c). +- An SX128x sample implementation is in the file [ral_sx128x_bsp.c](../lbm_examples/radio_hal/ral_sx128x_bsp.c). +- An SX127x sample implementation is in the file [ral_sx127x_bsp.c](../lbm_examples/radio_hal/ral_sx127x_bsp.c). The role of the 'const void* context' variable is described in previous section. It is typically used to store radio-specific information, but depending on the radio driver BSP implementation, it may be NULL if a single transceiver is used. When compiling the RAL BSP implementation, it is necessary to add the radio driver source directory and the RAL source directory to the include path. For example, for LR11xx: -* `lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src` -* `lbm_lib/smtc_modem_core/smtc_ral/src` + +- `lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src` +- `lbm_lib/smtc_modem_core/smtc_ral/src` ## LoRa Basics Modem HAL Implementation Porting LoRa Basics Modem to a new MCU architecture requires implementing the modem Hardware Abstraction Layer (HAL) API commands described by the prototypes in the header file [smtc_modem_hal.h](smtc_modem_hal/smtc_modem_hal.h). Among other things, these API implementations define how timing information is provided to the LoRa Basics Modem, how random numbers are generated, and how data is stored in non-volatile memory. If a TCXO is used on the radio part, its startup timing behavior should be specified in the RAL BSP implementation, and the documentation of the smtc_modem_hal_start_radio_tcxo(), smtc_modem_hal_stop_radio_tcxo(), and smtc_modem_hal_get_radio_tcxo_startup_delay_ms() functions, should be consulted. +Logging macros are defined in [smtc_modem_hal_dbg_trace.h](smtc_modem_core/logging/smtc_modem_hal_dbg_trace.h). In case the OS has a macro-based logging implementation, the HAL can provide its own header, by removing the `logging` directory from the include list. An example of implementation on STM32L476 and STM32L073 can be found in [smtc_modem_hal.c](../lbm_examples/smtc_modem_hal/smtc_modem_hal.c) @@ -108,10 +117,11 @@ The following sections provide the list and more details on the different modem **Brief**: Reset the MCU. -LoRa Basics Modem may need to reset the MCU during LoRaWAN certification process or in case Device Managament service is used and cloud is asking for a device reset. -Recommandation is also to reset the mcu in case of modem_panic (in `smtc_modem_hal_on_panic()`) +LoRa Basics Modem may need to reset the MCU during LoRaWAN certification process or in case Device Management service is used and cloud is asking for a device reset. + +Recommendation is also to reset the mcu in case of modem_panic (in `smtc_modem_hal_on_panic()`) -### Watchdog related functions +### Watchdog related functions #### `void smtc_modem_hal_reload_wdog( void )` @@ -119,11 +129,11 @@ Recommandation is also to reset the mcu in case of modem_panic (in `smtc_modem_h If the HAL implementation configures a watchdog timer, then this function should be implemented to reload the watchdog timer. Currently, the only code in LoRa Basics Modem that calls this HAL API command is the test code in smtc_modem_test.c. -### Time management related functions +### Time management related functions #### `uint32_t smtc_modem_hal_get_time_in_s( void )` -**Brief**: +**Brief**: Provide the time since startup, in seconds. LoRa Basics Modem uses this command to help perform various LoRaWAN® activities that do not have significant time accuracy requirements, such as NbTrans retransmissions. **Return**: @@ -131,7 +141,7 @@ The current system uptime in seconds. #### `uint32_t smtc_modem_hal_get_time_in_ms( void )` -**Brief**: +**Brief**: Provide the time since startup, in milliseconds. **Return**: The system uptime, in milliseconds. The value returned by this function must monotonically increase all the way to 0xFFFFFFFF and then overflow to 0x00000000. @@ -144,16 +154,17 @@ This command is used for Class B ping slot openings. **Return**: The system uptime, in tenths of milliseconds. The value returned by this function must monotonically increase all the way to 0xFFFFFFFF, and then overflow to 0x00000000. -### Timer management related functions +### Timer management related functions #### `void smtc_modem_hal_start_timer( const uint32_t milliseconds, void ( *callback )( void* context ), void* context )` -**Brief**: +**Brief**: Start a timer that will expire at the requested time. Upon expiration, the provided callback is called with context as its sole argument. -The current design of the LoRa Basics Modem has only been tested in the case where the provided callback is executed in an interrupt context, with interrupts disabled. +The current design of the LoRa Basics Modem has only been tested in the case where the provided callback is executed in an interrupt context, with interrupts disabled. **Parameters**: + | | | | |--- |--- |--- | |[in]|milliseconds|Number of milliseconds before callback execution| @@ -165,7 +176,7 @@ The current design of the LoRa Basics Modem has only been tested in the case whe **Brief**: Stop the timer that may have been started with `smtc_modem_hal_start_timer()` -### IRQ management related functions +### IRQ management related functions #### `void smtc_modem_hal_disable_modem_irq( void )` @@ -179,7 +190,7 @@ Please also refer to System Design Considerations. Enable the two interrupt sources that execute the LoRa Basics Modem code: the timer, and the transceiver DIO interrupt source. Please also refer to System Design Considerations. -### Context saving management related functions +### Context saving management related functions #### `void smtc_modem_hal_context_restore( const modem_context_type_t ctx_type, uint32_t offset, uint8_t* buffer, const uint32_t size )` @@ -187,6 +198,7 @@ Please also refer to System Design Considerations. Restore to RAM a data structure of type `ctx_type` that has previously been stored in non-volatile memory by calling `smtc_modem_hal_context_store()`. **Parameters**: + | | | | |--- |--- |--- | |[in]|ctx_type|Type of modem context to be restored| @@ -198,7 +210,8 @@ Restore to RAM a data structure of type `ctx_type` that has previously been stor **Brief**: Store a data structure of type `ctx_type` from RAM to non-volatile memory. -**Details of each type of context**: +**Details of each type of context**: + |Context type|Size in bytes|Purpose| |--- |--- |--- | |CONTEXT_MODEM|16|To save general info of modem, eg reset| @@ -209,6 +222,7 @@ Store a data structure of type `ctx_type` from RAM to non-volatile memory. |CONTEXT_STORE_AND_FORWARD|variable|To save data for store and forward| **Parameters**: + | | | | |--- |--- |--- | |[in]|ctx_type|Type of modem context to be saved| @@ -222,13 +236,14 @@ Erase a chosen number of flash pages of a context. This function is only used for Store and Forward service with `ctx_type` parameter set to `CONTEXT_STORE_AND_FORWARD` **Parameters**: + | | | | |--- |--- |--- | |[in]|ctx_type|Type of modem context that need to be erased| |[in]|offset|Memory offset after ctx_type address| |[in]|nb_page|Number of pages that| -### Panic management related functions +### Panic management related functions #### `void smtc_modem_hal_on_panic( uint8_t* func, uint32_t line, const char* fmt, ... )` @@ -237,6 +252,7 @@ Action to be taken in case on modem panic. In case Device Management is used, it is recommended to perform the crashlog storage and status update in this function **Parameters**: + | | | | |--- |--- |--- | |[in]|func|The name of the function where the panic occurs| @@ -244,7 +260,7 @@ In case Device Management is used, it is recommended to perform the crashlog sto |[in]|fmt|String Format| |[in]|...|String Arguments| -### Random management related functions +### Random management related functions #### `uint32_t smtc_modem_hal_get_random_nb_in_range( const uint32_t val_1, const uint32_t val_2 )` @@ -254,12 +270,13 @@ Return a uniformly-distributed unsigned random integer from the closed interval The random integer. **Parameters**: + | | | | |--- |--- |--- | |[in]|val_1|first range unsigned value| |[in]|val_2|second range unsigned value| -### Radio environment management related functions +### Radio environment management related functions #### `void smtc_modem_hal_irq_config_radio_irq( void ( *callback )( void* context ), void* context )` @@ -267,23 +284,17 @@ The random integer. Store the callback and context argument that must be executed when a radio event occurs. **Parameters**: + | | | | |--- |--- |--- | |[in]|callback|Callback that is executed upon radio interrupt service request| |[in]|context|Argument that is provided to callback| - -#### `void smtc_modem_hal_radio_irq_clear_pending( void )` - -**Brief**: -Clear interrupt pending status, if an interrupt service request is pending inside the MCU hardware interrupt controller or stored as a flag in software. -After this function is called, the HAL implementation must guarantee that an interrupt that was raised before this function was called, will not be processed by the callback provided to the API function `smtc_modem_hal_irq_config_radio_irq()`. - #### `void smtc_modem_hal_start_radio_tcxo( void )` **Brief**: If the TCXO is not controlled by the transceiver, powers up the TCXO. -If no TCXO is used, or if the TCXO has been configured in the RAL BSP to start up automatically, then implement an empty command. If the TCXO is not controlled by the transceiver, then this function must power up the TCXO, and then busywait until the TCXO is running with the proper accuracy. +If no TCXO is used, or if the TCXO has been configured in the RAL BSP to start up automatically, then implement an empty command. If the TCXO is not controlled by the transceiver, then this function must power up the TCXO, and then busy wait until the TCXO is running with the proper accuracy. #### `void smtc_modem_hal_stop_radio_tcxo( void )` @@ -306,13 +317,14 @@ The needed TCXO startup time, in milliseconds. Return 0 if no TCXO is used. Set antenna switch for Tx operation or not. If no antenna switch is used then implement an empty command. -### Environment management related functions +### Environment management related functions #### `uint8_t smtc_modem_hal_get_battery_level( void )` **Brief**: Indicate the current battery state. According to LoRaWan 1.0.4 spec: + - 0: The end-device is connected to an external power source. - 1..254: Battery level, where 1 is the minimum and 254 is the maximum. - 255: The end-device was not able to measure the battery level. @@ -327,7 +339,12 @@ This varies depending on the MCU clock speed and SPI bus speed. **Return**: The board delay, in milliseconds. -### Trace management related functions +### Trace management related functions + +The HAL can provide its own trace macros by: + +- removing the `smtc_modem_core/logging` from the include list +- writing its own `smtc_modem_hal_dbg_trace.h` header, based on the content of the existing[smtc_modem_hal_dbg_trace.h](smtc_modem_core/logging/smtc_modem_hal_dbg_trace.h). #### `void smtc_modem_hal_print_trace( const char* fmt, ... )` @@ -335,6 +352,7 @@ The board delay, in milliseconds. Output a printf-style variable-length argument list to the logging subsystem. **Parameters**: + | | | | |--- |--- |--- | |[in]|fmt|String Format| @@ -375,6 +393,7 @@ No need to implement this function if FMP package is not build in `LBM_FUOTA` op The firmware status field **Parameters**: + | | | | |--- |--- |--- | |[in]|fw_to_delete_version|Version of firmware to delete| @@ -382,7 +401,8 @@ The firmware status field #### `uint32_t smtc_modem_hal_get_next_fw_version_for_fuota( void )` **brief**: -Return the firmware version that will be running once the firmware update umagine is installed as defined in FMP Specification TS006-1.0.0. +Return the firmware version that will be running once the firmware update imagine is installed as defined in FMP Specification TS006-1.0.0. + No need to implement this function if FMP package is not build in `LBM_FUOTA` option. **Return**: The new firmware version. @@ -408,9 +428,12 @@ The battery voltage in mV. **Brief**: Store the modem crash log to non-volatile memory. On most MCUs, RAM is preserved upon reset, so it may be possible to use RAM for this purpose. -This function is not called by LoRa Basics Modem directly but the recommandation is to call it in `smtc_modem_hal_on_panic() `implementation. -In case Device Mangement service is running, if status is true the crashlog will be sent automatically after joining the network. +This function is not called by LoRa Basics Modem directly but the recommendation is to call it in `smtc_modem_hal_on_panic()`implementation. + +In case Device Management service is running, if status is true the crashlog will be sent automatically after joining the network. + **Parameters**: + | | | | |--- |--- |--- | |[in]|crash_string|Crashlog string to be stored| @@ -421,9 +444,10 @@ In case Device Mangement service is running, if status is true the crashlog will **Brief**: Retrieve the modem crash log from non-volatile memory. On most MCUs, RAM is preserved upon reset, so it may be possible to use RAM for this purpose. -In case Device Mangement service is running, if status is true the crashlog will be sent automatically after joining the network. +In case Device Management service is running, if status is true the crashlog will be sent automatically after joining the network. **Parameters**: + | | | | |--- |--- |--- | |[out]|crash_string|Crashlog string to be restored| @@ -434,10 +458,12 @@ In case Device Mangement service is running, if status is true the crashlog will **Brief**: Store the modem crash log status to non-volatile memory. True indicates that a crash log has been stored and is available for retrieval. On most MCUs, RAM is preserved upon reset, so it may be possible to use RAM for this purpose. -This function is not called by LoRa Basics Modem directly but the recommandation is to call it in `smtc_modem_hal_on_panic() `implementation. -In case Device Mangement service is running, if status is true the crashlog will be sent automatically after joining the network. +This function is not called by LoRa Basics Modem directly but the recommendation is to call it in `smtc_modem_hal_on_panic()`implementation. + +In case Device Management service is running, if status is true the crashlog will be sent automatically after joining the network. **Parameters**: + | | | | |--- |--- |--- | |[in]|available|True if a crashlog is available, false otherwise| @@ -448,7 +474,7 @@ In case Device Mangement service is running, if status is true the crashlog will Get the modem crash log status from non-volatile memory. **Return**: The crash log status, as previously written using `smtc_modem_hal_set_crashlog_status()`. -In case Device Mangement service is running, if status is true the crashlog will be sent automatically after joining the network. +In case Device Management service is running, if status is true the crashlog will be sent automatically after joining the network. ### Store and Forward related functions (optional) @@ -467,9 +493,9 @@ Gives the size of a flash page in bytes **Return**: The size of a flash page. -### RTOS compatiblity related functions +### RTOS compatibility related functions #### `void smtc_modem_hal_user_lbm_irq( void )` **Brief**: -This function is called by the LBM stack on each LBM interruption (radio interrupt or low-power timer nterrupt). It could be convenient in the case of an RTOS implementation to notify the thread that manages the LBM stack +This function is called by the LBM stack on each LBM interruption (radio interrupt or low-power timer interrupt). It could be convenient in the case of an RTOS implementation to notify the thread that manages the LBM stack diff --git a/lbm_lib/README.md b/lbm_lib/README.md index 2fee810..aa3abc8 100644 --- a/lbm_lib/README.md +++ b/lbm_lib/README.md @@ -84,6 +84,9 @@ Support for the following transceivers can be selected at build time: - sx1261 - SX1261 Transceiver. - sx1262 - SX1262 Transceiver. - sx1268 - SX1268 Transceiver. +- sx1272 - SX1272 Transceiver. +- sx1276 - SX1276 Transceiver. + LoRa Basics™ Modem (LBM) should be built for a specific transceiver by using the basic_modem_ parameter. ### MCU Flags @@ -127,8 +130,10 @@ The user can choose which feature to embed in LoRa Basics Modem by updating [opt - LBM_CLASS_B: Enable compilation of class B feature - LBM_CLASS_C: Enable compilation of class C feature -- LBM_MULTICAST: Enable compilation of LoRaWAN mutlicast feature +- LBM_MULTICAST: Enable compilation of LoRaWAN multicast feature - LBM_CSMA: Enable compilation of CSMA feature +- LBM_RELAY_TX_ENABLE : Enable compilation of Relay Tx feature +- LBM_RELAY_RX_ENABLE : Enable compilation of Relay Rx feature **LoRaWAN packages related options**: @@ -257,7 +262,7 @@ Retrieve information about the connection: ### Carrier Sense Multiple Access (CSMA) for LoRaWAN The modem supports a CSMA (Carrier Sense Multiple Access) feature designed to prevent collisions in LoRa packet transmissions. -LoRa Alliance Technical Recommandations can be read at [TR0013](https://resources.lora-alliance.org/home/tr013-1-0-0-csma) +LoRa Alliance Technical Recommendations can be read at [TR0013](https://resources.lora-alliance.org/home/tr013-1-0-0-csma) To enable CSMA during compilation, set the option `LBM_CSMA=yes` in the Makefile. By default, CSMA is activated at modem startup if the compilation option `USE_CSMA_BY_DEFAULT=yes` is configured. @@ -411,7 +416,7 @@ The proposed implementation supports both Class B or Class C modes and supports FUOTA is not enabled by default in LoRa Basics™ Modem. To activate it during project compilation, set the `LBM_FUOTA` flag to `yes` and set the `LBM_FUOTA_VERSION` flag to chosen version number 1 or 2 in [options.mk](makefiles/options.mk). -Multi-Package Access is not automaticaly added to compilation even if `LBM_FUOTA` flag is set to `yes`. User shall set `LBM_FUOTA_ENABLE_MPA` to yes to use it. +Multi-Package Access is not automatically added to compilation even if `LBM_FUOTA` flag is set to `yes`. User shall set `LBM_FUOTA_ENABLE_MPA` to yes to use it. Additionally, provide the following compilation fields: @@ -519,7 +524,7 @@ The cloud service may send requests to the modem on the device management port. - **Mute**: ask the modem to mute itself permanently or during a specified number of days (a `SMTC_MODEM_EVENT_MUTE` event is triggered) - **SetConf**: Update device management configuration (a `SMTC_MODEM_EVENT_DM_SET_CONF` event is triggered, provided the field that was updated according to `smtc_modem_event_setconf_opcode_t` ) -### Alamanac Update service (LoRaCloud) +### Almanac Update service (LoRaCloud) Choose to update the Lora-Edge transceiver almanac using the cloud with the autonomous Almanac Update service. Initiate the service with `smtc_modem_almanac_start()` and stop it anytime with `smtc_modem_almanac_stop()`. @@ -552,29 +557,50 @@ In the provided example on the STM32L4 MCU (under the lbm_examples folder), LPTI ## Relay -**LoRa Basic Modem** proposes an implementation of the [LoRaWAN® Relay Specification TS011-1.0.0](https://resources.lora-alliance.org/technical-specifications/ts011-1-0-0-relay) +**LoRa Basic Modem** proposes an implementation of the [LoRaWAN® Relay Specification TS011-1.0.1](https://resources.lora-alliance.org/technical-specifications/ts011-1-0-1-relay) -This implementation provides the code for the relayed end-device refered as Relay TX +This implementation provides the code for the relayed end-device referred as Relay Tx -### Relay TX +### Relay Tx -To build the relay TX feature you need to define "RELAY_TX_ENABLE=yes" +To build the relay Tx feature you need to define "LBM_RELAY_TX_ENABLE=yes" This option will require an additional 500 bytes of RAM and 5.5 Kbytes of FLASH. -### Known limitation for the Relay TX +### Known limitation for the Relay Tx + +- Relay specific cryptographic operations are not supported by Semtech’s hardware Crypto Engine (LR11xx platform), and therefore this implementation is only compatible with embedded software cryptographic operations. +- SX128x and SX127x are not supported fir Relay Tx operation. +- The Scan and Send feature (SEND_MODE_UPLINK used in SMTC_MODEM_WIFI_SEND_MODE) of the geolocation services can only be used when the Relay Tx device is joined. +- In a Store and Forward context (device accruing scans when it is offline) with device being relayed, the first uplink may be missed if the Relay Rx is waiting for its network configuration from the LNS. +- On this release, a single WOR channel is supported for US915 and AU915 regions. +- If the Periodical uplink example is built with the RELAY_TX=yes and RELAY_RX=yes flags (that device is relayed device, but can be changed to a Relay Rx by network command), the modem will enable the RELAY_TX feature after a reset. However, if a command from the LNS to activate the RELAY_RX feature (0X40 RELAY CONFIG) is received, the device will unexpectedly open an additional RxR window, without compromising functionality. + +### Relay Rx + +To build the relay Rx feature you need to define "LBM_RELAY_RX_ENABLE=yes" + +This option will require an additional 2.5 kbytes of RAM and 10 kbytes of FLASH. + +On a hardware note, it is strongly recommended to use a 32 MHz TCXO in a Relay Rx to respect the maximum frequency offset budget between the end-device and the relay itself. + +### Known limitation for the Relay Rx -- This implementation is only compatible with embedded software cryptographic operations. +- This implementation is only compatible with embedded software cryptographic operations. (see above “Relay Tx”). - SX128x and SX127x are not supported -- With relayTx feature enable, if a modem cannot send a WOR due to DutyCycle restriction in the band, the uplink is not send neither event if there is DutyCycle time still available. -- If geoloc services wifi scan and the wifi scan uplink is aborted by lbt or relay link, the extra data from wifi terminated event return nb_scan_sent at 1. +- Due to specification limitation, JoinAccept cannot be forwarded to end-device if Rx1 delay is greater than 12s with SF12BW125, Rx1 and RxR windows will overlap +- If the CAD periodicity is set to 250ms or less, it is no longer possible to increase it without resetting the Relay Rx. +- The reduction of a device bucket size on the go, will not be effective before the previous allocation has been used. +- On this release, a single WOR channel is supported for US915 and AU915 regions. +- If the Periodical uplink example is built with the RELAY_TX=yes and RELAY_RX=yes flags (that device is relayed device, but can be changed to a Relay Rx by network command) , the modem will enable the RELAY_TX feature after a reset. However, if a command from the LNS to activate the RELAY_RX feature (0X40 RELAY CONFIG) is received, the the device will unexpectedly open an additional RxR window, without compromising functionality. ## LoRa Basic Modem known limitations +- [test-mode] The device will panic and reset if a bandwidth that is not supported by the selected radio chip is chosen. The choice of bandwidth is dependent on the radio used. This will not happen for the LoRaWAN bandwidths 125kHz and 500kHz. +- [test-mode] In test mode, CSMA can’t be used for non LoRaWAN bandwidths lower than 125 kHz. - [charge] Values returned by `smtc_modem_get_charge()` for regions CN470 and CN470_RP1 are not accurate. -- [charge] Values returned by `smtc_modem_get_charge()` for the LR-FHSS based datarates are not accurate. - [charge] Values returned by `smtc_modem_get_charge()` for sx127x radios are not accurate. -- [modem-status] The joining bit status is exclusively set during the LoRaWAN join transaction (i.e., TX/RX1/RX2) and remains unset between join attempts. +- [modem-status] The joining bit status is exclusively set during the LoRaWAN join transaction (i.e., Tx/Rx1/Rx2) and remains unset between join attempts. - [file upload] DAS may encounter difficulties reconstructing small files (less than 13 bytes) when the modem operates in the US915 region and utilizes DR0 data rate. - On fixed channel plan regions (ex:US915) if LBT is enabled and a channel is constantly jammed, the modem will use the 7 others channels then it will try to send on the jammed channel. As the modem cannot send on this channel, it will not remove this channel from the usable channel list and did not re-enable all other channels. Resulting in modem stuck. diff --git a/lbm_lib/lora_basics_modem_version.h b/lbm_lib/lora_basics_modem_version.h index 219dfe6..256bc21 100644 --- a/lbm_lib/lora_basics_modem_version.h +++ b/lbm_lib/lora_basics_modem_version.h @@ -3,11 +3,12 @@ * * \brief Defines the Lora Basics Modem firmware version * - * Revised BSD License + * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef LORA_BASICS_MODEM_VERSION_H__ @@ -57,7 +60,7 @@ extern "C" * --- PUBLIC TYPES ------------------------------------------------------------ */ #define LORA_BASICS_MODEM_FW_VERSION_MAJOR 4 -#define LORA_BASICS_MODEM_FW_VERSION_MINOR 5 +#define LORA_BASICS_MODEM_FW_VERSION_MINOR 8 #define LORA_BASICS_MODEM_FW_VERSION_PATCH 0 /* diff --git a/lbm_lib/makefiles/common.mk b/lbm_lib/makefiles/common.mk index 5a652f3..1a01afe 100644 --- a/lbm_lib/makefiles/common.mk +++ b/lbm_lib/makefiles/common.mk @@ -219,7 +219,7 @@ else LBM_C_DEFS += \ -DADD_CLASS_C endif - + ifeq ($(LBM_MULTICAST),yes) LBM_C_DEFS += \ -DSMTC_MULTICAST @@ -384,6 +384,7 @@ LBM_C_INCLUDES += \ -I.\ -Ismtc_modem_api\ -Ismtc_modem_core\ + -Ismtc_modem_core/logging\ -Ismtc_modem_core/modem_supervisor\ -Ismtc_modem_core/modem_utilities\ -Ismtc_modem_core/lorawan_packages\ @@ -444,12 +445,12 @@ else -Ismtc_modem_core/modem_services/beacon_tx_service endif endif - + ifeq ($(LBM_CLASS_C),yes) LBM_C_INCLUDES += \ -Ismtc_modem_core/lr1mac/src/lr1mac_class_c endif - + ifeq ($(LBM_MULTICAST),yes) LBM_C_INCLUDES += \ -Ismtc_modem_core/lr1mac/src/services/smtc_multicast diff --git a/lbm_lib/makefiles/lr11xx.mk b/lbm_lib/makefiles/lr11xx.mk index aa0a33d..18843d9 100644 --- a/lbm_lib/makefiles/lr11xx.mk +++ b/lbm_lib/makefiles/lr11xx.mk @@ -1,5 +1,5 @@ ############################################################################## -# Definitions for the LR11XX tranceiver +# Definitions for the LR11XX transceiver ############################################################################## -include makefiles/options.mk diff --git a/lbm_lib/makefiles/options.mk b/lbm_lib/makefiles/options.mk index 0a023e4..de45ef9 100644 --- a/lbm_lib/makefiles/options.mk +++ b/lbm_lib/makefiles/options.mk @@ -124,4 +124,10 @@ LBM_GEOLOCATION ?= no LBM_STORE_AND_FORWARD ?= no # Multistack -NB_OF_STACK ?= 1 \ No newline at end of file +NB_OF_STACK ?= 1 + +# Relay Tx +LBM_RELAY_TX_ENABLE ?= no + +# Relay Rx +LBM_RELAY_RX_ENABLE ?= no \ No newline at end of file diff --git a/lbm_lib/makefiles/regions.mk b/lbm_lib/makefiles/regions.mk index 5f21966..2f5b847 100644 --- a/lbm_lib/makefiles/regions.mk +++ b/lbm_lib/makefiles/regions.mk @@ -30,6 +30,9 @@ endif ifeq ($(RADIO),lr1120) REGION_WW_2G4 = yes endif +ifeq ($(RADIO),lr1121) +REGION_WW_2G4 = yes +endif endif # REGION #----------------------------------------------------------------------------- diff --git a/lbm_lib/makefiles/relay.mk b/lbm_lib/makefiles/relay.mk index 1e90c7b..9bca7ed 100755 --- a/lbm_lib/makefiles/relay.mk +++ b/lbm_lib/makefiles/relay.mk @@ -2,7 +2,7 @@ # Definitions for the Relay ############################################################################## -ifeq ($(RELAY_TX_ENABLE),yes) +ifeq ($(LBM_RELAY_TX_ENABLE),yes) RELAY_C_SOURCES += \ smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.c \ smtc_modem_core/lr1mac/src/relay/common/relay_real.c \ @@ -14,19 +14,36 @@ RELAY_C_SOURCES += \ endif +ifeq ($(LBM_RELAY_RX_ENABLE),yes) +RELAY_C_SOURCES += \ + smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.c \ + smtc_modem_core/lr1mac/src/relay/common/relay_real.c \ + smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.c \ + smtc_modem_core/lr1mac/src/relay/common/relay_mac_parser.c \ + smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_mac_parser.c \ + smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx.c \ + smtc_modem_core/modem_services/relay_service/lorawan_relay_rx_service.c + +endif #----------------------------------------------------------------------------- # Includes #----------------------------------------------------------------------------- -ifeq ($(RELAY_TX_ENABLE),yes) +ifeq ($(LBM_RELAY_TX_ENABLE),yes) RELAY_C_INCLUDES = \ -Ismtc_modem_core/lr1mac/src/relay/common \ -Ismtc_modem_core/lr1mac/src/relay/relay_tx\ + -Ismtc_modem_core/lr1mac/src/relay/relay_rx\ -Ismtc_modem_core/modem_services/relay_service endif - - +ifeq ($(LBM_RELAY_RX_ENABLE),yes) +RELAY_C_INCLUDES = \ + -Ismtc_modem_core/lr1mac/src/relay/common \ + -Ismtc_modem_core/lr1mac/src/relay/relay_rx\ + -Ismtc_modem_core/lr1mac/src/relay/relay_tx\ + -Ismtc_modem_core/modem_services/relay_service +endif #----------------------------------------------------------------------------- # Region #----------------------------------------------------------------------------- @@ -34,7 +51,12 @@ endif #----------------------------------------------------------------------------- # Radio specific compilation flags #----------------------------------------------------------------------------- -ifeq ($(RELAY_TX_ENABLE),yes) +ifeq ($(LBM_RELAY_TX_ENABLE),yes) +RELAY_C_DEFS += \ + -DADD_RELAY_TX +endif +ifeq ($(LBM_RELAY_RX_ENABLE),yes) RELAY_C_DEFS += \ - -DRELAY_TX + -DADD_RELAY_RX endif + diff --git a/lbm_lib/smtc_modem_api/CHANGELOG.md b/lbm_lib/smtc_modem_api/CHANGELOG.md index 7f1c2f0..b2ec656 100644 --- a/lbm_lib/smtc_modem_api/CHANGELOG.md +++ b/lbm_lib/smtc_modem_api/CHANGELOG.md @@ -4,23 +4,46 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v4.8.0] 2024-12-20 + +### Added + +* Add relay rx event + * `SMTC_MODEM_EVENT_RELAY_RX_RUNNING` : Relay Rx enabled by network server +* Add test mode event + * `SMTC_MODEM_EVENT_TEST_MODE`: to be inform of the test mode status +* Add duty-cycle event + * `SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE`: when the regional duty-cycle constraint is reached or released +* For FUOTA with R11XX Crypto Engine + * `smtc_modem_get_data_block_int_key()` Get Fragmented DataBlockIntKey + * `smtc_modem_derive_and_set_data_block_int_key()` Derive and set DataBlockIntKey + +### Changed + +* `smtc_modem_api.h` + * function `smtc_modem_csma_set_parameters()` reverse some parameters to be consistent + * function `smtc_modem_get_rp_stats_to_array()` update output parameter +* `smtc_modem_test_api.h` globally reworked to be more generic and use smtc_ral value + ## [v4.5.0] 2024-05-06 ### Added + * All events and API defined in the v4.4.0 ## [v4.4.0] 2023-12-21 ### Added + * Add `smtc_modem_relay_tx_disable` function to disable the relay tx feature (disable the WOR frame) * Add `smtc_modem_relay_tx_enable` function to enable the relay tx feature (enable the WOR frame) * Add `smtc_modem_relay_tx_get_activation_mode` function to get the current relay tx mode activation -* Add `smtc_modem_relay_tx_get_sync_status` function to get the current synchronisation status with a relay rx +* Add `smtc_modem_relay_tx_get_sync_status` function to get the current synchronization status with a relay rx * Add `smtc_modem_relay_tx_is_enable` function to get if the relay tx feature is currently enable -* Add relay tx event +* Add relay tx event * `SMTC_MODEM_EVENT_RELAY_TX_DYNAMIC` : Relay TX dynamic mode has enable or disable the WOR protocol * `SMTC_MODEM_EVENT_RELAY_TX_MODE` : Relay TX activation has been updated via a MAC command - * `SMTC_MODEM_EVENT_RELAY_TX_SYNC` : Relay TX synchronisation has changed + * `SMTC_MODEM_EVENT_RELAY_TX_SYNC` : Relay TX synchronization has changed ## [v4.3.0] 2023-12-15 @@ -31,20 +54,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * Add `smtc_modem_get_certification_mode` to get the current certification mode status * Add `smtc_modem_adr_get_profile` to get current Datarate Profile of the modem * Add or re-add functions related to LoRaCloud: - * Almanac update service: - * function `smtc_modem_almanac_start` (new) + * Almanac update service: + * function `smtc_modem_almanac_start` (new) * function `smtc_modem_almanac_stop` (new) - * Stream service: + * Stream service: * Re-add `smtc_modem_stream_init` * Re-add `smtc_modem_stream_add_data` * Re-add `smtc_modem_stream_status` * Re-add related event `SMTC_MODEM_EVENT_STREAM_DONE` - * Large File Update service: + * Large File Update service: * Re-add `smtc_modem_file_upload_init` * Re-add `smtc_modem_file_upload_start` * Re-add `smtc_modem_file_upload_reset` * Re-add related event `SMTC_MODEM_EVENT_UPLOAD_DONE` - * Device Mangament service: + * Device Management service: * `smtc_modem_dm_enable` (new) * `smtc_modem_dm_get_fport` * `smtc_modem_dm_set_fport` @@ -57,7 +80,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * `smtc_modem_dm_get_user_data` * `smtc_modem_dm_handle_alcsync` (new) * Re-add related events `SMTC_MODEM_EVENT_DM_SET_CONF` and `SMTC_MODEM_EVENT_MUTE` -* Add Store and Forward service: +* Add Store and Forward service: * `smtc_modem_store_and_forward_set_state` * `smtc_modem_store_and_forward_get_state` * `smtc_modem_store_and_forward_flash_add_data` diff --git a/lbm_lib/smtc_modem_api/smtc_modem_api.h b/lbm_lib/smtc_modem_api/smtc_modem_api.h index 4091de1..5356214 100755 --- a/lbm_lib/smtc_modem_api/smtc_modem_api.h +++ b/lbm_lib/smtc_modem_api/smtc_modem_api.h @@ -351,8 +351,11 @@ typedef enum smtc_modem_event_type_e SMTC_MODEM_EVENT_WIFI_SCAN_DONE, SMTC_MODEM_EVENT_WIFI_TERMINATED, SMTC_MODEM_EVENT_RELAY_TX_DYNAMIC, //!< Relay TX dynamic mode has enable or disable the WOR protocol - SMTC_MODEM_EVENT_RELAY_TX_MODE, //!< Relay TX activation has been updated + SMTC_MODEM_EVENT_RELAY_TX_MODE, //!< Relay TX activation has been updated SMTC_MODEM_EVENT_RELAY_TX_SYNC, //!< Relay TX synchronisation has changed + SMTC_MODEM_EVENT_RELAY_RX_RUNNING, //!< Relay RX running has changed + SMTC_MODEM_EVENT_TEST_MODE, + SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE, SMTC_MODEM_EVENT_MAX, } smtc_modem_event_type_t; @@ -420,6 +423,14 @@ typedef enum smtc_modem_event_uploaddone_status_e SMTC_MODEM_EVENT_UPLOAD_DONE_SUCCESSFUL = 1, } smtc_modem_event_uploaddone_status_t; +typedef enum smtc_modem_event_test_mode_status_e +{ + SMTC_MODEM_EVENT_TEST_MODE_ENDED = 0, + SMTC_MODEM_EVENT_TEST_MODE_TX_COMPLETED = 1, + SMTC_MODEM_EVENT_TEST_MODE_TX_DONE = 2, + SMTC_MODEM_EVENT_TEST_MODE_RX_DONE = 3, + SMTC_MODEM_EVENT_TEST_MODE_RX_ABORTED = 4, +} smtc_modem_event_test_mode_status_t; /** * @brief Structure holding event-related data */ @@ -486,7 +497,18 @@ typedef struct smtc_modem_event_s { uint8_t status; } relay_tx; - + struct + { + uint8_t status; + } relay_rx; + struct + { + smtc_modem_event_test_mode_status_t status; + } test_mode_status; + struct + { + uint8_t status; + } regional_duty_cycle; } event_data; } smtc_modem_event_t; @@ -744,6 +766,38 @@ smtc_modem_return_code_t smtc_modem_get_chip_eui( uint8_t stack_id, uint8_t chip */ smtc_modem_return_code_t smtc_modem_derive_keys( uint8_t stack_id ); +#if defined( USE_LR11XX_CE ) +/** + * @brief Get Fragmented DataBlockIntKey + * + * @param [in] stack_id Stack identifier + * @param [out] data_block_int_key the derived DataBlockIntKey from GenAppKey + * + * @return Modem return code as defined in @ref smtc_modem_return_code_t + * @retval SMTC_MODEM_RC_OK Command executed without errors + * @retval SMTC_MODEM_RC_BUSY Modem is currently in test mode + * @retval SMTC_MODEM_RC_FAIL Modem is already joined or is joining + * @retval SMTC_MODEM_RC_INVALID_STACK_ID Invalid \p stack_id + */ +smtc_modem_return_code_t smtc_modem_get_data_block_int_key( uint8_t stack_id, + uint8_t data_block_int_key[SMTC_MODEM_KEY_LENGTH] ); + +/** + * @brief Derive and set DataBlockIntKey + * @remark this key is not saved in crypto engine due to an hardware limitation + * + * @param [in] stack_id Stack identifier + * @param [out] gen_appkey GenAppKey for fragmented data block + * + * @return Modem return code as defined in @ref smtc_modem_return_code_t + * @retval SMTC_MODEM_RC_OK Command executed without errors + * @retval SMTC_MODEM_RC_BUSY Modem is currently in test mode + * @retval SMTC_MODEM_RC_FAIL Modem is already joined or is joining + * @retval SMTC_MODEM_RC_INVALID_STACK_ID Invalid \p stack_id + */ +smtc_modem_return_code_t smtc_modem_derive_and_set_data_block_int_key( + uint8_t stack_id, const uint8_t gen_appkey[SMTC_MODEM_KEY_LENGTH] ); +#endif // USE_LR11XX_CE /* * ----------------------------------------------------------------------------- * ----------- ADVANCED MODEM FUNCTIONS ---------------------------------------- @@ -941,7 +995,6 @@ smtc_modem_return_code_t smtc_modem_get_suspend_radio_communications( uint8_t st */ smtc_modem_return_code_t smtc_modem_suspend_radio_communications( bool suspend ); - /** * @brief Set and start the alarm timer (up to 864000s ie 10 days) * @@ -1312,8 +1365,8 @@ smtc_modem_return_code_t smtc_modem_csma_get_state( uint8_t stack_id, bool* enab * @retval SMTC_MODEM_RC_BUSY Modem is currently in test mode * @retval SMTC_MODEM_RC_INVALID_STACK_ID Invalid \p stack_id */ -smtc_modem_return_code_t smtc_modem_csma_set_parameters( uint8_t stack_id, uint8_t nb_bo_max, bool bo_enabled, - uint8_t max_ch_change ); +smtc_modem_return_code_t smtc_modem_csma_set_parameters( uint8_t stack_id, uint8_t max_ch_change, bool bo_enabled, + uint8_t nb_bo_max ); /** * @brief Get the parameters of the CSMA feature @@ -1351,7 +1404,7 @@ smtc_modem_return_code_t smtc_modem_get_charge( uint32_t* charge_mah ); * @param stats_array_length * @return smtc_modem_return_code_t */ -smtc_modem_return_code_t smtc_modem_get_rp_stats_to_array( uint8_t* stats_array, uint8_t* stats_array_length ); +smtc_modem_return_code_t smtc_modem_get_rp_stats_to_array( uint8_t* stats_array, uint16_t* stats_array_length ); /** * @brief Reset the total charge counter of the modem @@ -2011,7 +2064,7 @@ smtc_modem_return_code_t smtc_modem_dm_get_user_data( uint8_t stack_id, * @remark This configuration function shall be called before the ALCSync service is started * * @param [in] stack_id Stack identifier - * @param [in] handle_alcsync True to handle ALCSync trafic on dm frame, false otherwise + * @param [in] handle_alcsync True to handle ALCSync traffic on dm frame, false otherwise * * @return Modem return code as defined in @ref smtc_modem_return_code_t * @retval SMTC_MODEM_RC_OK Command executed without errors diff --git a/lbm_lib/smtc_modem_api/smtc_modem_relay_api.h b/lbm_lib/smtc_modem_api/smtc_modem_relay_api.h index eaf1ee4..6405f17 100644 --- a/lbm_lib/smtc_modem_api/smtc_modem_relay_api.h +++ b/lbm_lib/smtc_modem_api/smtc_modem_relay_api.h @@ -64,7 +64,7 @@ typedef enum smtc_modem_relay_tx_activation_mode_e SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_DISABLED, SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ENABLE, SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_DYNAMIC, - SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ED_CONTROLED, + SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ED_CONTROLLED, } smtc_modem_relay_tx_activation_mode_t; typedef enum smtc_modem_relay_tx_sync_status_e @@ -110,7 +110,6 @@ typedef struct smtc_modem_relay_tx_config_s smtc_modem_return_code_t smtc_modem_relay_tx_get_activation_mode( uint8_t stack_id, smtc_modem_relay_tx_activation_mode_t* mode ); - /** * @brief Return the relay configuration tx * @@ -123,7 +122,7 @@ smtc_modem_return_code_t smtc_modem_relay_tx_get_activation_mode( uint8_t */ smtc_modem_return_code_t smtc_modem_relay_tx_get_config( uint8_t stack_id, smtc_modem_relay_tx_config_t* config ); /** - * @brief Return the synchronisation status of the relay tx stacl + * @brief Return the synchronisation status of the relay tx stack * * @param[in] stack_id Stack identifier * @param[out] status Synchronisation status @@ -155,7 +154,7 @@ smtc_modem_return_code_t smtc_modem_relay_tx_is_enable( uint8_t stack_id, bool* /** * @brief Enable the relay tx * - * Only works if the ED is in SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ED_CONTROLED + * Only works if the ED is in SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ED_CONTROLLED * @param[in] stack_id Stack identifier * @param[in] smtc_modem_relay_tx_config_t full relay config * @@ -165,21 +164,24 @@ smtc_modem_return_code_t smtc_modem_relay_tx_is_enable( uint8_t stack_id, bool* * @return Modem return code as defined in @ref smtc_modem_return_code_t * @retval SMTC_MODEM_RC_OK Command executed without errors * @retval SMTC_MODEM_RC_BUSY Modem is currently in test mode - * @retval SMTC_MODEM_RC_FAIL This stack doesn't have the relay tx feature or is not in ED controled mode + * @retval SMTC_MODEM_RC_FAIL This stack doesn't have the relay tx feature + * or is not in ED controlled mode + * or Relay Rx enabled by the network * @retval SMTC_MODEM_RC_INVALID_STACK_ID Invalid \p stack_id */ -smtc_modem_return_code_t smtc_modem_relay_tx_enable( uint8_t stack_id, const smtc_modem_relay_tx_config_t* relay_config ); +smtc_modem_return_code_t smtc_modem_relay_tx_enable( uint8_t stack_id, + const smtc_modem_relay_tx_config_t* relay_config ); /** * @brief Disable the relay tx * - * Only works if the ED is in SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ED_CONTROLED + * Only works if the ED is in SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ED_CONTROLLED * @param[in] stack_id Stack identifier * * @return Modem return code as defined in @ref smtc_modem_return_code_t * @retval SMTC_MODEM_RC_OK Command executed without errors * @retval SMTC_MODEM_RC_BUSY Modem is currently in test mode - * @retval SMTC_MODEM_RC_FAIL This stack doesn't have the relay tx feature or is not in ED controled mode + * @retval SMTC_MODEM_RC_FAIL This stack doesn't have the relay tx feature or is not in ED controlled mode * @retval SMTC_MODEM_RC_INVALID_STACK_ID Invalid \p stack_id */ smtc_modem_return_code_t smtc_modem_relay_tx_disable( uint8_t stack_id ); diff --git a/lbm_lib/smtc_modem_api/smtc_modem_test_api.h b/lbm_lib/smtc_modem_api/smtc_modem_test_api.h index 5fd747e..47b7f68 100644 --- a/lbm_lib/smtc_modem_api/smtc_modem_test_api.h +++ b/lbm_lib/smtc_modem_api/smtc_modem_test_api.h @@ -48,6 +48,7 @@ extern "C" { #include // bool type #include "smtc_modem_api.h" +#include "ral_defs.h" /* * ----------------------------------------------------------------------------- @@ -63,65 +64,13 @@ extern "C" { * ----------------------------------------------------------------------------- * --- PUBLIC TYPES ------------------------------------------------------------ */ - -/** - * @brief Test mode Spreading Factor type - */ -typedef enum smtc_modem_test_sf_e -{ - SMTC_MODEM_TEST_FSK = 0, //!< FSK - SMTC_MODEM_TEST_LORA_SF5, //!< SF5 - SMTC_MODEM_TEST_LORA_SF6, //!< SF6 - SMTC_MODEM_TEST_LORA_SF7, //!< SF7 - SMTC_MODEM_TEST_LORA_SF8, //!< SF8 - SMTC_MODEM_TEST_LORA_SF9, //!< SF9 - SMTC_MODEM_TEST_LORA_SF10, //!< SF10 - SMTC_MODEM_TEST_LORA_SF11, //!< SF11 - SMTC_MODEM_TEST_LORA_SF12, //!< SF12 - SMTC_MODEM_TEST_LORA_SF_COUNT, //!< Count -} smtc_modem_test_sf_t; - -/** - * @brief Test mode Bandwith type - */ -typedef enum smtc_modem_test_bw_e -{ - SMTC_MODEM_TEST_BW_125_KHZ, //!< BW125 - SMTC_MODEM_TEST_BW_250_KHZ, //!< BW250 - SMTC_MODEM_TEST_BW_500_KHZ, //!< BW500 - SMTC_MODEM_TEST_BW_200_KHZ, //!< BW200 - SMTC_MODEM_TEST_BW_400_KHZ, //!< BW400 - SMTC_MODEM_TEST_BW_800_KHZ, //!< BW800 - SMTC_MODEM_TEST_BW_1600_KHZ, //!< BW1600 - SMTC_MODEM_TEST_BW_COUNT, //!< Count -} smtc_modem_test_bw_t; - -/** - * @brief Test mode Bandwith type (high bandwidth) - */ -typedef enum smtc_modem_test_bw_m_e -{ - SMTC_MODEM_TEST_BW_12M = 15, - SMTC_MODEM_TEST_BW_18M, - SMTC_MODEM_TEST_BW_24M, -} smtc_modem_test_bw_m_t; - -/** - * @brief Test mode Coding Rate type - */ -typedef enum smtc_modem_test_cr_e +typedef enum smtc_modem_test_mode_sync_word_e { - SMTC_MODEM_TEST_CR_4_5 = 0, //!< CR 4/5 - SMTC_MODEM_TEST_CR_4_6, //!< CR 4/6 - SMTC_MODEM_TEST_CR_4_7, //!< CR 4/7 - SMTC_MODEM_TEST_CR_4_8, //!< CR 4/8 - SMTC_MODEM_TEST_CR_LI_4_5, //!< CR 4/5 long interleaved - SMTC_MODEM_TEST_CR_LI_4_6, //!< CR 4/6 long interleaved - SMTC_MODEM_TEST_CR_LI_4_8, //!< CR 4/8 long interleaved - SMTC_MODEM_TEST_CR_COUNT, //!< Count -} smtc_modem_test_cr_t; - -/* clang-format on */ + SYNC_WORD_0x12 = 0x12, + SYNC_WORD_0x21 = 0x21, + SYNC_WORD_0x34 = 0x34, + SYNC_WORD_0x56 = 0x56, +} smtc_modem_test_mode_sync_word_t; /* * ----------------------------------------------------------------------------- @@ -147,30 +96,75 @@ smtc_modem_return_code_t smtc_modem_test_stop( void ); /** * @brief Perform no operation. This function can be used to terminate an ongoing continuous operation * @remark Abort the radio planner task - * + * @param [in] reset_radio Reset radio after NOP * @return Modem return code as defined in @ref smtc_modem_return_code_t */ -smtc_modem_return_code_t smtc_modem_test_nop( void ); +smtc_modem_return_code_t smtc_modem_test_nop( bool reset_radio ); /** - * @brief Test mode TX single or continue - * @remark Transmit a single packet or continuously transmit packets as fast as possible. + * @brief Test mode TX LoRa single or continue * * @param [in] payload* Payload that will be sent. If NULL a randomly generated payload_length msg will be sent * @param [in] payload_length Length of the payload * @param [in] frequency_hz Frequency in Hz * @param [in] tx_power_dbm Power in dbm - * @param [in] sf Spreading factor following smtc_modem_test_sf_t definition - * @param [in] bw Bandwith following smtc_modem_test_bw_t definition - * @param [in] cr Coding rate following smtc_modem_test_cr_t definition + * @param [in] sf Spreading factor following ral_lora_sf_t definition + * @param [in] bw Bandwidth following ral_lora_bw_t definition + * @param [in] cr Coding rate following ral_lora_cr_t definition + * @param [in] sync_word sync_word + * @param [in] invert_iq invert iq parameter + * @param [in] crc_is_on include crc boolean + * @param [in] header_type header type (explicit/implicit) * @param [in] preamble_size Size of the preamble - * @param [in] continuous_tx false: single transmission / true: continuous transmission + * @param [in] nb_of_tx nb of transmissions (0 means tx continuous) + * @param [in] delay_ms delay between two transmissions + * + * @return Modem return code as defined in @ref smtc_modem_return_code_t + */ + +smtc_modem_return_code_t smtc_modem_test_tx_lora( uint8_t* payload, uint8_t payload_length, uint32_t frequency_hz, + int8_t tx_power_dbm, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cr_t cr, smtc_modem_test_mode_sync_word_t sync_word, + bool invert_iq, bool crc_is_on, ral_lora_pkt_len_modes_t header_type, + uint32_t preamble_size, uint32_t nb_of_tx, uint32_t delay_ms ); + +/** + * @brief Test mode TX FSK single or continue + * + * @param [in] payload* Payload that will be sent. If NULL a randomly generated payload_length msg will be + * sent + * @param [in] payload_length Length of the payload + * @param [in] frequency_hz Frequency in Hz + * @param [in] tx_power_dbm Power in dbm + * @param [in] nb_of_tx nb of transmissions (0 means tx continuous) + * @param [in] delay_ms delay between two transmissions * * @return Modem return code as defined in @ref smtc_modem_return_code_t */ -smtc_modem_return_code_t smtc_modem_test_tx( uint8_t* payload, uint8_t payload_length, uint32_t frequency_hz, - int8_t tx_power_dbm, smtc_modem_test_sf_t sf, smtc_modem_test_bw_t bw, - smtc_modem_test_cr_t cr, uint32_t preamble_size, bool continuous_tx ); +smtc_modem_return_code_t smtc_modem_test_tx_fsk( uint8_t* payload, uint8_t payload_length, uint32_t frequency_hz, + int8_t tx_power_dbm, uint32_t nb_of_tx, uint32_t delay_ms ); + +/** + * @brief Test mode TX LR_FHSS single or continue + * + * @param [in] payload* Payload that will be sent. If NULL a randomly generated payload_length msg will be sent + * @param [in] payload_length Length of the payload + * @param [in] frequency_hz Frequency in Hz + * @param [in] tx_power_dbm Power in dbm + * @param [in] cr Coding rate following lr_fhss_v1_cr_t definition + * @param [in] bw Bandwidth following lr_fhss_v1_bw_t definition + * @param [in] grid Grid following lr_fhss_v1_grid_t definition + * @param [in] enable_hopping Enable channel hopping + * @param [in] nb_of_tx nb of transmissions (0 means tx continuous) + * @param [in] delay_ms delay between two transmissions + * + * @return Modem return code as defined in @ref smtc_modem_return_code_t + */ + +smtc_modem_return_code_t smtc_modem_test_tx_lrfhss( uint8_t* payload, uint8_t payload_length, uint32_t frequency_hz, + int8_t tx_power_dbm, lr_fhss_v1_cr_t tx_cr, lr_fhss_v1_bw_t tx_bw, + lr_fhss_v1_grid_t tx_grid, bool enable_hopping, uint32_t nb_of_tx, + uint32_t delay_ms ); /** * @brief Test mode transmit a continuous wave. @@ -184,18 +178,38 @@ smtc_modem_return_code_t smtc_modem_test_tx( uint8_t* payload, uint8_t payload_l smtc_modem_return_code_t smtc_modem_test_tx_cw( uint32_t frequency_hz, int8_t tx_power_dbm ); /** - * @brief Test mode RX continue + * @brief Test mode RX LoRa continue + * @remark Continuously receive packets. + * + * @param [in] frequency_hz Frequency in Hz + * @param [in] sf Spreading factor following ral_lora_sf_t definition + * @param [in] bw Bandwidth following ral_lora_bw_t definition + * @param [in] cr Coding rate following ral_lora_cr_t definition + * @param [in] sync_word sync_word + * @param [in] invert_iq invert iq parameter + * @param [in] crc_is_on include crc boolean + * @param [in] header_type header type (explicit/implicit) + * @param [in] preamble_size Size of the preamble + * @param [in] symb_nb_timeout Number of symbols before timeout (0 means no timeout) + * + * @return Modem return code as defined in @ref smtc_modem_return_code_t + */ + +smtc_modem_return_code_t smtc_modem_test_rx_lora( uint32_t frequency_hz, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cr_t cr, + smtc_modem_test_mode_sync_word_t sync_word, bool invert_iq, + bool crc_is_on, ral_lora_pkt_len_modes_t header_type, + uint32_t preamble_size, uint8_t symb_nb_timeout); + +/** + * @brief Test mode RX FSK continue * @remark Continuously receive packets. * * @param [in] frequency_hz Frequency in Hz - * @param [in] sf Spreading factor following smtc_modem_test_sf_t definition - * @param [in] bw Bandwith following smtc_modem_test_bw_t definition - * @param [in] cr Coding rate following smtc_modem_test_cr_t definition * * @return Modem return code as defined in @ref smtc_modem_return_code_t */ -smtc_modem_return_code_t smtc_modem_test_rx_continuous( uint32_t frequency_hz, smtc_modem_test_sf_t sf, - smtc_modem_test_bw_t bw, smtc_modem_test_cr_t cr ); +smtc_modem_return_code_t smtc_modem_test_rx_fsk_continuous( uint32_t frequency_hz ); /** * @brief Read number of received packets during test RX continue @@ -208,16 +222,29 @@ smtc_modem_return_code_t smtc_modem_test_rx_continuous( uint32_t frequency_hz, s smtc_modem_return_code_t smtc_modem_test_get_nb_rx_packets( uint32_t* nb_rx_packets ); /** - * @brief Test mode RSSI + * @brief Read last received packet during test RX continue + * @remark + * @param [out] rssi* RSSI in dBm + * @param [out] snr* SNR in dB + * @param [out] rx_payload* Pointer to the buffer to store the received payload + * @param [out] rx_payload_length* Length of the received payload + * @return Modem return code as defined in @ref smtc_modem_return_code_t + */ +smtc_modem_return_code_t smtc_modem_test_get_last_rx_packets( int16_t* rssi, int16_t* snr, uint8_t* rx_payload, + uint8_t* rx_payload_length ); + +/** + * @brief Test mode RSSI LBT * @remark Measure continuously the RSSI during a chosen time and give an average value * * @param [in] frequency_hz Frequency in Hz - * @param [in] bw bandwidth following smtc_modem_test_bw_t definition + * @param [in] bw bandwidth in Hz * @param [in] time_ms test duration in ms (1 rssi every 10 ms) * @return Modem return code as defined in @ref smtc_modem_return_code_t */ -smtc_modem_return_code_t smtc_modem_test_rssi( uint32_t frequency_hz, smtc_modem_test_bw_t bw, uint16_t time_ms ); + +smtc_modem_return_code_t smtc_modem_test_rssi_lbt( uint32_t frequency_hz, uint32_t bw_hz, uint16_t time_ms ); /** * @brief Get RSSI result (to be called when test rssi is finished) diff --git a/lbm_lib/smtc_modem_core/geolocation_services/mw_wifi_scan.c b/lbm_lib/smtc_modem_core/geolocation_services/mw_wifi_scan.c index 778feac..d0589d4 100644 --- a/lbm_lib/smtc_modem_core/geolocation_services/mw_wifi_scan.c +++ b/lbm_lib/smtc_modem_core/geolocation_services/mw_wifi_scan.c @@ -97,7 +97,7 @@ #ifndef WIFI_SCAN_DEEP_DBG_TRACE #define WIFI_SCAN_DEEP_DBG_TRACE MODEM_HAL_FEATURE_OFF #endif -#if( WIFI_SCAN_DEEP_DBG_TRACE ) +#if ( WIFI_SCAN_DEEP_DBG_TRACE ) #define WIFI_SCAN_TRACE_PRINTF_DEBUG( ... ) SMTC_MODEM_HAL_TRACE_PRINTF( __VA_ARGS__ ) #define WIFI_SCAN_TRACE_ARRAY_DEBUG( ... ) SMTC_MODEM_HAL_TRACE_ARRAY( __VA_ARGS__ ) #else @@ -391,7 +391,7 @@ static void wifi_rp_task_launch( void* context ) if( mw_radio_configure_for_scan( modem_get_radio_ctx( ) ) == false ) { - SMTC_MODEM_HAL_TRACE_ERROR( "gnss_rp_task_launch: mw_radio_configure_for_scan() failed\n" ); + SMTC_MODEM_HAL_TRACE_ERROR( "wifi_rp_task_launch: mw_radio_configure_for_scan() failed\n" ); rp_task_abort( modem_get_rp( ), RP_HOOK_ID_DIRECT_RP_ACCESS_WIFI ); return; } diff --git a/lbm_lib/smtc_modem_core/smtc_modem_hal_dbg_trace.h b/lbm_lib/smtc_modem_core/logging/smtc_modem_hal_dbg_trace.h similarity index 99% rename from lbm_lib/smtc_modem_core/smtc_modem_hal_dbg_trace.h rename to lbm_lib/smtc_modem_core/logging/smtc_modem_hal_dbg_trace.h index 6588358..97ae627 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_hal_dbg_trace.h +++ b/lbm_lib/smtc_modem_core/logging/smtc_modem_hal_dbg_trace.h @@ -52,7 +52,7 @@ extern "C" { * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define MODEM_HAL_FEATURE_OFF 0 #define MODEM_HAL_FEATURE_ON !MODEM_HAL_FEATURE_OFF @@ -72,14 +72,14 @@ extern "C" { #ifndef MODEM_HAL_DEEP_DBG_TRACE #define MODEM_HAL_DEEP_DBG_TRACE MODEM_HAL_FEATURE_OFF #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #if ( MODEM_HAL_DBG_TRACE_COLOR == MODEM_HAL_FEATURE_ON ) #define MODEM_HAL_DBG_TRACE_COLOR_BLACK "\x1B[0;30m" #define MODEM_HAL_DBG_TRACE_COLOR_RED "\x1B[0;31m" @@ -229,7 +229,7 @@ extern "C" { #define SMTC_MODEM_HAL_RP_TRACE_MSG( msg ) #define SMTC_MODEM_HAL_RP_TRACE_PRINTF( ... ) #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lorawan_api/lorawan_api.c b/lbm_lib/smtc_modem_core/lorawan_api/lorawan_api.c index 4d58286..9c61d82 100644 --- a/lbm_lib/smtc_modem_core/lorawan_api/lorawan_api.c +++ b/lbm_lib/smtc_modem_core/lorawan_api/lorawan_api.c @@ -950,7 +950,7 @@ void lorawan_api_set_no_rx_windows( uint8_t stack_id, uint8_t disable_rx_windows lr1mac_core_set_no_rx_windows( &lr1_mac_obj[stack_id], disable_rx_windows ); } -uint8_t lorawan_api_get_no_rx_windows( uint8_t stack_id, uint8_t disable_rx_windows ) +uint8_t lorawan_api_get_no_rx_windows( uint8_t stack_id ) { return lr1mac_core_get_no_rx_windows( &lr1_mac_obj[stack_id] ); } diff --git a/lbm_lib/smtc_modem_core/lorawan_api/lorawan_api.h b/lbm_lib/smtc_modem_core/lorawan_api/lorawan_api.h index f19e088..5913a62 100644 --- a/lbm_lib/smtc_modem_core/lorawan_api/lorawan_api.h +++ b/lbm_lib/smtc_modem_core/lorawan_api/lorawan_api.h @@ -649,10 +649,9 @@ void lorawan_api_set_no_rx_windows( uint8_t stack_id, uint8_t disable_rx_windows * @brief Get the status disable/enable Rx windows after a Tx * * @param stack_id - * @param disable_rx_windows * @return uint8_t */ -uint8_t lorawan_api_get_no_rx_windows( uint8_t stack_id, uint8_t disable_rx_windows ); +uint8_t lorawan_api_get_no_rx_windows( uint8_t stack_id ); /** * @brief Set the threshold number of uplinks without downlink before reset stack @@ -1071,7 +1070,7 @@ void lorawan_api_set_next_tx_at_time( uint8_t stack_id, bool is_send_at_time ); * @param [in] stack_id Stack identifier * @param [in] join_status_t join_status */ -void lorawan_api_set_join_status(uint8_t stack_id, join_status_t join_status ); +void lorawan_api_set_join_status( uint8_t stack_id, join_status_t join_status ); #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_cid_request_management.c b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_cid_request_management.c index f8f6e0c..c7f8c6b 100644 --- a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_cid_request_management.c +++ b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_cid_request_management.c @@ -53,13 +53,9 @@ * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- */ -#define STACK_ID_CURRENT_TASK \ - ( ( stask_manager* ) context )->modem_task[( ( stask_manager* ) context )->next_task_id].stack_id -#define CURRENT_TASK_ID ( ( stask_manager* ) context )->next_task_id - ( NUMBER_OF_TASKS * STACK_ID_CURRENT_TASK ) -#define CURRENT_TASK_TIME \ - ( ( stask_manager* ) context )->modem_task[( ( stask_manager* ) context )->next_task_id].time_to_execute_s -#define CURRENT_TASK_CONTEXT \ - ( ( stask_manager* ) context )->modem_task[( ( stask_manager* ) context )->next_task_id].task_context +#define VIRTUAL_TASK_ID ( ( stask_manager* ) context )->next_task_id +#define STACK_ID_CURRENT_TASK ( ( stask_manager* ) context )->modem_task[VIRTUAL_TASK_ID].stack_id +#define CURRENT_TASK_CONTEXT ( ( stask_manager* ) context )->modem_task[VIRTUAL_TASK_ID].task_context /** * @brief Check is the index is valid before accessing the object @@ -182,8 +178,8 @@ static void lorawan_cid_request_management_on_launch( void* context ) if( ( cid_request_size > 0 ) && ( cid_request_size <= MAX_NUMBER_OF_CIQ_REQUEST ) ) { - tx_protocol_manager_request (TX_PROTOCOL_TRANSMIT_CID, 0, false, cid_buffer, cid_request_size, 0, - smtc_modem_hal_get_time_in_ms( ), STACK_ID_CURRENT_TASK ); + tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_CID, 0, false, cid_buffer, cid_request_size, 0, + smtc_modem_hal_get_time_in_ms( ), STACK_ID_CURRENT_TASK ); } } diff --git a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_class_b_management.c b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_class_b_management.c index f00932a..eee89cd 100644 --- a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_class_b_management.c +++ b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_class_b_management.c @@ -53,10 +53,8 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ -#define CURRENT_STACK ( task_id / NUMBER_OF_TASKS ) -#define STACK_ID_CURRENT_TASK \ - ( ( stask_manager* ) context )->modem_task[( ( stask_manager* ) context )->next_task_id].stack_id -#define CURRENT_TASK_ID ( ( stask_manager* ) context )->next_task_id - ( NUMBER_OF_TASKS * STACK_ID_CURRENT_TASK ) +#define VIRTUAL_TASK_ID ( ( stask_manager* ) context )->next_task_id +#define STACK_ID_CURRENT_TASK ( ( stask_manager* ) context )->modem_task[VIRTUAL_TASK_ID].stack_id /** * @brief Check is the index is valid before accessing the object @@ -315,7 +313,7 @@ static uint8_t lorawan_class_b_management_service_downlink_handler( lr1_stack_ma if( stack_id >= NUMBER_MAX_OF_CLASS_B_MANAGEMENT_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } diff --git a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_dwn_ack_management.c b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_dwn_ack_management.c index 14be005..127fae0 100644 --- a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_dwn_ack_management.c +++ b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_dwn_ack_management.c @@ -52,11 +52,9 @@ * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- */ -#define STACK_ID_CURRENT_TASK \ - ( ( stask_manager* ) context )->modem_task[( ( stask_manager* ) context )->next_task_id].stack_id -#define CURRENT_TASK_ID ( ( stask_manager* ) context )->next_task_id - ( NUMBER_OF_TASKS * STACK_ID_CURRENT_TASK ) -#define CURRENT_TASK_TIME \ - ( ( stask_manager* ) context )->modem_task[( ( stask_manager* ) context )->next_task_id].time_to_execute_s +#define VIRTUAL_TASK_ID ( ( stask_manager* ) context )->next_task_id +#define STACK_ID_CURRENT_TASK ( ( stask_manager* ) context )->modem_task[VIRTUAL_TASK_ID].stack_id +#define CURRENT_TASK_TIME ( ( stask_manager* ) context )->modem_task[VIRTUAL_TASK_ID].time_to_execute_s /** * @brief Check is the index is valid before accessing the object @@ -153,7 +151,8 @@ static void lorawan_dwn_ack_management_on_launch( void* context ) if( ( smtc_modem_hal_get_time_in_s( ) <= ( CURRENT_TASK_TIME + 2 ) ) && ( lorawan_api_tx_ack_bit_get( STACK_ID_CURRENT_TASK ) ) ) { - lorawan_send_add_task( STACK_ID_CURRENT_TASK, 1, false, false, NULL, 0, false, 0 ); + tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_LORA, 1, false, NULL, 0, UNCONF_DATA_UP, + smtc_modem_hal_get_time_in_ms( ), STACK_ID_CURRENT_TASK ); } else { diff --git a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_join_management.c b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_join_management.c index 345c2c7..716dbb4 100644 --- a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_join_management.c +++ b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_join_management.c @@ -52,9 +52,8 @@ * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- */ -#define STACK_ID_CURRENT_TASK \ - ( ( stask_manager* ) context )->modem_task[( ( stask_manager* ) context )->next_task_id].stack_id -#define CURRENT_TASK_ID ( ( stask_manager* ) context )->next_task_id - ( NUMBER_OF_TASKS * STACK_ID_CURRENT_TASK ) +#define VIRTUAL_TASK_ID ( ( stask_manager* ) context )->next_task_id +#define STACK_ID_CURRENT_TASK ( ( stask_manager* ) context )->modem_task[VIRTUAL_TASK_ID].stack_id #define NAP 0 /** * @brief Check is the index is valid before accessing the object @@ -112,7 +111,7 @@ static uint8_t lorawan_join_management_service_downlink_handler( lr1_stack_mac_d * * @param stack_id */ -static void lorawan_join_internal_add_task( uint8_t stack_id ); +static void lorawan_join_internal_add_task( uint8_t stack_id, uint32_t current_time_s ); static uint8_t nap = 0; /* * ----------------------------------------------------------------------------- @@ -137,7 +136,7 @@ void lorawan_join_add_task( uint8_t stack_id ) { return; } - lorawan_join_internal_add_task( stack_id ); + lorawan_join_internal_add_task( stack_id, smtc_modem_hal_get_time_in_s( ) ); } void lorawan_join_remove_task( uint8_t stack_id ) @@ -153,6 +152,7 @@ void lorawan_join_remove_task( uint8_t stack_id ) static void lorawan_join_management_service_on_launch( void* context ) { + stask_manager* task_manager = ( stask_manager* ) context; if( lorawan_api_isjoined( STACK_ID_CURRENT_TASK ) == JOINED ) { SMTC_MODEM_HAL_TRACE_WARNING( "DEVICE ALREADY JOINED\n" ); @@ -160,8 +160,17 @@ static void lorawan_join_management_service_on_launch( void* context ) else { lorawan_api_set_join_status( STACK_ID_CURRENT_TASK, JOINING ); - tx_protocol_manager_request( TX_PROTOCOL_JOIN_LORA, NAP, NAP, &nap, NAP, NAP, smtc_modem_hal_get_time_in_ms( ), - STACK_ID_CURRENT_TASK ); + status_lorawan_t status = tx_protocol_manager_request( + TX_PROTOCOL_JOIN_LORA, NAP, NAP, &nap, NAP, NAP, smtc_modem_hal_get_time_in_ms( ), STACK_ID_CURRENT_TASK ); + if( status == OKLORAWAN ) + { + task_manager->modem_task[VIRTUAL_TASK_ID].task_context = SUCCESS_TO_LAUNCH_JOIN; + } + else + { + // can happen in specific cases such as no more duty cycle for wor tx when relay tx is activated + task_manager->modem_task[VIRTUAL_TASK_ID].task_context = FAIL_TO_LAUNCH_JOIN; + } } } @@ -176,9 +185,16 @@ static void lorawan_join_management_service_on_update( void* context ) else { lorawan_api_set_join_status( STACK_ID_CURRENT_TASK, JOINING ); - if( task_manager->modem_task[CURRENT_TASK_ID].task_enabled == true ) + if( task_manager->modem_task[VIRTUAL_TASK_ID].task_enabled == true ) { - lorawan_join_internal_add_task( STACK_ID_CURRENT_TASK ); + if( task_manager->modem_task[VIRTUAL_TASK_ID].task_context == SUCCESS_TO_LAUNCH_JOIN ) + { + lorawan_join_internal_add_task( STACK_ID_CURRENT_TASK, smtc_modem_hal_get_time_in_s( ) ); + } + else + { + lorawan_join_internal_add_task( STACK_ID_CURRENT_TASK, smtc_modem_hal_get_time_in_s( ) + 120 ); + } increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_JOINFAIL, 0, STACK_ID_CURRENT_TASK ); } } @@ -192,15 +208,13 @@ static uint8_t lorawan_join_management_service_downlink_handler( lr1_stack_mac_d return MODEM_DOWNLINK_UNCONSUMED; } -static void lorawan_join_internal_add_task( uint8_t stack_id ) +static void lorawan_join_internal_add_task( uint8_t stack_id, uint32_t current_time_s ) { smodem_task task_join = { 0 }; task_join.id = JOIN_TASK + ( NUMBER_OF_TASKS * stack_id ); task_join.stack_id = stack_id; task_join.priority = TASK_MEDIUM_HIGH_PRIORITY; - uint32_t current_time_s = smtc_modem_hal_get_time_in_s( ); - task_join.time_to_execute_s = smtc_modem_hal_get_random_nb_in_range( 0, 5 ); #if defined( TEST_BYPASS_JOIN_DUTY_CYCLE ) diff --git a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_join_management.h b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_join_management.h index f86bbb6..320d5c7 100644 --- a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_join_management.h +++ b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_join_management.h @@ -61,6 +61,11 @@ extern "C" { * ----------------------------------------------------------------------------- * --- PUBLIC TYPES ------------------------------------------------------------ */ +enum +{ + SUCCESS_TO_LAUNCH_JOIN = 0, + FAIL_TO_LAUNCH_JOIN = 1 +} ; /** * @brief LoRaWAN join_management Object diff --git a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_send_management.c b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_send_management.c index 6ce2f97..d539661 100644 --- a/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_send_management.c +++ b/lbm_lib/smtc_modem_core/lorawan_manager/lorawan_send_management.c @@ -54,9 +54,8 @@ * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- */ -#define STACK_ID_CURRENT_TASK \ - ( ( stask_manager* ) context )->modem_task[( ( stask_manager* ) context )->next_task_id].stack_id -#define CURRENT_TASK_ID ( ( stask_manager* ) context )->next_task_id - ( NUMBER_OF_TASKS * STACK_ID_CURRENT_TASK ) +#define VIRTUAL_TASK_ID ( ( stask_manager* ) context )->next_task_id +#define STACK_ID_CURRENT_TASK ( ( stask_manager* ) context )->modem_task[VIRTUAL_TASK_ID].stack_id /** * @brief Check is the index is valid before accessing the object @@ -206,7 +205,7 @@ static void lorawan_send_management_service_on_launch( void* context ) if( send_status == OKLORAWAN ) { - task_manager->modem_task[CURRENT_TASK_ID].task_context = true; + task_manager->modem_task[VIRTUAL_TASK_ID].task_context = true; SMTC_MODEM_HAL_TRACE_PRINTF( " User LoRaWAN tx %s %d \n", ( lorawan_send_management_obj[STACK_ID_CURRENT_TASK].fport_present == true ) ? "on FPort" : "No FPort", @@ -214,7 +213,7 @@ static void lorawan_send_management_service_on_launch( void* context ) } else { - task_manager->modem_task[CURRENT_TASK_ID].task_context = false; + task_manager->modem_task[VIRTUAL_TASK_ID].task_context = false; SMTC_MODEM_HAL_TRACE_WARNING( "The payload can't be send! internal code: %x\n", send_status ); } } @@ -222,14 +221,14 @@ static void lorawan_send_management_service_on_launch( void* context ) static void lorawan_send_management_service_on_update( void* context ) { stask_manager* task_manager = ( stask_manager* ) context; - if( task_manager->modem_task[CURRENT_TASK_ID].priority == TASK_HIGH_PRIORITY ) + if( task_manager->modem_task[VIRTUAL_TASK_ID].priority == TASK_HIGH_PRIORITY ) { smtc_duty_cycle_enable_set( SMTC_DTC_ENABLED ); } - if( task_manager->modem_task[CURRENT_TASK_ID].task_enabled == true ) + if( task_manager->modem_task[VIRTUAL_TASK_ID].task_enabled == true ) { - if( ( task_manager->modem_task[CURRENT_TASK_ID].task_context == true ) && + if( ( task_manager->modem_task[VIRTUAL_TASK_ID].task_context == true ) && ( tx_protocol_manager_tx_is_aborted( ) == false ) ) { if( lorawan_send_management_obj[STACK_ID_CURRENT_TASK].rx_ack_bit_context == 1 ) @@ -251,7 +250,7 @@ static void lorawan_send_management_service_on_update( void* context ) static uint8_t lorawan_send_management_service_downlink_handler( lr1_stack_mac_down_data_t* rx_down_data ) { -#ifdef RELAY_TX +#if defined( ADD_RELAY_TX ) if( ( rx_down_data->rx_metadata.rx_window == RECEIVE_ON_RX2 ) || ( rx_down_data->rx_metadata.rx_window == RECEIVE_ON_RX1 ) || ( rx_down_data->rx_metadata.rx_window == RECEIVE_ON_RXR ) ) diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/application_layer_clock_synchronization/v1.0.0/lorawan_alcsync_v1.0.0.c b/lbm_lib/smtc_modem_core/lorawan_packages/application_layer_clock_synchronization/v1.0.0/lorawan_alcsync_v1.0.0.c index b2dba79..08fc31a 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/application_layer_clock_synchronization/v1.0.0/lorawan_alcsync_v1.0.0.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/application_layer_clock_synchronization/v1.0.0/lorawan_alcsync_v1.0.0.c @@ -103,7 +103,7 @@ SMTC_MODEM_HAL_PANIC_ON_FAILURE( x < NUMBER_OF_STACKS ); \ } while( 0 ) -#if( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) +#if ( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) static const char alc_sync_bad_size_str[] = "ALC Sync payload bad size"; #endif /* @@ -465,7 +465,7 @@ uint8_t lorawan_alcsync_service_downlink_handler( lr1_stack_mac_down_data_t* rx_ if( stack_id >= NUMBER_OF_ALCSYNC_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -495,7 +495,7 @@ uint8_t lorawan_alcsync_service_downlink_handler( lr1_stack_mac_down_data_t* rx_ } else #endif - if( rx_down_data->rx_metadata.rx_fport == ctx->fport ) + if( ( ctx->use_cloud_dm == false ) && ( rx_down_data->rx_metadata.rx_fport == ctx->fport ) ) { rx_payload_ptr = &rx_down_data->rx_payload[0]; rx_payload_ptr_size = rx_down_data->rx_payload_size; @@ -540,7 +540,7 @@ bool lorawan_alcsync_mpa_injector( uint8_t stack_id, uint8_t* payload_in, uint8_ if( stack_id >= NUMBER_OF_ALCSYNC_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return false; } diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/application_layer_clock_synchronization/v2.0.0/lorawan_alcsync_v2.0.0.c b/lbm_lib/smtc_modem_core/lorawan_packages/application_layer_clock_synchronization/v2.0.0/lorawan_alcsync_v2.0.0.c index 1cde08a..049f6d0 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/application_layer_clock_synchronization/v2.0.0/lorawan_alcsync_v2.0.0.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/application_layer_clock_synchronization/v2.0.0/lorawan_alcsync_v2.0.0.c @@ -103,7 +103,7 @@ SMTC_MODEM_HAL_PANIC_ON_FAILURE( x < NUMBER_OF_STACKS ); \ } while( 0 ) -#if( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) +#if ( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) static const char alc_sync_bad_size_str[] = "ALC Sync payload bad size"; #endif /* @@ -465,7 +465,7 @@ uint8_t lorawan_alcsync_service_downlink_handler( lr1_stack_mac_down_data_t* rx_ if( stack_id >= NUMBER_OF_ALCSYNC_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -495,7 +495,7 @@ uint8_t lorawan_alcsync_service_downlink_handler( lr1_stack_mac_down_data_t* rx_ } else #endif - if( rx_down_data->rx_metadata.rx_fport == ctx->fport ) + if( ( ctx->use_cloud_dm == false ) && ( rx_down_data->rx_metadata.rx_fport == ctx->fport ) ) { rx_payload_ptr = &rx_down_data->rx_payload[0]; rx_payload_ptr_size = rx_down_data->rx_payload_size; @@ -540,7 +540,7 @@ bool lorawan_alcsync_mpa_injector( uint8_t stack_id, uint8_t* payload_in, uint8_ if( stack_id >= NUMBER_OF_ALCSYNC_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return false; } diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/firmware_management_protocol/lorawan_fmp_package.c b/lbm_lib/smtc_modem_core/lorawan_packages/firmware_management_protocol/lorawan_fmp_package.c index ea9192c..e7ab82d 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/firmware_management_protocol/lorawan_fmp_package.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/firmware_management_protocol/lorawan_fmp_package.c @@ -53,6 +53,7 @@ #include "modem_core.h" #include "smtc_modem_api.h" #include "modem_tx_protocol_manager.h" +#include "lorawan_cid_request_management.h" /* * ----------------------------------------------------------------------------- @@ -186,8 +187,8 @@ typedef struct lorawan_fmp_package_s uint32_t fmp_fw_to_delete_version; uint32_t fmp_task_ctx_mask; fmp_supervisor_task_types_t fmp_current_task_ctx; - bool request_time_sync; - bool enabled; + // bool request_time_sync; + bool enabled; } lorawan_fmp_package_ctx_t; typedef enum @@ -280,8 +281,7 @@ void lorawan_fmp_package_services_init( uint8_t* service_id, uint8_t task_id, void lorawan_fmp_package_service_on_launch( void* service_id ) { - lorawan_fmp_package_ctx_t* ctx = ( lorawan_fmp_package_ctx_t* ) service_id; - uint8_t stack_id = ctx->stack_id; + lorawan_fmp_package_ctx_t* ctx = ( lorawan_fmp_package_ctx_t* ) service_id; ctx->fmp_current_task_ctx = EMPTY_TASK_MASK; @@ -300,16 +300,16 @@ void lorawan_fmp_package_service_on_launch( void* service_id ) ctx->fmp_tx_payload_ans_size = 0; } } - else if( ( ctx->fmp_task_ctx_mask & REQUEST_TIME_SYNC_TASK_MASK ) == REQUEST_TIME_SYNC_TASK_MASK ) - { - ctx->fmp_current_task_ctx = REQUEST_TIME_SYNC_TASK_MASK; - SMTC_MODEM_HAL_TRACE_PRINTF( " lorawan_fmp_package launch REQUEST_TIME_SYNC_TASK n" ); - ctx->request_time_sync = false; - cid_from_device_t cid_buffer[] = { DEVICE_TIME_REQ }; - uint8_t cid_request_size = 1; - tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_CID, 0, false, cid_buffer, cid_request_size, 0, - smtc_modem_hal_get_time_in_ms( ), stack_id ); - } + // else if( ( ctx->fmp_task_ctx_mask & REQUEST_TIME_SYNC_TASK_MASK ) == REQUEST_TIME_SYNC_TASK_MASK ) + // { + // ctx->fmp_current_task_ctx = REQUEST_TIME_SYNC_TASK_MASK; + // SMTC_MODEM_HAL_TRACE_PRINTF( " lorawan_fmp_package launch REQUEST_TIME_SYNC_TASK n" ); + // ctx->request_time_sync = false; + // cid_from_device_t cid_buffer[] = { DEVICE_TIME_REQ }; + // uint8_t cid_request_size = 1; + // tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_CID, 0, false, cid_buffer, cid_request_size, 0, + // smtc_modem_hal_get_time_in_ms( ), ctx->stack_id ); + // } else if( ( ctx->fmp_task_ctx_mask & REQUEST_REBOOT_TASK_MASK ) == REQUEST_REBOOT_TASK_MASK ) { ctx->fmp_current_task_ctx = REQUEST_REBOOT_TASK_MASK; @@ -322,15 +322,17 @@ void lorawan_fmp_package_service_on_update( void* service_id ) lorawan_fmp_package_ctx_t* ctx = ( lorawan_fmp_package_ctx_t* ) service_id; switch( ctx->fmp_current_task_ctx ) { - case ANS_CMD_TASK_MASK: { - break; - } - case REQUEST_TIME_SYNC_TASK_MASK: { - // by choice of implementation time is requested only one time - ctx->fmp_task_ctx_mask &= ~( REQUEST_TIME_SYNC_TASK_MASK ); + case ANS_CMD_TASK_MASK: + { break; } - case REQUEST_REBOOT_TASK_MASK: { + // case REQUEST_TIME_SYNC_TASK_MASK: { + // // by choice of implementation time is requested only one time + // ctx->fmp_task_ctx_mask &= ~( REQUEST_TIME_SYNC_TASK_MASK ); + // break; + // } + case REQUEST_REBOOT_TASK_MASK: + { if( ( int ) ( ctx->fmp_rtc_target_time_for_reboot - smtc_modem_hal_get_time_in_s( ) ) < 2 ) { increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_FIRMWARE_MANAGEMENT, @@ -365,7 +367,7 @@ uint8_t lorawan_fmp_package_service_downlink_handler( lr1_stack_mac_down_data_t* if( stack_id >= NUMBER_OF_FMP_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -426,7 +428,7 @@ bool lorawan_fmp_mpa_injector( uint8_t stack_id, uint8_t* payload_in, uint8_t* n if( stack_id >= NUMBER_OF_FMP_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return false; } @@ -538,7 +540,8 @@ static fmp_status_t fmp_package_parser( lorawan_fmp_package_ctx_t* ctx, uint8_t* { switch( fmp_package_rx_buffer[fmp_package_rx_buffer_index] ) { - case FMP_PKG_VERSION_REQ: { + case FMP_PKG_VERSION_REQ: + { IS_VALID_PKG_CMD( FMP_PKG_VERSION_REQ_SIZE ); fmp_package_rx_buffer_index += FMP_PKG_VERSION_REQ_SIZE; if( ( ans_index + FMP_PKG_VERSION_ANS_SIZE ) <= max_payload_size ) @@ -552,7 +555,8 @@ static fmp_status_t fmp_package_parser( lorawan_fmp_package_ctx_t* ctx, uint8_t* break; } - case FMP_DEV_VERSION_REQ: { + case FMP_DEV_VERSION_REQ: + { IS_VALID_PKG_CMD( FMP_DEV_VERSION_REQ_SIZE ); fmp_package_rx_buffer_index += FMP_DEV_VERSION_REQ_SIZE; if( ( ans_index + FMP_DEV_VERSION_ANS_SIZE ) <= max_payload_size ) @@ -573,7 +577,8 @@ static fmp_status_t fmp_package_parser( lorawan_fmp_package_ctx_t* ctx, uint8_t* } break; } - case FMP_DEV_REBOOT_TIME_REQ: { + case FMP_DEV_REBOOT_TIME_REQ: + { IS_VALID_PKG_CMD( FMP_DEV_REBOOT_TIME_REQ_SIZE ); uint32_t fmp_reboot_time = fmp_package_rx_buffer[fmp_package_rx_buffer_index + 1] + ( fmp_package_rx_buffer[fmp_package_rx_buffer_index + 2] << 8 ) + @@ -653,12 +658,15 @@ static fmp_status_t fmp_package_parser( lorawan_fmp_package_ctx_t* ctx, uint8_t* ctx->fmp_task_ctx_mask |= ANS_CMD_TASK_MASK; } - ctx->fmp_task_ctx_mask |= REQUEST_TIME_SYNC_TASK_MASK; + // ctx->fmp_task_ctx_mask |= REQUEST_TIME_SYNC_TASK_MASK; + smtc_modem_lorawan_mac_request_mask_t cid_request_mask = SMTC_MODEM_LORAWAN_MAC_REQ_DEVICE_TIME; + lorawan_cid_request_add_task( stack_id, cid_request_mask, 1 ); } } break; } - case FMP_DEV_REBOOT_COUNT_DOWN_REQ: { + case FMP_DEV_REBOOT_COUNT_DOWN_REQ: + { IS_VALID_PKG_CMD( FMP_DEV_REBOOT_COUNT_DOWN_REQ_SIZE ); uint32_t fmp_count_down = fmp_package_rx_buffer[fmp_package_rx_buffer_index + 1] + ( fmp_package_rx_buffer[fmp_package_rx_buffer_index + 2] << 8 ) + @@ -708,7 +716,8 @@ static fmp_status_t fmp_package_parser( lorawan_fmp_package_ctx_t* ctx, uint8_t* } break; } - case FMP_DEV_UPGRADE_IMAGE_REQ: { + case FMP_DEV_UPGRADE_IMAGE_REQ: + { IS_VALID_PKG_CMD( FMP_DEV_UPGRADE_IMAGE_REQ_SIZE ); fmp_package_rx_buffer_index += FMP_DEV_UPGRADE_IMAGE_REQ_SIZE; @@ -726,13 +735,13 @@ static fmp_status_t fmp_package_parser( lorawan_fmp_package_ctx_t* ctx, uint8_t* ctx->fmp_tx_payload_ans[ans_index++] = ( next_fw_verion >> 8 ) & 0xFF; ctx->fmp_tx_payload_ans[ans_index++] = ( next_fw_verion >> 16 ) & 0xFF; ctx->fmp_tx_payload_ans[ans_index++] = ( next_fw_verion >> 24 ) & 0xFF; - - ctx->fmp_task_ctx_mask |= ANS_CMD_TASK_MASK; } + ctx->fmp_task_ctx_mask |= ANS_CMD_TASK_MASK; } break; } - case FMP_DEV_DELETE_IMAGE_REQ: { + case FMP_DEV_DELETE_IMAGE_REQ: + { IS_VALID_PKG_CMD( FMP_DEV_DELETE_IMAGE_REQ_SIZE ); ctx->fmp_fw_to_delete_version = fmp_package_rx_buffer[fmp_package_rx_buffer_index + 1] + ( fmp_package_rx_buffer[fmp_package_rx_buffer_index + 2] << 8 ) + diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/lorawan_fragmentation_package.h b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/lorawan_fragmentation_package.h index 4285f17..5ac46d1 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/lorawan_fragmentation_package.h +++ b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/lorawan_fragmentation_package.h @@ -117,7 +117,7 @@ typedef enum */ void lorawan_fragmentation_package_services_init( uint8_t* service_id, uint8_t task_id, uint8_t ( **downlink_callback )( lr1_stack_mac_down_data_t* ), - void ( **on_launch_callback )( void* ), + void ( **on_launch_callback )( void* ), void ( **on_update_callback )( void* ), void** context_callback ); /** @@ -179,6 +179,14 @@ bool lorawan_fragmentation_package_service_mpa_injector( uint8_t stack_id, uint8 const uint8_t max_payload_out_length, uint32_t rx_timestamp_ms ); +/** + * @brief Get the downloaded file size + * + * @param stack_id The requested stack_id + * @param file_size The file size in bytes + */ +void lorawan_fragmentation_package_get_file_size( uint8_t stack_id, uint32_t* file_size ); + #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v1.0.0/fragmentation_helper_v1.0.0.c b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v1.0.0/fragmentation_helper_v1.0.0.c index 6a56c88..96d20a9 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v1.0.0/fragmentation_helper_v1.0.0.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v1.0.0/fragmentation_helper_v1.0.0.c @@ -224,6 +224,7 @@ static FragDecoder_t FragDecoder; void FragDecoderInit( uint16_t fragNb, uint8_t fragSize, FragDecoderCallbacks_t* callbacks ) { + memset( &FragDecoder, 0, sizeof( FragDecoder ) ); FragDecoder.Callbacks = callbacks; FragDecoder.FragNb = fragNb; // FragNb = FRAG_MAX_SIZE FragDecoder.FragSize = fragSize; // number of byte on a row diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v1.0.0/lorawan_fragmentation_package_v1.0.0.c b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v1.0.0/lorawan_fragmentation_package_v1.0.0.c index 3766fdc..fccc8ed 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v1.0.0/lorawan_fragmentation_package_v1.0.0.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v1.0.0/lorawan_fragmentation_package_v1.0.0.c @@ -117,7 +117,14 @@ #define FRAGMENTATION_PORT 201 #define FRAGMENTATION_ID 3 #define FRAGMENTATION_VERSION 1 + +#if !defined( FRAGMENTATION_MAX_NB_SESSIONS ) #define FRAGMENTATION_MAX_NB_SESSIONS 4 +#else +#if ( FRAGMENTATION_MAX_NB_SESSIONS > 4 ) +#error "FRAGMENTATION_MAX_NB_SESSIONS MAX is 4" +#endif +#endif // Request message sizes (with header) #define FRAGMENTATION_PKG_VERSION_REQ_SIZE ( 1 ) #define FRAGMENTATION_SESSION_STATUS_REQ_SIZE ( 2 ) @@ -249,7 +256,7 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package void lorawan_fragmentation_package_services_init( uint8_t* service_id, uint8_t task_id, uint8_t ( **downlink_callback )( lr1_stack_mac_down_data_t* ), - void ( **on_launch_callback )( void* ), + void ( **on_launch_callback )( void* ), void ( **on_update_callback )( void* ), void** context_callback ) { SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( @@ -279,8 +286,8 @@ void lorawan_fragmentation_package_service_on_launch( void* service_id ) { if( lorawan_fragmentation_package_ctx[*( uint8_t* ) service_id].fragmentation_tx_payload_ans_size > 0 ) { - tx_protocol_manager_request (TX_PROTOCOL_TRANSMIT_LORA, - FRAGMENTATION_PORT, true, + tx_protocol_manager_request( + TX_PROTOCOL_TRANSMIT_LORA, FRAGMENTATION_PORT, true, lorawan_fragmentation_package_ctx[*( uint8_t* ) service_id].fragmentation_tx_payload_ans, lorawan_fragmentation_package_ctx[*( uint8_t* ) service_id].fragmentation_tx_payload_ans_size, UNCONF_DATA_UP, @@ -306,7 +313,7 @@ uint8_t lorawan_fragmentation_package_service_downlink_handler( lr1_stack_mac_do uint8_t stack_id = rx_down_data->stack_id; if( stack_id >= NUMBER_OF_FRAGMENTED_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -360,7 +367,7 @@ bool lorawan_fragmentation_package_service_mpa_injector( uint8_t stack_id, uint8 if( stack_id >= NUMBER_OF_FRAGMENTED_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return false; } @@ -484,7 +491,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package { switch( fragmentation_package_rx_buffer[fragmentation_package_rx_buffer_index] ) { - case FRAGMENTATION_PKG_VERSION_REQ: { + case FRAGMENTATION_PKG_VERSION_REQ: + { IS_VALID_PKG_CMD( FRAGMENTATION_PKG_VERSION_REQ_SIZE ); fragmentation_package_rx_buffer_index += FRAGMENTATION_PKG_VERSION_REQ_SIZE; if( is_received_on_multicast_window( fragmentation_package_rx_window ) == true ) @@ -501,7 +509,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package break; } - case FRAGMENTATION_SESSION_STATUS_REQ: { + case FRAGMENTATION_SESSION_STATUS_REQ: + { IS_VALID_PKG_CMD( FRAGMENTATION_SESSION_STATUS_REQ_SIZE ); uint8_t frag_index = @@ -524,7 +533,7 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package ctx->fragmentation_tx_payload_ans[ans_index++] = ( frag_index << 6 ) | ( ( nb_frag_received >> 8 ) & 0x3F ); ctx->fragmentation_tx_payload_ans[ans_index++] = - frag_session_data[frag_index].frag_decoder_status.MissingFrag; + frag_session_data[frag_index].frag_decoder_status.MissingFrag; ctx->fragmentation_tx_payload_ans[ans_index++] = frag_session_data[frag_index].frag_decoder_status.MatrixError & 0x01; @@ -535,7 +544,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package } break; } - case FRAGMENTATION_SESSION_SETUP_REQ: { + case FRAGMENTATION_SESSION_SETUP_REQ: + { IS_VALID_PKG_CMD( FRAGMENTATION_SESSION_SETUP_REQ_SIZE ); if( is_received_on_multicast_window( fragmentation_package_rx_window ) == true ) @@ -626,7 +636,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package break; } - case FRAGMENTATION_SESSION_DELETE_REQ: { + case FRAGMENTATION_SESSION_DELETE_REQ: + { IS_VALID_PKG_CMD( FRAGMENTATION_SESSION_DELETE_REQ_SIZE ); if( is_received_on_multicast_window( fragmentation_package_rx_window ) == true ) @@ -656,7 +667,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package break; } - case FRAGMENTATION_DATA_FRAGMENT: { + case FRAGMENTATION_DATA_FRAGMENT: + { uint8_t frag_index = 0; uint16_t frag_counter = 0; @@ -672,45 +684,48 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package SMTC_MODEM_HAL_TRACE_PRINTF( "Fuota fragmentation_package_rx_window %d\n", fragmentation_package_rx_window ); - if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x1 ) == 0x1 ) + if( frag_index < FRAGMENTATION_MAX_NB_SESSIONS ) { - if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP0 ) || - ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP0 ) ) + if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x1 ) == 0x1 ) { - accept_data = true; + if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP0 ) || + ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP0 ) ) + { + accept_data = true; + } } - } - if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x2 ) == 0x2 ) - { - if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP1 ) || - ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP1 ) ) + if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x2 ) == 0x2 ) { - accept_data = true; + if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP1 ) || + ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP1 ) ) + { + accept_data = true; + } } - } - if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x4 ) == 0x4 ) - { - if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP2 ) || - ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP2 ) ) + if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x4 ) == 0x4 ) { - accept_data = true; + if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP2 ) || + ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP2 ) ) + { + accept_data = true; + } } - } - if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x8 ) == 0x8 ) - { - if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP3 ) || - ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP3 ) ) + if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x8 ) == 0x8 ) { - accept_data = true; + if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP3 ) || + ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP3 ) ) + { + accept_data = true; + } } - } - if( is_received_on_multicast_window( fragmentation_package_rx_window ) == false ) - { - accept_data = true; + if( is_received_on_multicast_window( fragmentation_package_rx_window ) == false ) + { + accept_data = true; + } } if( accept_data == true ) @@ -759,7 +774,9 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_LORAWAN_FUOTA_DONE, status, stack_id ); } } - fragmentation_package_rx_buffer_index += frag_session_data[frag_index].frag_group_data.frag_size + 3; + // A message MAY carry more than one command, except for the DataFragment command, + // which SHALL be the only command in a message’s payload + fragmentation_package_rx_buffer_index += fragmentation_package_rx_buffer_length; break; } default: diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v2.0.0/fragmentation_helper_v2.0.0.c b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v2.0.0/fragmentation_helper_v2.0.0.c index 2cfd0f9..cc120be 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v2.0.0/fragmentation_helper_v2.0.0.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v2.0.0/fragmentation_helper_v2.0.0.c @@ -224,6 +224,7 @@ static FragDecoder_t FragDecoder; void FragDecoderInit( uint16_t fragNb, uint8_t fragSize, FragDecoderCallbacks_t* callbacks ) { + memset( &FragDecoder, 0, sizeof( FragDecoder ) ); FragDecoder.Callbacks = callbacks; FragDecoder.FragNb = fragNb; // FragNb = FRAG_MAX_SIZE FragDecoder.FragSize = fragSize; // number of byte on a row diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v2.0.0/lorawan_fragmentation_package_v2.0.0.c b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v2.0.0/lorawan_fragmentation_package_v2.0.0.c index 596b7ec..5b5df0d 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v2.0.0/lorawan_fragmentation_package_v2.0.0.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/fragmented_data_block_transport/v2.0.0/lorawan_fragmentation_package_v2.0.0.c @@ -118,7 +118,14 @@ #define FRAGMENTATION_PORT 201 #define FRAGMENTATION_ID 3 #define FRAGMENTATION_VERSION 2 + +#if !defined( FRAGMENTATION_MAX_NB_SESSIONS ) #define FRAGMENTATION_MAX_NB_SESSIONS 4 +#else +#if ( FRAGMENTATION_MAX_NB_SESSIONS > 4 ) +#error "FRAGMENTATION_MAX_NB_SESSIONS MAX is 4" +#endif +#endif // Request message sizes (with header) #define FRAGMENTATION_PKG_VERSION_REQ_SIZE ( 1 ) #define FRAGMENTATION_SESSION_STATUS_REQ_SIZE ( 2 ) @@ -169,6 +176,7 @@ typedef struct lorawan_fragmentation_package_s bool is_pending_task; bool enabled; uint8_t frag_index_data_block_rcv_req; + uint32_t file_done_size; } lorawan_fragmentation_package_ctx_t; @@ -204,12 +212,21 @@ typedef struct frag_session_data_s int32_t frag_decoder_process_status; } frag_session_data_t; -static uint8_t nb_transmit_ans; -static frag_session_data_t frag_session_data[FRAGMENTATION_MAX_NB_SESSIONS]; -static FragDecoderCallbacks_t frag_decoder_callback; -static int8_t frag_decoder_write( uint32_t addr, uint8_t* data, uint32_t size ); -static int8_t frag_decoder_read( uint32_t addr, uint8_t* data, uint32_t size ); -static uint8_t compute_data_block_integrity_ckeck( uint8_t frag_index, uint8_t stack_id ); +typedef struct lr1_frag_pkg_s +{ + uint8_t nb_transmit_ans; + frag_session_data_t frag_session_data[FRAGMENTATION_MAX_NB_SESSIONS]; + FragDecoderCallbacks_t frag_decoder_callback; +} lr1_frag_pkg_t; + +static lr1_frag_pkg_t lr1_frag_pkg_ctx; +#define nb_transmit_ans lr1_frag_pkg_ctx.nb_transmit_ans +#define frag_session_data lr1_frag_pkg_ctx.frag_session_data +#define frag_decoder_callback lr1_frag_pkg_ctx.frag_decoder_callback + +static int8_t frag_decoder_write( uint32_t addr, uint8_t* data, uint32_t size ); +static int8_t frag_decoder_read( uint32_t addr, uint8_t* data, uint32_t size ); +static uint8_t compute_data_block_integrity_ckeck( uint8_t frag_index, uint8_t stack_id ); /* ----------------------------------------------------------------------------- * --- PRIVATE VARIABLES ------------------------------------------------------- @@ -325,7 +342,7 @@ uint8_t lorawan_fragmentation_package_service_downlink_handler( lr1_stack_mac_do uint8_t stack_id = rx_down_data->stack_id; if( stack_id >= NUMBER_OF_FRAGMENTED_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -395,7 +412,7 @@ bool lorawan_fragmentation_package_service_mpa_injector( uint8_t stack_id, uint8 if( stack_id >= NUMBER_OF_FRAGMENTED_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return false; } @@ -446,6 +463,14 @@ bool lorawan_fragmentation_package_service_mpa_injector( uint8_t stack_id, uint8 } } +void lorawan_fragmentation_package_get_file_size( uint8_t stack_id, uint32_t* file_size ) +{ + uint8_t service_id; + lorawan_fragmentation_package_ctx_t* ctx = + lorawan_fragmentation_package_get_ctx_from_stack_id( stack_id, &service_id ); + + *file_size = ctx->file_done_size; +} /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- @@ -519,7 +544,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package { switch( fragmentation_package_rx_buffer[fragmentation_package_rx_buffer_index] ) { - case FRAGMENTATION_PKG_VERSION_REQ: { + case FRAGMENTATION_PKG_VERSION_REQ: + { IS_VALID_PKG_CMD( FRAGMENTATION_PKG_VERSION_REQ_SIZE ); fragmentation_package_rx_buffer_index += FRAGMENTATION_PKG_VERSION_REQ_SIZE; if( is_received_on_multicast_window( fragmentation_package_rx_window ) == true ) @@ -536,7 +562,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package break; } - case FRAGMENTATION_SESSION_STATUS_REQ: { + case FRAGMENTATION_SESSION_STATUS_REQ: + { IS_VALID_PKG_CMD( FRAGMENTATION_SESSION_STATUS_REQ_SIZE ); uint8_t frag_index = @@ -592,7 +619,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package } break; } - case FRAGMENTATION_SESSION_SETUP_REQ: { + case FRAGMENTATION_SESSION_SETUP_REQ: + { IS_VALID_PKG_CMD( FRAGMENTATION_SESSION_SETUP_REQ_SIZE ); if( is_received_on_multicast_window( fragmentation_package_rx_window ) == true ) @@ -707,10 +735,12 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package ctx->fragmentation_tx_payload_ans[ans_index++] = FRAGMENTATION_SESSION_SETUP_ANS; ctx->fragmentation_tx_payload_ans[ans_index++] = status; } + ctx->file_done_size = 0; break; } - case FRAGMENTATION_SESSION_DELETE_REQ: { + case FRAGMENTATION_SESSION_DELETE_REQ: + { IS_VALID_PKG_CMD( FRAGMENTATION_SESSION_DELETE_REQ_SIZE ); if( is_received_on_multicast_window( fragmentation_package_rx_window ) == true ) @@ -740,7 +770,8 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package break; } - case FRAGMENTATION_DATA_FRAGMENT: { + case FRAGMENTATION_DATA_FRAGMENT: + { uint8_t frag_index = 0; uint16_t frag_counter = 0; @@ -756,45 +787,48 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package SMTC_MODEM_HAL_TRACE_PRINTF( "Fuota fragmentation_package_rx_window %d\n", fragmentation_package_rx_window ); - if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x1 ) == 0x1 ) + if( frag_index < FRAGMENTATION_MAX_NB_SESSIONS ) { - if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP0 ) || - ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP0 ) ) + if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x1 ) == 0x1 ) { - accept_data = true; + if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP0 ) || + ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP0 ) ) + { + accept_data = true; + } } - } - if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x2 ) == 0x2 ) - { - if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP1 ) || - ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP1 ) ) + if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x2 ) == 0x2 ) { - accept_data = true; + if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP1 ) || + ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP1 ) ) + { + accept_data = true; + } } - } - if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x4 ) == 0x4 ) - { - if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP2 ) || - ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP2 ) ) + if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x4 ) == 0x4 ) { - accept_data = true; + if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP2 ) || + ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP2 ) ) + { + accept_data = true; + } } - } - if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x8 ) == 0x8 ) - { - if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP3 ) || - ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP3 ) ) + if( ( frag_session_data[frag_index].frag_group_data.frag_session.mc_group_bit_mask & 0x8 ) == 0x8 ) { - accept_data = true; + if( ( fragmentation_package_rx_window == RECEIVE_ON_RXB_MC_GRP3 ) || + ( fragmentation_package_rx_window == RECEIVE_ON_RXC_MC_GRP3 ) ) + { + accept_data = true; + } } - } - if( is_received_on_multicast_window( fragmentation_package_rx_window ) == false ) - { - accept_data = true; + if( is_received_on_multicast_window( fragmentation_package_rx_window ) == false ) + { + accept_data = true; + } } if( accept_data == true ) @@ -864,13 +898,22 @@ static frag_status_t fragmentation_package_parser( lorawan_fragmentation_package uint8_t status = ( frag_session_data[frag_index].frag_decoder_process_status < 255 ) ? frag_session_data[frag_index].frag_decoder_process_status : 255; + if( status == FRAG_SESSION_FINISHED_SUCCESSFULLY ) + { + ctx->file_done_size = frag_session_data[frag_index].frag_group_data.frag_nb * + frag_session_data[frag_index].frag_group_data.frag_size - + frag_session_data[frag_index].frag_group_data.padding; + } increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_LORAWAN_FUOTA_DONE, status, stack_id ); } } - fragmentation_package_rx_buffer_index += frag_session_data[frag_index].frag_group_data.frag_size + 3; + // A message MAY carry more than one command, except for the DataFragment command, + // which SHALL be the only command in a message’s payload + fragmentation_package_rx_buffer_index += fragmentation_package_rx_buffer_length; break; } - case FRAGMENTATION_DATA_BLOCK_RECEIVED_ANS: { + case FRAGMENTATION_DATA_BLOCK_RECEIVED_ANS: + { IS_VALID_PKG_CMD( FRAGMENTATION_DATA_BLOCK_RECEIVED_ANS_SIZE ); if( is_received_on_multicast_window( fragmentation_package_rx_window ) == true ) { @@ -930,10 +973,17 @@ static uint8_t compute_data_block_integrity_ckeck( uint8_t frag_index, uint8_t s // Derive key b0[0] = 0x30; +#if defined( USE_LR11XX_CE ) + if( smtc_modem_get_data_block_int_key( stack_id, key ) != SMTC_MODEM_RC_OK ) + { + return 1; + } +#else if( smtc_secure_element_aes_encrypt( b0, 16, SMTC_SE_APP_KEY, key, stack_id ) != SMTC_SE_RC_SUCCESS ) { return 1; } +#endif // USE_LR11XX_CE uint32_t size = frag_session_data[frag_index].frag_group_data.frag_nb * frag_session_data[frag_index].frag_group_data.frag_size - @@ -968,12 +1018,12 @@ static uint8_t compute_data_block_integrity_ckeck( uint8_t frag_index, uint8_t s AES_CMAC_Init( &aes_cmac_ctx ); AES_CMAC_SetKey( &aes_cmac_ctx, key ); AES_CMAC_Update( &aes_cmac_ctx, b0, 16 ); + for( uint32_t i = 0; i < size; i++ ) { frag_decoder_read( i, &d, 1 ); AES_CMAC_Update( &aes_cmac_ctx, &d, 1 ); } - AES_CMAC_Final( cmac, &aes_cmac_ctx ); uint32_t computed_mic = ( uint32_t ) ( ( uint32_t ) cmac[3] << 24 | ( uint32_t ) cmac[2] << 16 | ( uint32_t ) cmac[1] << 8 | ( uint32_t ) cmac[0] ); diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/lorawan_certification/lorawan_certification.c b/lbm_lib/smtc_modem_core/lorawan_packages/lorawan_certification/lorawan_certification.c index 37de9ba..92fecfc 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/lorawan_certification/lorawan_certification.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/lorawan_certification/lorawan_certification.c @@ -49,10 +49,16 @@ #include "modem_core.h" #include "lora_basics_modem_version.h" #include "lorawan_certification.h" +#include "modem_tx_protocol_manager.h" + #ifdef ADD_FUOTA #include "lorawan_fragmentation_package.h" #endif -#include "modem_tx_protocol_manager.h" + +#if defined( ADD_RELAY_TX ) +#include "smtc_modem_relay_api.h" +#endif + /* * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- @@ -305,7 +311,7 @@ static void lorawan_certification_service_on_launch( void* service_id ) IS_VALID_OBJECT_ID( idx ); - timestamp_launch_ms[idx] = smtc_modem_hal_get_time_in_ms( ) + 10; + timestamp_launch_ms[idx] = smtc_modem_hal_get_time_in_ms( ); if( lorawan_certification_obj[idx].cw_running == true ) { @@ -321,24 +327,27 @@ static void lorawan_certification_service_on_launch( void* service_id ) status_lorawan_t status_lorawan = ERRORLORAWAN; switch( lorawan_certification_obj[idx].is_tx_requested ) { - case LORAWAN_CERTIFICATION_TX_CERTIF_REQ: { + case LORAWAN_CERTIFICATION_TX_CERTIF_REQ: + { status_lorawan = tx_protocol_manager_request( - TX_PROTOCOL_TRANSMIT_LORA, LORAWAN_CERTIFICATION_FPORT, + TX_PROTOCOL_TRANSMIT_LORA_CERTIFICATION, LORAWAN_CERTIFICATION_FPORT, ( lorawan_certification_obj[idx].tx_buffer_length == 0 ) ? false : true, lorawan_certification_obj[idx].tx_buffer, lorawan_certification_obj[idx].tx_buffer_length, ( lorawan_certification_obj[idx].frame_type == false ) ? UNCONF_DATA_UP : CONF_DATA_UP, timestamp_launch_ms[idx], lorawan_certification_obj[idx].stack_id ); break; } - case LORAWAN_CERTIFICATION_TX_MAC_REQ: { + case LORAWAN_CERTIFICATION_TX_MAC_REQ: + { status_lorawan = tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_CID, 0, false, lorawan_certification_obj[idx].cid_req_list, - lorawan_certification_obj[idx].cid_req_list_size, 0, smtc_modem_hal_get_time_in_ms( ), + lorawan_certification_obj[idx].cid_req_list_size, 0, timestamp_launch_ms[idx], lorawan_certification_obj[idx].stack_id ); lorawan_certification_obj[idx].cid_req_list_size = 0; break; } - case LORAWAN_CERTIFICATION_JOIN_REQ: { + case LORAWAN_CERTIFICATION_JOIN_REQ: + { if( lorawan_api_isjoined( lorawan_certification_obj[idx].stack_id ) != JOINED ) { lorawan_join_add_task( lorawan_certification_obj[idx].stack_id ); @@ -346,10 +355,11 @@ static void lorawan_certification_service_on_launch( void* service_id ) break; } case LORAWAN_CERTIFICATION_NO_TX_REQ: - default: { + default: + { uint8_t buffer_tx_tmp[] = { 0x11, 0x12, 0x13, 0x14 }; status_lorawan = tx_protocol_manager_request( - TX_PROTOCOL_TRANSMIT_LORA, 1, true, buffer_tx_tmp, sizeof( buffer_tx_tmp ), + TX_PROTOCOL_TRANSMIT_LORA_CERTIFICATION, 1, true, buffer_tx_tmp, sizeof( buffer_tx_tmp ), ( lorawan_certification_obj[idx].frame_type == false ) ? UNCONF_DATA_UP : CONF_DATA_UP, timestamp_launch_ms[idx], lorawan_certification_obj[idx].stack_id ); break; @@ -384,25 +394,27 @@ static void lorawan_certification_service_on_update( void* service_id ) { if( lorawan_certification_obj[idx].cw_running == true ) { - timestamp_launch_ms[idx] = - smtc_modem_hal_get_time_in_ms( ) + ( lorawan_certification_obj[idx].cw_timeout_s * 1000 ); + task_certif.time_to_execute_s = ( timestamp_launch_ms[idx] + smtc_modem_hal_get_time_in_ms( ) + + ( lorawan_certification_obj[idx].cw_timeout_s * 1000UL ) ) / + 1000; } else { - timestamp_launch_ms[idx] += ( lorawan_certification_obj[idx].ul_periodicity_s * 1000 ); + task_certif.time_to_execute_s = + ( timestamp_launch_ms[idx] + ( lorawan_certification_obj[idx].ul_periodicity_s * 1000UL ) ) / 1000UL; } - task_certif.time_to_execute_s = timestamp_launch_ms[idx] / 1000; modem_supervisor_add_task( &task_certif ); } } + static uint8_t lorawan_certification_service_downlink_handler( lr1_stack_mac_down_data_t* rx_down_data ) { uint8_t stack_id = rx_down_data->stack_id; if( stack_id >= NUMBER_OF_CERTIF_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -438,6 +450,7 @@ static uint8_t lorawan_certification_service_downlink_handler( lr1_stack_mac_dow #if defined( ADD_SMTC_ALC_SYNC ) lorawan_alcsync_set_enabled( stack_id, true ); #endif + return MODEM_DOWNLINK_UNCONSUMED; } if( rx_down_data->rx_metadata.rx_window == RECEIVE_ON_RXBEACON ) @@ -482,6 +495,14 @@ static uint8_t lorawan_certification_service_downlink_handler( lr1_stack_mac_dow &lorawan_certification_obj[service_id], rx_down_data->rx_payload, rx_down_data->rx_payload_size, lorawan_certification_obj[service_id].tx_buffer, &lorawan_certification_obj[service_id].tx_buffer_length ); + + task_id_t current_task_id = modem_supervisor_get_task( )->next_task_id; + if( current_task_id != lorawan_certification_obj[service_id].task_id ) + { + // To recompute time for the next certif uplink in case received downlink when another service is + // running + lorawan_certification_service_on_update( &service_id ); + } } } return MODEM_DOWNLINK_CONSUMED; @@ -531,6 +552,7 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( switch( cid ) { case LORAWAN_CERTIFICATION_PACKAGE_VERSION_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_PACKAGE_VERSION_REQ_SIZE ) { tx_buffer[( *tx_buffer_length )++] = LORAWAN_CERTIFICATION_PACKAGE_VERSION_ANS; @@ -544,9 +566,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } break; - - case LORAWAN_CERTIFICATION_DUT_REST_REQ: - if( rx_buffer_length == LORAWAN_CERTIFICATION_DUT_REST_REQ_SIZE ) + } + case LORAWAN_CERTIFICATION_DUT_RESET_REQ: + { + if( rx_buffer_length == LORAWAN_CERTIFICATION_DUT_RESET_REQ_SIZE ) { SMTC_MODEM_HAL_TRACE_PRINTF( "Certif mcu reset\n" ); smtc_modem_hal_reset_mcu( ); @@ -555,9 +578,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_DUT_JOIN_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_DUT_JOIN_REQ_SIZE ) { // leave network @@ -569,9 +593,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_SWITCH_CLASS_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_SWITCH_CLASS_REQ_SIZE ) { if( rx_buffer[1] <= ( uint8_t ) LORAWAN_CERTIFICATION_CLASS_C ) @@ -587,9 +612,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_ADR_BIT_CHANGE_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_ADR_BIT_CHANGE_REQ_SIZE ) { if( rx_buffer[1] == ( uint8_t ) LORAWAN_CERTIFICATION_ADR_OFF ) @@ -608,9 +634,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_REGIONAL_DUTY_CYCLE_CTRL_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_REGIONAL_DUTY_CYCLE_CTRL_REQ_SIZE ) { if( rx_buffer[1] == ( uint8_t ) LORAWAN_CERTIFICATION_DUTY_CYCLE_OFF ) @@ -626,9 +653,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_TX_PERIODICITY_CHANGE_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_TX_PERIODICITY_CHANGE_REQ_SIZE ) { lorawan_certification->ul_periodicity_s = lorawan_certification_periodicity_table_s[rx_buffer[1]]; @@ -637,9 +665,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_TX_FRAME_CTRL_REQ: + { if( rx_buffer_length <= LORAWAN_CERTIFICATION_TX_FRAME_CTRL_REQ_SIZE ) { if( rx_buffer[1] == ( uint8_t ) LORAWAN_CERTIFICATION_FRAME_TYPE_UNCONFIRMED ) @@ -657,7 +686,9 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( } break; + } case LORAWAN_CERTIFICATION_ECHO_PLAY_REQ: + { if( rx_buffer_length <= LORAWAN_CERTIFICATION_ECHO_PLAY_REQ_SIZE ) { uint8_t max_len = @@ -679,9 +710,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_RX_APP_CNT_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_RX_APP_CNT_REQ_SIZE ) { tx_buffer[( *tx_buffer_length )++] = LORAWAN_CERTIFICATION_RX_APP_CNT_ANS; @@ -694,9 +726,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_RX_APP_CNT_RESET_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_RX_APP_CNT_RESET_REQ_SIZE ) { lorawan_certification->rx_app_cnt = 0; @@ -705,10 +738,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_LINK_CHECK_REQ: - + { if( rx_buffer_length == LORAWAN_CERTIFICATION_LINK_CHECK_REQ_SIZE ) { if( lorawan_certification->cid_req_list_size < sizeof( lorawan_certification->cid_req_list ) ) @@ -721,9 +754,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_DEVICE_TIME_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_DEVICE_TIME_REQ_SIZE ) { if( lorawan_certification->cid_req_list_size < sizeof( lorawan_certification->cid_req_list ) ) @@ -736,9 +770,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_PING_SLOT_INFO_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_PING_SLOT_INFO_REQ_SIZE ) { lorawan_api_set_ping_slot_periodicity( rx_buffer[1], lorawan_certification->stack_id ); @@ -752,9 +787,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_BEACON_RX_STATUS_IND_CTRL: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_BEACON_RX_STATUS_IND_CTRL_SIZE ) { lorawan_certification->beacon_rx_status_ind_ctrl = rx_buffer[1]; @@ -764,7 +800,9 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } break; + } case LORAWAN_CERTIFICATION_BEACON_CNT_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_BEACON_CNT_REQ_SIZE ) { tx_buffer[( *tx_buffer_length )++] = LORAWAN_CERTIFICATION_BEACON_CNT_ANS; @@ -778,8 +816,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } break; + } case LORAWAN_CERTIFICATION_FRAG_SESSION_CNT_REQ: -#if( ADD_FUOTA == 2 ) + { +#if ( ADD_FUOTA == 2 ) if( rx_buffer_length == LORAWAN_CERTIFICATION_FRAG_SESSION_CNT_REQ_SIZE ) { uint8_t frag_index = rx_buffer[1] & 0x03; @@ -804,7 +844,40 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( SMTC_MODEM_HAL_TRACE_ERROR( "Not implemented\n" ); #endif break; + } + + case LORAWAN_CERTIFICATION_RELAY_MODE_CTRL_REQ: + { +#if defined( ADD_RELAY_TX ) + if( rx_buffer_length == LORAWAN_CERTIFICATION_RELAY_MODE_CTRL_SIZE ) + { + if( rx_buffer[1] == ( uint8_t ) LORAWAN_CERTIFICATION_RELAY_TX_OFF ) + { + smtc_modem_relay_tx_disable( lorawan_certification_obj->stack_id ); + } + else + { + smtc_modem_relay_tx_config_t user_relay_config = { 0 }; + user_relay_config.second_ch_enable = false; + user_relay_config.activation = SMTC_MODEM_RELAY_TX_ACTIVATION_MODE_ED_CONTROLLED; + user_relay_config.number_of_miss_wor_ack_to_switch_in_nosync_mode = 1; + user_relay_config.smart_level = 5; + user_relay_config.backoff = 4; + + smtc_modem_relay_tx_enable( lorawan_certification_obj->stack_id, &user_relay_config ); + } + } + else + { + SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); + } +#else + SMTC_MODEM_HAL_TRACE_ERROR( "RELAY_TX not implemented\n" ); +#endif + break; + } case LORAWAN_CERTIFICATION_BEACON_CNT_RST_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_BEACON_CNT_RST_REQ_SIZE ) { lorawan_certification->rx_beacon_cnt = 0; @@ -814,7 +887,9 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } break; + } case LORAWAN_CERTIFICATION_TX_CW_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_TX_CW_REQ_SIZE ) { lorawan_certification->cw_running = true; @@ -834,9 +909,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_DUT_FPORT_224_DISABLE_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_DUT_FPORT_224_DISABLE_REQ_SIZE ) { lorawan_certification->enabled = false; @@ -847,9 +923,10 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( { SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } - break; + } case LORAWAN_CERTIFICATION_DUT_VERSION_REQ: + { if( rx_buffer_length == LORAWAN_CERTIFICATION_DUT_VERSION_REQ_SIZE ) { // Ignore command if the payload length is greater than the max payload length allowed @@ -889,7 +966,7 @@ static lorawan_certification_requested_tx_type_t lorawan_certification_parser( SMTC_MODEM_HAL_TRACE_ERROR( "bad size\n" ); } break; - + } default: SMTC_MODEM_HAL_TRACE_ERROR( "%s Illegal state(%u)\n ", __func__, cid ); SMTC_MODEM_HAL_TRACE_ARRAY( "rx_buffer", rx_buffer, rx_buffer_length ); diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/lorawan_certification/lorawan_certification.h b/lbm_lib/smtc_modem_core/lorawan_packages/lorawan_certification/lorawan_certification.h index 261dfd6..c31f473 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/lorawan_certification/lorawan_certification.h +++ b/lbm_lib/smtc_modem_core/lorawan_packages/lorawan_certification/lorawan_certification.h @@ -68,7 +68,7 @@ extern "C" { */ #define LORAWAN_CERTIFICATION_PACKAGE_VERSION_REQ_SIZE 1 #define LORAWAN_CERTIFICATION_PACKAGE_VERSION_ANS_SIZE 2 -#define LORAWAN_CERTIFICATION_DUT_REST_REQ_SIZE 1 +#define LORAWAN_CERTIFICATION_DUT_RESET_REQ_SIZE 1 #define LORAWAN_CERTIFICATION_DUT_JOIN_REQ_SIZE 1 #define LORAWAN_CERTIFICATION_SWITCH_CLASS_REQ_SIZE 2 #define LORAWAN_CERTIFICATION_ADR_BIT_CHANGE_REQ_SIZE 2 @@ -96,6 +96,8 @@ extern "C" { #define LORAWAN_CERTIFICATION_FRAG_SESSION_CNT_REQ_SIZE 2 +#define LORAWAN_CERTIFICATION_RELAY_MODE_CTRL_SIZE 2 + #define LORAWAN_CERTIFICATION_FPORT 224 /* * ----------------------------------------------------------------------------- @@ -123,7 +125,7 @@ typedef enum lorawan_certification_cid_dut_e LORAWAN_CERTIFICATION_ECHO_PLAY_ANS = 0x08, LORAWAN_CERTIFICATION_RX_APP_CNT_ANS = 0x09, LORAWAN_CERTIFICATION_BEACON_RX_STATUS_IND = 0x41, - LORAWAN_CERTIFICATION_BEACON_CNT_ANS = 0x42, + LORAWAN_CERTIFICATION_BEACON_CNT_ANS = 0x43, LORAWAN_CERTIFICATION_FRAG_SESSION_CNT_ANS = 0x52, LORAWAN_CERTIFICATION_DUT_VERSION_ANS = 0x7F, } lorawan_certification_cid_dut_t; @@ -136,7 +138,7 @@ typedef enum lorawan_certification_cid_dut_e typedef enum lorawan_certification_cid_tcl_e { LORAWAN_CERTIFICATION_PACKAGE_VERSION_REQ = 0x00, - LORAWAN_CERTIFICATION_DUT_REST_REQ = 0x01, + LORAWAN_CERTIFICATION_DUT_RESET_REQ = 0x01, LORAWAN_CERTIFICATION_DUT_JOIN_REQ = 0x02, LORAWAN_CERTIFICATION_SWITCH_CLASS_REQ = 0x03, LORAWAN_CERTIFICATION_ADR_BIT_CHANGE_REQ = 0x04, @@ -151,8 +153,9 @@ typedef enum lorawan_certification_cid_tcl_e LORAWAN_CERTIFICATION_PING_SLOT_INFO_REQ = 0x22, LORAWAN_CERTIFICATION_BEACON_RX_STATUS_IND_CTRL = 0x40, LORAWAN_CERTIFICATION_BEACON_CNT_REQ = 0x42, - LORAWAN_CERTIFICATION_BEACON_CNT_RST_REQ = 0x43, + LORAWAN_CERTIFICATION_BEACON_CNT_RST_REQ = 0x44, LORAWAN_CERTIFICATION_FRAG_SESSION_CNT_REQ = 0x52, + LORAWAN_CERTIFICATION_RELAY_MODE_CTRL_REQ = 0x53, LORAWAN_CERTIFICATION_TX_CW_REQ = 0x7D, LORAWAN_CERTIFICATION_DUT_FPORT_224_DISABLE_REQ = 0x7E, LORAWAN_CERTIFICATION_DUT_VERSION_REQ = 0x7F, @@ -241,6 +244,12 @@ typedef enum lorawan_certification_requested_tx_type_e LORAWAN_CERTIFICATION_JOIN_REQ = 0x03, } lorawan_certification_requested_tx_type_t; +typedef enum lorawan_certification_relay_tx_enabled_e +{ + LORAWAN_CERTIFICATION_RELAY_TX_OFF = 0x00, + LORAWAN_CERTIFICATION_RELAY_TX_ON, +} lorawan_certification_relay_tx_enabled_t; + /** * @brief LoRaWAN Certification Object * @@ -292,7 +301,7 @@ typedef struct lorawan_certification_s */ void lorawan_certification_services_init( uint8_t* service_id, uint8_t task_id, uint8_t ( **downlink_callback )( lr1_stack_mac_down_data_t* ), - void ( **on_launch_callback )( void* ), + void ( **on_launch_callback )( void* ), void ( **on_update_callback )( void* ), void** context_callback ); //////////////////////////////////////////////////////// diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/multi_package_access/lorawan_mpa_package.c b/lbm_lib/smtc_modem_core/lorawan_packages/multi_package_access/lorawan_mpa_package.c index becc112..78e4f95 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/multi_package_access/lorawan_mpa_package.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/multi_package_access/lorawan_mpa_package.c @@ -415,8 +415,8 @@ void lorawan_mpa_package_service_on_launch( void* service_id ) SMTC_MODEM_HAL_TRACE_PRINTF( " lorawan_mpa_package launch ANS_CMD_TASK n" ); SMTC_MODEM_HAL_TRACE_ARRAY( "MPA ans", tmp_ans, tmp_ans_size ); - if( tx_protocol_manager_request (TX_PROTOCOL_TRANSMIT_LORA, - MPA_PORT, true, tmp_ans, tmp_ans_size, UNCONF_DATA_UP, + if( tx_protocol_manager_request( + TX_PROTOCOL_TRANSMIT_LORA, MPA_PORT, true, tmp_ans, tmp_ans_size, UNCONF_DATA_UP, smtc_modem_hal_get_time_in_ms( ) + smtc_modem_hal_get_random_nb_in_range( 0, 2000 ), ctx->stack_id ) == OKLORAWAN ) { @@ -471,7 +471,7 @@ uint8_t lorawan_mpa_package_service_downlink_handler( lr1_stack_mac_down_data_t* if( stack_id >= NUMBER_OF_MPA_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -676,7 +676,7 @@ static bool mpa_package_parser_internal( uint8_t stack_id, uint8_t* payload_in, if( stack_id >= NUMBER_OF_MPA_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return false; } @@ -696,14 +696,16 @@ static bool mpa_package_parser_internal( uint8_t stack_id, uint8_t* payload_in, switch( cmd_id ) { - case MPA_PKG_VERSION_REQ: { + case MPA_PKG_VERSION_REQ: + { ans_buffer_tmp[ans_index++] = MPA_PKG_VERSION_ANS; ans_buffer_tmp[ans_index++] = MPA_ID; ans_buffer_tmp[ans_index++] = MPA_VERSION; break; } - case MPA_DEV_PACKAGE_REQ: { + case MPA_DEV_PACKAGE_REQ: + { uint8_t pkt_id; uint8_t pkt_version; uint8_t pkt_port; @@ -720,7 +722,8 @@ static bool mpa_package_parser_internal( uint8_t stack_id, uint8_t* payload_in, } break; } - case MPA_MULTI_PACK_BUFFER_REQ: { + case MPA_MULTI_PACK_BUFFER_REQ: + { ctx->start_byte_pending = payload_in[mpa_package_rx_buffer_index + 1]; ctx->stop_byte_pending = payload_in[mpa_package_rx_buffer_index + 2]; diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/remote_multicast_setup/v1.0.0/lorawan_remote_multicast_setup_package_v1.0.0.c b/lbm_lib/smtc_modem_core/lorawan_packages/remote_multicast_setup/v1.0.0/lorawan_remote_multicast_setup_package_v1.0.0.c index b41ba71..c88422f 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/remote_multicast_setup/v1.0.0/lorawan_remote_multicast_setup_package_v1.0.0.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/remote_multicast_setup/v1.0.0/lorawan_remote_multicast_setup_package_v1.0.0.c @@ -55,6 +55,8 @@ #include "lorawan_remote_multicast_setup_package.h" #include "smtc_multicast.h" #include "modem_tx_protocol_manager.h" +#include "lorawan_cid_request_management.h" + /* * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- @@ -161,28 +163,27 @@ static const uint8_t multicast_setup_req_cmd_size[6] = { REMOTE_MULTICAST_SETUP_ REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ_SIZE, REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ_SIZE }; -#define NB_MULTICAST_GROUPS LR1MAC_MC_NUMBER_OF_SESSION +#define NB_MULTICAST_GROUPS ( LR1MAC_MC_NUMBER_OF_SESSION ) typedef enum { ANS_CMD_TASK = 0, - REQUEST_TIME_SYNC_TASK = 1, - LAUNCH_CLASS_C_TASK_GROUP_ID_0 = 2, - LAUNCH_CLASS_C_TASK_GROUP_ID_1 = 3, - LAUNCH_CLASS_C_TASK_GROUP_ID_2 = 4, - LAUNCH_CLASS_C_TASK_GROUP_ID_3 = 5, - STOP_CLASS_C_TASK_GROUP_ID_0 = 6, - STOP_CLASS_C_TASK_GROUP_ID_1 = 7, - STOP_CLASS_C_TASK_GROUP_ID_2 = 8, - STOP_CLASS_C_TASK_GROUP_ID_3 = 9, - LAUNCH_CLASS_B_TASK_GROUP_ID_0 = 10, - LAUNCH_CLASS_B_TASK_GROUP_ID_1 = 11, - LAUNCH_CLASS_B_TASK_GROUP_ID_2 = 12, - LAUNCH_CLASS_B_TASK_GROUP_ID_3 = 13, - STOP_CLASS_B_TASK_GROUP_ID_0 = 14, - STOP_CLASS_B_TASK_GROUP_ID_1 = 15, - STOP_CLASS_B_TASK_GROUP_ID_2 = 16, - STOP_CLASS_B_TASK_GROUP_ID_3 = 17, + LAUNCH_CLASS_C_TASK_GROUP_ID_0 = 1, + LAUNCH_CLASS_C_TASK_GROUP_ID_1 = 2, + LAUNCH_CLASS_C_TASK_GROUP_ID_2 = 3, + LAUNCH_CLASS_C_TASK_GROUP_ID_3 = 4, + STOP_CLASS_C_TASK_GROUP_ID_0 = 5, + STOP_CLASS_C_TASK_GROUP_ID_1 = 6, + STOP_CLASS_C_TASK_GROUP_ID_2 = 7, + STOP_CLASS_C_TASK_GROUP_ID_3 = 8, + LAUNCH_CLASS_B_TASK_GROUP_ID_0 = 9, + LAUNCH_CLASS_B_TASK_GROUP_ID_1 = 10, + LAUNCH_CLASS_B_TASK_GROUP_ID_2 = 11, + LAUNCH_CLASS_B_TASK_GROUP_ID_3 = 12, + STOP_CLASS_B_TASK_GROUP_ID_0 = 13, + STOP_CLASS_B_TASK_GROUP_ID_1 = 14, + STOP_CLASS_B_TASK_GROUP_ID_2 = 15, + STOP_CLASS_B_TASK_GROUP_ID_3 = 16, } remote_multicast_supervisor_task_types_t; typedef struct lorawan_remote_multicast_setup_package_s @@ -360,6 +361,8 @@ void lorawan_remote_multicast_setup_package_services_init( ctx->launch_class_b[i] = false; ctx->stop_class_b[i] = false; } + + memset( multicast_group_params, 0, sizeof( multicast_group_params ) ); } void lorawan_remote_multicast_setup_package_service_on_launch( void* ctx_service ) @@ -381,18 +384,6 @@ void lorawan_remote_multicast_setup_package_service_on_launch( void* ctx_service ctx->task_ctx_mask &= ~( 1 << ANS_CMD_TASK ); } - else if( ( ( ctx->task_ctx_mask >> REQUEST_TIME_SYNC_TASK ) & 0x01 ) == 0x01 ) - { - SMTC_MODEM_HAL_TRACE_PRINTF( " lorawan_remote_multicast_setup_package launch REQUEST_TIME_SYNC_TASK \n" ); - ctx->request_time_sync = false; - cid_from_device_t cid_buffer[] = { DEVICE_TIME_REQ }; - uint8_t cid_request_size = 1; - - tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_CID, 0, false, cid_buffer, cid_request_size, 0, - smtc_modem_hal_get_time_in_ms( ), stack_id ); - ctx->task_ctx_mask &= ~( 1 << REQUEST_TIME_SYNC_TASK ); - } - else if( ( ( ctx->task_ctx_mask >> LAUNCH_CLASS_C_TASK_GROUP_ID_0 ) & 0x0F ) != 0 ) { uint8_t mc_grp_id = 0; @@ -537,8 +528,8 @@ void lorawan_remote_multicast_setup_package_service_on_update( void* ctx_service // if time sync is missing launch a task to ask time sync (network sync) if( ctx->request_time_sync == true ) { - lorawan_remote_multicast_setup_add_task( ( lorawan_remote_multicast_setup_package_ctx_t* ) ctx_service, 0 ); - ctx->task_ctx_mask |= ( 1 << REQUEST_TIME_SYNC_TASK ); + smtc_modem_lorawan_mac_request_mask_t cid_request_mask = SMTC_MODEM_LORAWAN_MAC_REQ_DEVICE_TIME; + lorawan_cid_request_add_task( stack_id, cid_request_mask, 1 ); return; } @@ -686,7 +677,7 @@ uint8_t lorawan_remote_multicast_setup_package_service_downlink_handler( lr1_sta if( stack_id >= NUMBER_OF_REMOTE_MULTICAST_SETUP_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -739,7 +730,7 @@ bool lorawan_remote_multicast_setup_mpa_injector( uint8_t stack_id, uint8_t* pay if( stack_id >= NUMBER_OF_REMOTE_MULTICAST_SETUP_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return false; } @@ -764,7 +755,7 @@ bool lorawan_remote_multicast_setup_mpa_injector( uint8_t stack_id, uint8_t* pay SMTC_MODEM_HAL_PANIC_ON_FAILURE( ctx->remote_multicast_tx_payload_ans_size <= max_payload_out_length ); *payload_out_length = ctx->remote_multicast_tx_payload_ans_size; memcpy( payload_out, ctx->remote_multicast_tx_payload_ans, ctx->remote_multicast_tx_payload_ans_size ); - + lorawan_remote_multicast_setup_add_task( ctx, 0 ); return true; } @@ -863,7 +854,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( { switch( rx_buffer[rx_buffer_index] ) { - case REMOTE_MULTICAST_SETUP_PKG_VERSION_REQ: { + case REMOTE_MULTICAST_SETUP_PKG_VERSION_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_PKG_VERSION_REQ_SIZE ); rx_buffer_index += REMOTE_MULTICAST_SETUP_PKG_VERSION_REQ_SIZE; @@ -876,7 +868,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_STATUS_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_STATUS_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_STATUS_REQ_SIZE ); uint8_t mc_grp_mask = rx_buffer[rx_buffer_index + 1] & 0x0F; uint8_t ans_group_mask = 0; @@ -912,7 +905,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( rx_buffer_index += REMOTE_MULTICAST_SETUP_MC_GROUP_STATUS_REQ_SIZE; break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_SETUP_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_SETUP_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_SETUP_REQ_SIZE ); uint8_t mc_grp_id = rx_buffer[rx_buffer_index + 1] & 0x03; bool id_error = 0; @@ -952,7 +946,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_DELETE_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_DELETE_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_DELETE_REQ_SIZE ); uint8_t mc_grp_id = rx_buffer[rx_buffer_index + 1] & 0x03; @@ -969,7 +964,7 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( // reset time out to force stop class c in case of class c is already started multicast_group_params[mc_grp_id].params.time_out = 0; ctx->launch_class_c[mc_grp_id] = - false; // don't reset ctx->stop_class_c, let do it by the task enqueu by the supervisor + false; // don't reset ctx->stop_class_c, let do it by the task enqueue by the supervisor if( ctx->stop_class_c[mc_grp_id] == true ) { lorawan_api_multicast_c_stop_session( mc_grp_id, stack_id ); @@ -988,7 +983,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ_SIZE ); uint8_t mc_grp_id = rx_buffer[rx_buffer_index + 1] & 0x03; @@ -1075,7 +1071,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( rx_buffer_index += REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ_SIZE; break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ_SIZE ); uint8_t mc_grp_id = rx_buffer[rx_buffer_index + 1] & 0x03; diff --git a/lbm_lib/smtc_modem_core/lorawan_packages/remote_multicast_setup/v2.0.0/lorawan_remote_multicast_setup_package_v2.0.0.c b/lbm_lib/smtc_modem_core/lorawan_packages/remote_multicast_setup/v2.0.0/lorawan_remote_multicast_setup_package_v2.0.0.c index 6e6c28d..50930d0 100644 --- a/lbm_lib/smtc_modem_core/lorawan_packages/remote_multicast_setup/v2.0.0/lorawan_remote_multicast_setup_package_v2.0.0.c +++ b/lbm_lib/smtc_modem_core/lorawan_packages/remote_multicast_setup/v2.0.0/lorawan_remote_multicast_setup_package_v2.0.0.c @@ -54,6 +54,8 @@ #include "lorawan_class_b_management.h" #include "lorawan_remote_multicast_setup_package.h" #include "modem_tx_protocol_manager.h" +#include "lorawan_cid_request_management.h" + /* * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- @@ -160,28 +162,27 @@ static const uint8_t multicast_setup_req_cmd_size[6] = { REMOTE_MULTICAST_SETUP_ REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ_SIZE, REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ_SIZE }; -#define NB_MULTICAST_GROUPS ( 4 ) +#define NB_MULTICAST_GROUPS ( LR1MAC_MC_NUMBER_OF_SESSION ) typedef enum { ANS_CMD_TASK = 0, - REQUEST_TIME_SYNC_TASK = 1, - LAUNCH_CLASS_C_TASK_GROUP_ID_0 = 2, - LAUNCH_CLASS_C_TASK_GROUP_ID_1 = 3, - LAUNCH_CLASS_C_TASK_GROUP_ID_2 = 4, - LAUNCH_CLASS_C_TASK_GROUP_ID_3 = 5, - STOP_CLASS_C_TASK_GROUP_ID_0 = 6, - STOP_CLASS_C_TASK_GROUP_ID_1 = 7, - STOP_CLASS_C_TASK_GROUP_ID_2 = 8, - STOP_CLASS_C_TASK_GROUP_ID_3 = 9, - LAUNCH_CLASS_B_TASK_GROUP_ID_0 = 10, - LAUNCH_CLASS_B_TASK_GROUP_ID_1 = 11, - LAUNCH_CLASS_B_TASK_GROUP_ID_2 = 12, - LAUNCH_CLASS_B_TASK_GROUP_ID_3 = 13, - STOP_CLASS_B_TASK_GROUP_ID_0 = 14, - STOP_CLASS_B_TASK_GROUP_ID_1 = 15, - STOP_CLASS_B_TASK_GROUP_ID_2 = 16, - STOP_CLASS_B_TASK_GROUP_ID_3 = 17, + LAUNCH_CLASS_C_TASK_GROUP_ID_0 = 1, + LAUNCH_CLASS_C_TASK_GROUP_ID_1 = 2, + LAUNCH_CLASS_C_TASK_GROUP_ID_2 = 3, + LAUNCH_CLASS_C_TASK_GROUP_ID_3 = 4, + STOP_CLASS_C_TASK_GROUP_ID_0 = 5, + STOP_CLASS_C_TASK_GROUP_ID_1 = 6, + STOP_CLASS_C_TASK_GROUP_ID_2 = 7, + STOP_CLASS_C_TASK_GROUP_ID_3 = 8, + LAUNCH_CLASS_B_TASK_GROUP_ID_0 = 9, + LAUNCH_CLASS_B_TASK_GROUP_ID_1 = 10, + LAUNCH_CLASS_B_TASK_GROUP_ID_2 = 11, + LAUNCH_CLASS_B_TASK_GROUP_ID_3 = 12, + STOP_CLASS_B_TASK_GROUP_ID_0 = 13, + STOP_CLASS_B_TASK_GROUP_ID_1 = 14, + STOP_CLASS_B_TASK_GROUP_ID_2 = 15, + STOP_CLASS_B_TASK_GROUP_ID_3 = 16, } remote_multicast_supervisor_task_types_t; typedef struct lorawan_remote_multicast_setup_package_s @@ -359,6 +360,8 @@ void lorawan_remote_multicast_setup_package_services_init( ctx->launch_class_b[i] = false; ctx->stop_class_b[i] = false; } + + memset( multicast_group_params, 0, sizeof( multicast_group_params ) ); } void lorawan_remote_multicast_setup_package_service_on_launch( void* ctx_service ) @@ -380,18 +383,6 @@ void lorawan_remote_multicast_setup_package_service_on_launch( void* ctx_service ctx->task_ctx_mask &= ~( 1 << ANS_CMD_TASK ); } - else if( ( ( ctx->task_ctx_mask >> REQUEST_TIME_SYNC_TASK ) & 0x01 ) == 0x01 ) - { - SMTC_MODEM_HAL_TRACE_PRINTF( " lorawan_remote_multicast_setup_package launch REQUEST_TIME_SYNC_TASK \n" ); - ctx->request_time_sync = false; - cid_from_device_t cid_buffer[] = { DEVICE_TIME_REQ }; - uint8_t cid_request_size = 1; - - tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_CID, 0, false, cid_buffer, cid_request_size, 0, - smtc_modem_hal_get_time_in_ms( ), stack_id ); - ctx->task_ctx_mask &= ~( 1 << REQUEST_TIME_SYNC_TASK ); - } - else if( ( ( ctx->task_ctx_mask >> LAUNCH_CLASS_C_TASK_GROUP_ID_0 ) & 0x0F ) != 0 ) { uint8_t mc_grp_id = 0; @@ -536,8 +527,9 @@ void lorawan_remote_multicast_setup_package_service_on_update( void* ctx_service // if time sync is missing launch a task to ask time sync (network sync) if( ctx->request_time_sync == true ) { - lorawan_remote_multicast_setup_add_task( ( lorawan_remote_multicast_setup_package_ctx_t* ) ctx_service, 0 ); - ctx->task_ctx_mask |= ( 1 << REQUEST_TIME_SYNC_TASK ); + smtc_modem_lorawan_mac_request_mask_t cid_request_mask = SMTC_MODEM_LORAWAN_MAC_REQ_DEVICE_TIME; + lorawan_cid_request_add_task( stack_id, cid_request_mask, 1 ); + return; } @@ -685,7 +677,7 @@ uint8_t lorawan_remote_multicast_setup_package_service_downlink_handler( lr1_sta if( stack_id >= NUMBER_OF_REMOTE_MULTICAST_SETUP_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } @@ -738,7 +730,7 @@ bool lorawan_remote_multicast_setup_mpa_injector( uint8_t stack_id, uint8_t* pay if( stack_id >= NUMBER_OF_REMOTE_MULTICAST_SETUP_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return false; } @@ -862,7 +854,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( { switch( rx_buffer[rx_buffer_index] ) { - case REMOTE_MULTICAST_SETUP_PKG_VERSION_REQ: { + case REMOTE_MULTICAST_SETUP_PKG_VERSION_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_PKG_VERSION_REQ_SIZE ); rx_buffer_index += REMOTE_MULTICAST_SETUP_PKG_VERSION_REQ_SIZE; @@ -875,7 +868,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_STATUS_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_STATUS_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_STATUS_REQ_SIZE ); uint8_t mc_grp_mask = rx_buffer[rx_buffer_index + 1] & 0x0F; uint8_t ans_group_mask = 0; @@ -911,7 +905,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( rx_buffer_index += REMOTE_MULTICAST_SETUP_MC_GROUP_STATUS_REQ_SIZE; break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_SETUP_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_SETUP_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_SETUP_REQ_SIZE ); uint8_t mc_grp_id = rx_buffer[rx_buffer_index + 1] & 0x03; bool id_error = 0; @@ -951,7 +946,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_DELETE_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_DELETE_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_DELETE_REQ_SIZE ); uint8_t mc_grp_id = rx_buffer[rx_buffer_index + 1] & 0x03; @@ -987,7 +983,8 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ_SIZE ); uint8_t mc_grp_id = rx_buffer[rx_buffer_index + 1] & 0x03; @@ -1074,9 +1071,11 @@ static remote_multicast_setup_status_t remote_multicast_setup_package_parser( rx_buffer_index += REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_C_SESSION_REQ_SIZE; break; } - case REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ: { + case REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ: + { IS_VALID_PKG_CMD( REMOTE_MULTICAST_SETUP_MC_GROUP_CLASS_B_SESSION_REQ_SIZE ); uint8_t mc_grp_id = rx_buffer[rx_buffer_index + 1] & 0x03; + // Check if group id is in supported range if( mc_grp_id < NB_MULTICAST_GROUPS ) { diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1_stack_mac_layer.c b/lbm_lib/smtc_modem_core/lr1mac/src/lr1_stack_mac_layer.c index 747096f..8d008d1 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1_stack_mac_layer.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1_stack_mac_layer.c @@ -50,7 +50,12 @@ #include "lr1mac_config.h" #include "smtc_modem_crypto.h" -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_RX ) +#include "relay_rx_mac_parser.h" +#include "relay_def.h" +#endif + +#if defined( ADD_RELAY_TX ) #include "relay_tx_api.h" #include "relay_tx_mac_parser.h" #include "relay_def.h" @@ -70,8 +75,8 @@ * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#if( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) -#if defined( RELAY_TX ) +#if ( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) +#if defined( ADD_RELAY_TX ) static const char* smtc_name_rx_windows[] = { "RX1", "RX2", "RXR" }; #else static const char* smtc_name_rx_windows[] = { "RX1", "RX2" }; @@ -224,11 +229,17 @@ void lr1_stack_mac_tx_frame_encrypt( lr1_stack_mac_t* lr1_mac ) { tx_fopts_length = lr1_mac->tx_fopts_current_length; } - + smtc_se_key_identifier_t enc_key = ( lr1_mac->tx_fport == PORTNWK ) ? SMTC_SE_NWK_S_ENC_KEY : SMTC_SE_APP_S_KEY; +#if defined( ADD_RELAY_RX ) + if( lr1_mac->tx_fport == FPORT_RELAY ) + { + enc_key = SMTC_SE_NWK_S_ENC_KEY; + } +#endif if( smtc_modem_crypto_payload_encrypt( &lr1_mac->tx_payload[FHDROFFSET + lr1_mac->tx_fport_present + tx_fopts_length], lr1_mac->app_payload_size, - ( lr1_mac->tx_fport == PORTNWK ) ? SMTC_SE_NWK_S_ENC_KEY : SMTC_SE_APP_S_KEY, lr1_mac->dev_addr, UP_LINK, - lr1_mac->fcnt_up, &lr1_mac->tx_payload[FHDROFFSET + lr1_mac->tx_fport_present + tx_fopts_length], + enc_key, lr1_mac->dev_addr, UP_LINK, lr1_mac->fcnt_up, + &lr1_mac->tx_payload[FHDROFFSET + lr1_mac->tx_fport_present + tx_fopts_length], lr1_mac->stack_id ) != SMTC_MODEM_CRYPTO_RC_SUCCESS ) { SMTC_MODEM_HAL_PANIC( "Crypto error during payload encryption\n" ); @@ -253,7 +264,7 @@ void lr1_stack_mac_tx_lora_launch_callback_for_rp( void* rp_void ) SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_pkt_payload( &( rp->radio->ral ), rp->payload[id], rp->payload_buffer_size[id] ) == RAL_STATUS_OK ); // Wait the exact expected time (ie target - tcxo startup delay) - while( ( int32_t )( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) { // Do nothing } @@ -274,7 +285,7 @@ void lr1_stack_mac_tx_gfsk_launch_callback_for_rp( void* rp_void ) SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_pkt_payload( &( rp->radio->ral ), rp->payload[id], rp->payload_buffer_size[id] ) == RAL_STATUS_OK ); // Wait the exact expected time (ie target - tcxo startup delay) - while( ( int32_t )( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) { } // At this time only tcxo startup delay is remaining @@ -303,7 +314,7 @@ void lr1_stack_mac_tx_lr_fhss_launch_callback_for_rp( void* rp_void ) rp->radio_params[id].tx.lr_fhss.hop_sequence_id, rp->payload[id], rp->payload_buffer_size[id] ) == RAL_STATUS_OK ); // Wait the exact expected time (ie target - tcxo startup delay) - while( ( int32_t )( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) { // Do nothing } @@ -324,7 +335,7 @@ void lr1_stack_mac_rx_lora_launch_callback_for_rp( void* rp_void ) ral_set_dio_irq_params( &( rp->radio->ral ), RAL_IRQ_RX_DONE | RAL_IRQ_RX_TIMEOUT | RAL_IRQ_RX_HDR_ERROR | RAL_IRQ_RX_CRC_ERROR ) == RAL_STATUS_OK ); // Wait the exact expected time (ie target - tcxo startup delay) - while( ( int32_t )( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) { } // At this time only tcxo startup delay is remaining @@ -345,7 +356,7 @@ void lr1_stack_mac_rx_gfsk_launch_callback_for_rp( void* rp_void ) ral_set_dio_irq_params( &( rp->radio->ral ), RAL_IRQ_RX_DONE | RAL_IRQ_RX_TIMEOUT | RAL_IRQ_RX_CRC_ERROR ) == RAL_STATUS_OK ); // Wait the exact expected time (ie target - tcxo startup delay) - while( ( int32_t )( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) { } // At this time only tcxo startup delay is remaining @@ -450,12 +461,6 @@ void lr1_stack_mac_tx_radio_start( lr1_stack_mac_t* lr1_mac ) lr_fhss_param.output_pwr_in_dbm = smtc_real_clamp_output_power_eirp_vs_freq_and_dr( lr1_mac->real, lr1_mac->tx_power, lr1_mac->tx_frequency, lr1_mac->tx_data_rate ); - unsigned int nb_max_hop_sequence = 0; - SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_lr_fhss_get_hop_sequence_count( &lr1_mac->rp->radio->ral, - &lr_fhss_param.ral_lr_fhss_params, - &nb_max_hop_sequence ) == RAL_STATUS_OK ); - lr_fhss_param.hop_sequence_id = - smtc_modem_hal_get_random_nb_in_range( 0, ( uint32_t ) nb_max_hop_sequence - 1 ); lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.modulation_type = LR_FHSS_V1_MODULATION_TYPE_GMSK_488; lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.cr = tx_cr; lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.grid = smtc_real_lr_fhss_get_grid( lr1_mac->real ); @@ -466,6 +471,13 @@ void lr1_stack_mac_tx_radio_start( lr1_stack_mac_t* lr1_mac ) lr_fhss_param.ral_lr_fhss_params.center_frequency_in_hz = lr1_mac->tx_frequency; lr_fhss_param.ral_lr_fhss_params.device_offset = 0; + unsigned int nb_max_hop_sequence = 0; + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_lr_fhss_get_hop_sequence_count( &lr1_mac->rp->radio->ral, + &lr_fhss_param.ral_lr_fhss_params, + &nb_max_hop_sequence ) == RAL_STATUS_OK ); + lr_fhss_param.hop_sequence_id = + smtc_modem_hal_get_random_nb_in_range( 0, ( uint32_t ) nb_max_hop_sequence - 1 ); + radio_params.tx.lr_fhss = lr_fhss_param; ral_lr_fhss_get_time_on_air_in_ms( ( &lr1_mac->rp->radio->ral ), &lr_fhss_param.ral_lr_fhss_params, @@ -525,7 +537,7 @@ void lr1_stack_mac_rx_radio_start( lr1_stack_mac_t* lr1_mac, const rx_win_type_t case RX2: rx_frequency = lr1_mac->rx2_frequency; break; -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) case RXR: smtc_relay_tx_get_rxr_param( lr1_mac->stack_id, lr1_mac->tx_data_rate, NULL, &rx_frequency ); break; @@ -555,9 +567,8 @@ void lr1_stack_mac_rx_radio_start( lr1_stack_mac_t* lr1_mac, const rx_win_type_t lora_param.pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; - // +5 for MIC + FPort lora_param.pkt_params.pld_len_in_bytes = - 5 + smtc_real_get_max_payload_size( lr1_mac->real, rx_datarate, DOWN_LINK ); + smtc_real_get_max_payload_size( lr1_mac->real, rx_datarate, DOWN_LINK ) + MHDRSIZE + MICSIZE; lora_param.pkt_params.crc_is_on = false; lora_param.pkt_params.invert_iq_is_on = true; @@ -616,9 +627,9 @@ void lr1_stack_mac_rx_radio_start( lr1_stack_mac_t* lr1_mac, const rx_win_type_t .launch_task_callbacks = ( radio_params.pkt_type == RAL_PKT_TYPE_LORA ) ? lr1_stack_mac_rx_lora_launch_callback_for_rp : lr1_stack_mac_rx_gfsk_launch_callback_for_rp, - .state = RP_TASK_STATE_SCHEDULE, - .start_time_ms = time_to_start, - .duration_time_ms = lr1_mac->rx_timeout_symb_in_ms, + .state = RP_TASK_STATE_SCHEDULE, + .start_time_ms = time_to_start, + .duration_time_ms = lr1_mac->rx_timeout_symb_in_ms, }; if( rp_task_enqueue( lr1_mac->rp, &rp_task, lr1_mac->rx_down_data.rx_payload, 255, &radio_params ) == @@ -664,16 +675,30 @@ void lr1_stack_mac_rp_callback( lr1_stack_mac_t* lr1_mac ) case RP_STATUS_RX_PACKET: // save rssi and snr lr1_mac->rx_down_data.rx_metadata.timestamp_ms = tcurrent_ms; - lr1_mac->rx_down_data.rx_metadata.rx_snr = - lr1_mac->rp->radio_params[my_hook_id].rx.lora_pkt_status.snr_pkt_in_db; - lr1_mac->rx_down_data.rx_metadata.rx_rssi = - lr1_mac->rp->radio_params[my_hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm; + + if( lr1_mac->rp->radio_params[my_hook_id].pkt_type == RAL_PKT_TYPE_LORA ) + { + lr1_mac->rx_down_data.rx_metadata.rx_snr = + lr1_mac->rp->radio_params[my_hook_id].rx.lora_pkt_status.snr_pkt_in_db; + lr1_mac->rx_down_data.rx_metadata.rx_rssi = + lr1_mac->rp->radio_params[my_hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm; + } + else if( lr1_mac->rp->radio_params[my_hook_id].pkt_type == RAL_PKT_TYPE_GFSK ) + { + lr1_mac->rx_down_data.rx_metadata.rx_snr = 0; + lr1_mac->rx_down_data.rx_metadata.rx_rssi = + lr1_mac->rp->radio_params[my_hook_id].rx.gfsk_pkt_status.rssi_avg_in_dbm; + } + else + { + SMTC_MODEM_HAL_PANIC( ); + } + lr1_mac->rx_down_data.rx_payload_size = ( uint8_t ) lr1_mac->rp->rx_payload_size[my_hook_id]; - SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( "payload size receive = %u, snr = %d , rssi = %d\n", - lr1_mac->rx_down_data.rx_payload_size, - lr1_mac->rp->radio_params[my_hook_id].rx.lora_pkt_status.snr_pkt_in_db, - lr1_mac->rp->radio_params[my_hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm ); + SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( + "payload size receive = %u, snr = %d , rssi = %d\n", lr1_mac->rx_down_data.rx_payload_size, + lr1_mac->rx_down_data.rx_metadata.rx_snr, lr1_mac->rx_down_data.rx_metadata.rx_rssi ); if( lr1_stack_mac_downlink_check_under_it( lr1_mac ) != OKLORAWAN ) { // Case receive a packet but it isn't a valid packet @@ -687,7 +712,8 @@ void lr1_stack_mac_rp_callback( lr1_stack_mac_t* lr1_mac ) SMTC_MODEM_HAL_TRACE_PRINTF( "RP_STATUS_RX_CRC_ERROR\n" ); break; - case RP_STATUS_RX_TIMEOUT: { + case RP_STATUS_RX_TIMEOUT: + { #ifndef BSP_LR1MAC_DISABLE_FINE_TUNE uint32_t rx_timestamp_calibration = tcurrent_ms; uint32_t rx_delay_ms = 0; @@ -700,7 +726,7 @@ void lr1_stack_mac_rp_callback( lr1_stack_mac_t* lr1_mac ) { rx_delay_ms = lr1_mac->rx1_delay_s + 1; } -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) else if( lr1_mac->current_win == RXR ) { rx_delay_ms = RXR_WINDOWS_DELAY_S; @@ -788,7 +814,7 @@ bool lr1_stack_mac_rx_timer_configure( lr1_stack_mac_t* lr1_mac, const rx_win_ty lr1_mac->rx_data_rate = lr1_mac->rx2_data_rate; break; -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) case RXR: delay_ms = RXR_WINDOWS_DELAY_S; smtc_relay_tx_get_rxr_param( lr1_mac->stack_id, lr1_mac->tx_data_rate, &lr1_mac->rx_data_rate, NULL ); @@ -829,7 +855,7 @@ bool lr1_stack_mac_rx_timer_configure( lr1_stack_mac_t* lr1_mac, const rx_win_ty +smtc_modem_hal_get_board_delay_ms( ) + lr1_mac->fine_tune_board_setting_delay_ms[lr1_mac->rx_data_rate]; -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) uint32_t crystal_error = lr1_mac->crystal_error; if( type == RXR ) { @@ -853,7 +879,7 @@ bool lr1_stack_mac_rx_timer_configure( lr1_stack_mac_t* lr1_mac, const rx_win_ty lr1_mac->rx_timeout_symb_in_ms, lr1_mac->rx_window_symb, board_delay_ms ); int32_t talarm_ms = - delay_ms + ( int32_t )( lr1_mac->isr_tx_done_radio_timestamp - tcurrent_ms ) + lr1_mac->rx_offset_ms; + delay_ms + ( int32_t ) ( lr1_mac->isr_tx_done_radio_timestamp - tcurrent_ms ) + lr1_mac->rx_offset_ms; if( talarm_ms < 0 ) { lr1_mac->radio_process_state = RADIOSTATE_RX_FINISHED; @@ -968,7 +994,7 @@ rx_packet_type_t lr1_stack_mac_rx_frame_decode( lr1_stack_mac_t* lr1_mac ) { lr1_mac->rx_down_data.rx_metadata.rx_frequency_hz = lr1_mac->rx2_frequency; } -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) else if( lr1_mac->current_win == RXR ) { smtc_relay_tx_get_rxr_param( lr1_mac->stack_id, lr1_mac->tx_data_rate, NULL, @@ -991,7 +1017,22 @@ rx_packet_type_t lr1_stack_mac_rx_frame_decode( lr1_stack_mac_t* lr1_mac ) // => set rx_packet_type = NWKRXPACKET // => if ack bit is set to one : notify the upper layer that the stack have received an ack bit +#if defined( ADD_RELAY_RX ) + bool decode_with_nwk_s_key = false; + + if( lr1_mac->rx_down_data.rx_metadata.rx_fport == 0 ) + { + decode_with_nwk_s_key = true; + } + + if( lr1_mac->rx_down_data.rx_metadata.rx_fport == FPORT_RELAY ) + { + decode_with_nwk_s_key = true; + } + if( decode_with_nwk_s_key == true ) +#else if( lr1_mac->rx_down_data.rx_metadata.rx_fport == 0 ) +#endif { // receive a mac management frame without fopts if( lr1_mac->rx_fopts_length == 0 ) { @@ -1125,8 +1166,8 @@ void lr1_stack_mac_update( lr1_stack_mac_t* lr1_mac ) if( lr1_mac->join_status == JOINING ) { // get current timestamp to check which duty cycle will be applied - uint32_t current_time_s = smtc_modem_hal_get_time_in_s( ); - + uint32_t current_time_s = smtc_modem_hal_get_time_in_s( ); + lr1_mac->adr_mode_select = JOIN_DR_DISTRIBUTION; lr1_mac->retry_join_cpt++; if( current_time_s + ( ( lr1_stack_toa_get( lr1_mac ) ) / 10 ) < ( lr1_mac->first_join_timestamp + 3600 ) ) @@ -1139,13 +1180,16 @@ void lr1_stack_mac_update( lr1_stack_mac_t* lr1_mac ) { // during the 10 hours following first hour after first join try => duty cycle of 1/1000 ie 36s over 10 // hours - lr1_mac->next_time_to_join_seconds = current_time_s + ( lr1_stack_toa_get( lr1_mac ) ); + lr1_mac->next_time_to_join_seconds = current_time_s + ( ( ( lr1_stack_toa_get( lr1_mac ) * 12 ) / 10 ) ); // ts=cur_ts+(toa_s*1000) = cur_ts + (toa_ms / 1000) * 1000 = cur_ts + toa_ms + // *12/10 to round the number of JoinReq to the worst case } else { // Following the first 11 hours after first join try => duty cycle of 1/10000 ie 8.7s over 24 hours - lr1_mac->next_time_to_join_seconds = current_time_s + ( lr1_stack_toa_get( lr1_mac ) ) * 10; + lr1_mac->next_time_to_join_seconds = + current_time_s + ( lr1_stack_toa_get( lr1_mac ) ) * 12; // *12 to avoid to launch 6 JoinReq by 24h + lr1_mac->adr_mode_select = JOIN_DR_DISTRIBUTION_LONG_TERM; // ts=cur_ts+(toa_s*10000) = cur_ts + (toa_ms / 1000) * 10000 = cur_ts + toa_ms*10 } @@ -1315,7 +1359,8 @@ status_lorawan_t lr1_stack_mac_cmd_parse( lr1_stack_mac_t* lr1_mac ) dl_channel_parser( lr1_mac ); break; - case DEVICE_TIME_ANS: { + case DEVICE_TIME_ANS: + { if( device_time_ans_parser( lr1_mac ) == OKLORAWAN ) { lr1_mac->timestamp_tx_done_device_time_req_ms = lr1_mac->timestamp_tx_done_device_time_req_ms_tmp; @@ -1325,7 +1370,8 @@ status_lorawan_t lr1_stack_mac_cmd_parse( lr1_stack_mac_t* lr1_mac ) } // Class B - case PING_SLOT_INFO_ANS: { + case PING_SLOT_INFO_ANS: + { if( ping_slot_info_ans_parser( lr1_mac ) == OKLORAWAN ) { lr1_mac->ping_slot_periodicity_ans = lr1_mac->ping_slot_periodicity_req; @@ -1341,13 +1387,29 @@ status_lorawan_t lr1_stack_mac_cmd_parse( lr1_stack_mac_t* lr1_mac ) beacon_freq_req_parser( lr1_mac ); break; -#if defined( RELAY_TX ) - default: { - const bool mac_is_known = relay_tx_mac_parser( lr1_mac ); - if( mac_is_known == false ) +#if defined( ADD_RELAY_TX ) || defined( ADD_RELAY_RX ) + default: + { + bool mac_is_known_relay_tx = false; + bool mac_is_known_relay_rx = false; +#if defined( ADD_RELAY_TX ) + mac_is_known_relay_tx = relay_tx_mac_parser( lr1_mac ); +#endif +#if defined( ADD_RELAY_RX ) + + if( ( lr1_mac->rx_down_data.rx_metadata.rx_fport_present == true ) && + ( lr1_mac->rx_down_data.rx_metadata.rx_fport == FPORT_RELAY ) ) + { + mac_is_known_relay_rx = false; // Don't process data on FPORT 226 as MAC command + } + else + { + mac_is_known_relay_rx = relay_rx_mac_parser( lr1_mac ); + } +#endif + if( ( mac_is_known_relay_tx == false ) && ( mac_is_known_relay_rx == false ) ) { lr1_mac->nwk_payload_size = 0; - SMTC_MODEM_HAL_TRACE_PRINTF( " Unknown mac command %02x\n", cmd_identifier ); } } break; @@ -1390,8 +1452,8 @@ void lr1_stack_mac_join_request_build( lr1_stack_mac_t* lr1_mac ) lr1_mac->tx_payload[1 + i] = join_eui[7 - i]; lr1_mac->tx_payload[9 + i] = dev_eui[7 - i]; } - lr1_mac->tx_payload[17] = ( uint8_t )( ( lr1_mac->dev_nonce & 0x00FF ) ); - lr1_mac->tx_payload[18] = ( uint8_t )( ( lr1_mac->dev_nonce & 0xFF00 ) >> 8 ); + lr1_mac->tx_payload[17] = ( uint8_t ) ( ( lr1_mac->dev_nonce & 0x00FF ) ); + lr1_mac->tx_payload[18] = ( uint8_t ) ( ( lr1_mac->dev_nonce & 0xFF00 ) >> 8 ); lr1_mac->tx_payload_size = 19; uint32_t mic; // FcntUp = 1; @@ -1410,7 +1472,6 @@ status_lorawan_t lr1_stack_mac_join_accept( lr1_stack_mac_t* lr1_mac ) uint8_t join_nonce[6]; // JoinNonce + NetID uint32_t join_nonce_tmp; // JoinNonce only uint32_t join_nonce_prev; // JoinNonce only - uint32_t i; memcpy( join_nonce, &lr1_mac->rx_down_data.rx_payload[1], 6 ); @@ -1440,16 +1501,19 @@ status_lorawan_t lr1_stack_mac_join_accept( lr1_stack_mac_t* lr1_mac ) lr1_stack_mac_session_init( lr1_mac ); smtc_real_config_session( lr1_mac->real ); + bool is_valid_join_cflist = false; + if( lr1_mac->rx_down_data.rx_payload_size > 13 ) // MIC has been removed (17 bytes - 4 bytes MIC) { // cflist are presents - for( i = 0; i < 16; i++ ) + memcpy( lr1_mac->cf_list, &lr1_mac->rx_down_data.rx_payload[13], 16 ); + + if( smtc_real_update_cflist( lr1_mac->real, lr1_mac->cf_list ) == OKLORAWAN ) { - lr1_mac->cf_list[i] = lr1_mac->rx_down_data.rx_payload[13 + i]; + is_valid_join_cflist = true; } - - smtc_real_update_cflist( lr1_mac->real, lr1_mac->cf_list ); } - else + + if( is_valid_join_cflist == false ) { smtc_real_init_after_join_snapshot_channel_mask( lr1_mac->real, lr1_mac->tx_data_rate, lr1_mac->tx_frequency ); } @@ -1462,7 +1526,7 @@ status_lorawan_t lr1_stack_mac_join_accept( lr1_stack_mac_t* lr1_mac ) lr1_mac->rx1_delay_s = ( lr1_mac->rx_down_data.rx_payload[12] & 0x0F ); if( lr1_mac->rx1_delay_s == 0 ) { - lr1_mac->rx1_delay_s = 1; // Lorawan standart define 0 such as a delay of 1 + lr1_mac->rx1_delay_s = 1; // Lorawan standard define 0 such as a delay of 1 } if( smtc_real_is_rx1_dr_offset_valid( lr1_mac->real, lr1_mac->rx1_dr_offset ) != OKLORAWAN ) @@ -1679,13 +1743,13 @@ static void mac_header_set( lr1_stack_mac_t* lr1_mac ) static void frame_header_set( lr1_stack_mac_t* lr1_mac ) { - lr1_mac->tx_payload[1] = ( uint8_t )( ( lr1_mac->dev_addr & 0x000000FF ) ); - lr1_mac->tx_payload[2] = ( uint8_t )( ( lr1_mac->dev_addr & 0x0000FF00 ) >> 8 ); - lr1_mac->tx_payload[3] = ( uint8_t )( ( lr1_mac->dev_addr & 0x00FF0000 ) >> 16 ); - lr1_mac->tx_payload[4] = ( uint8_t )( ( lr1_mac->dev_addr & 0xFF000000 ) >> 24 ); + lr1_mac->tx_payload[1] = ( uint8_t ) ( ( lr1_mac->dev_addr & 0x000000FF ) ); + lr1_mac->tx_payload[2] = ( uint8_t ) ( ( lr1_mac->dev_addr & 0x0000FF00 ) >> 8 ); + lr1_mac->tx_payload[3] = ( uint8_t ) ( ( lr1_mac->dev_addr & 0x00FF0000 ) >> 16 ); + lr1_mac->tx_payload[4] = ( uint8_t ) ( ( lr1_mac->dev_addr & 0xFF000000 ) >> 24 ); lr1_mac->tx_payload[5] = lr1_mac->tx_fctrl; - lr1_mac->tx_payload[6] = ( uint8_t )( ( lr1_mac->fcnt_up & 0x000000FF ) ); - lr1_mac->tx_payload[7] = ( uint8_t )( ( lr1_mac->fcnt_up & 0x0000FF00 ) >> 8 ); + lr1_mac->tx_payload[6] = ( uint8_t ) ( ( lr1_mac->fcnt_up & 0x000000FF ) ); + lr1_mac->tx_payload[7] = ( uint8_t ) ( ( lr1_mac->fcnt_up & 0x0000FF00 ) >> 8 ); if( lr1_mac->tx_fport == PORTNWK ) { @@ -1730,24 +1794,25 @@ static void link_check_parser( lr1_stack_mac_t* lr1_mac ) } /**********************************************************************************************************************/ -/* Private NWK MANAGEMENTS : */ -/* LinkADR */ -/* Note : describe multiple adr specification */ +/* Private NWK MANAGEMENTS : */ +/* LinkADR */ +/* Note : describe multiple adr specification */ /* */ -/* Step 1 : Create a "unwrapped channel mask" in case of multiple adr cmd with both Channem Mask and ChannnelMaskCntl*/ -/* 2 : Extract from the last adr cmd datarate candidate */ -/* 3 : Extract from the last adr cmd TxPower candidate */ -/* 4 : Extract from the last adr cmd NBRetry candidate */ -/* 5 : Check errors cases (described below) */ -/* 6 : If No error Set new channel mask, txpower,datarate and nbretry */ -/* 7 : Compute duplicated LinkAdrAns */ +/* Step 1 : Create a "unwrapped channel mask" in case of multiple adr cmd with both Channel Mask and + * ChannnelMaskCntl*/ +/* 2 : Extract from the last adr cmd datarate candidate */ +/* 3 : Extract from the last adr cmd TxPower candidate */ +/* 4 : Extract from the last adr cmd NBRetry candidate */ +/* 5 : Check errors cases (described below) */ +/* 6 : If No error Set new channel mask, txpower,datarate and nbretry */ +/* 7 : Compute duplicated LinkAdrAns */ /* */ -/* Error cases 1 : Channel Cntl mask RFU for each adr cmd (in case of multiple cmd) */ -/* 2 : Undefined channel ( freq = 0 ) for active bit in the unwrapped channel mask */ -/* 3 : Unwrapped channel mask = 0 (none active channel) */ -/* 4 : For the last adr cmd not valid tx power */ -/* 5 : For the last adr cmd not valid datarate */ -/* ( datarate > dRMax or datarate < dRMin for all active channel ) */ +/* Error cases 1 : Channel Cntl mask RFU for each adr cmd (in case of multiple cmd) */ +/* 2 : Undefined channel ( freq = 0 ) for active bit in the unwrapped channel mask */ +/* 3 : Unwrapped channel mask = 0 (none active channel) */ +/* 4 : For the last adr cmd not valid tx power */ +/* 5 : For the last adr cmd not valid datarate */ +/* ( datarate > dRMax or datarate < dRMin for all active channel ) */ /**********************************************************************************************************************/ static void link_adr_parser( lr1_stack_mac_t* lr1_mac ) { @@ -1789,7 +1854,7 @@ static void link_adr_parser( lr1_stack_mac_t* lr1_mac ) uint8_t ch_mask_cntl_temp = ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + ( i * LINK_ADR_REQ_SIZE ) + 4] & 0x70 ) >> 4; - SMTC_MODEM_HAL_TRACE_PRINTF( "%u - LINK ADR REQ , channel mask = 0x%x , ChMAstCntl = 0x%x\n", i + 1, + SMTC_MODEM_HAL_TRACE_PRINTF( "%u - LINK ADR REQ , channel mask = 0x%x , ChMaskCntl = 0x%x\n", i + 1, channel_mask_temp, ch_mask_cntl_temp ); status_channel = smtc_real_build_channel_mask( lr1_mac->real, ch_mask_cntl_temp, channel_mask_temp ); @@ -1806,42 +1871,42 @@ static void link_adr_parser( lr1_stack_mac_t* lr1_mac ) SMTC_MODEM_HAL_TRACE_WARNING( "INVALID CHANNEL MASK\n" ); } + uint8_t dr_tmp = + ( ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + ( ( nb_link_adr_req - 1 ) * LINK_ADR_REQ_SIZE ) + 1] & + 0xF0 ) >> + 4 ); + + uint8_t tx_power_tmp = + ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + ( ( nb_link_adr_req - 1 ) * LINK_ADR_REQ_SIZE ) + 1] & + 0x0F ); + // At This point global temporary channel mask is built and validated if( lr1_mac->adr_mode_select != STATIC_ADR_MODE ) { - if( status_ans == 7 ) // mean none ERROR_CHANNEL_CNTL or ERROR_CHANNEL_MASK so valid channel mask only bit - // 1 is really tested + // If datarate == 0x0F, ignore the value else answer an ERROR and don't change anything + if( dr_tmp != 0x0F ) { - // check if new proposal channel mask is compatible with our mobile distribution - if( smtc_real_is_channel_mask_for_mobile_mode( lr1_mac->real ) == ERRORLORAWAN ) - { - status_ans = 0x0; // reject the cmd because even if the channel mask is valid it is not compatible - // with our current adr distribution - SMTC_MODEM_HAL_TRACE_WARNING( "INVALID CHANNEL MASK in Mobile Mode\n" ); - } - else - { - // new channel mask is acceptable : - smtc_real_set_channel_mask( lr1_mac->real ); - // set this flag at true to notify upper layer that end device has received a valid link adr - lr1_mac->available_link_adr = true; - status_ans = 0x1; // Only the ChMask could be acked, other parameters are discarded - } + status_ans &= 0x5; + SMTC_MODEM_HAL_TRACE_WARNING( "INVALID DATARATE\n" ); } - else // rejected because channel mask not valid + + // If power id is 0x0F, ignore the value else answer an ERROR and don't change anything + if( tx_power_tmp != 0x0F ) { - status_ans = 0x0; - SMTC_MODEM_HAL_TRACE_WARNING( "INVALID CHANNEL MASK\n" ); + status_ans &= 0x3; + SMTC_MODEM_HAL_TRACE_WARNING( "INVALID TXPOWER\n" ); + } + // check if new proposal channel mask is compatible with our mobile distribution + if( smtc_real_is_channel_mask_for_mobile_mode( lr1_mac->real ) == ERRORLORAWAN ) + { + status_ans &= 0x6; // reject the cmd because even if the channel mask is valid, it is not compatible + // with our current adr distribution + SMTC_MODEM_HAL_TRACE_WARNING( "INVALID CHANNEL MASK in Mobile Mode\n" ); } } else // static mode { // Valid the last DataRate - uint8_t dr_tmp = - ( ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + ( ( nb_link_adr_req - 1 ) * LINK_ADR_REQ_SIZE ) + 1] & - 0xF0 ) >> - 4 ); - // If datarate requested is 0x0F, ignore the value if( dr_tmp != 0x0F ) { @@ -2158,7 +2223,7 @@ static void rx_timing_setup_parser( lr1_stack_mac_t* lr1_mac ) lr1_mac->rx1_delay_s = ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + 1] & 0xF ); if( lr1_mac->rx1_delay_s == 0 ) { - lr1_mac->rx1_delay_s = 1; // Lorawan standart define 0 such as a delay of 1 + lr1_mac->rx1_delay_s = 1; // Lorawan standard define 0 such as a delay of 1 } lr1_mac->nwk_payload_index += RXTIMING_SETUP_REQ_SIZE; @@ -2208,6 +2273,9 @@ static void tx_param_setup_parser( lr1_stack_mac_t* lr1_mac ) lr1_mac->max_erp_dbm = ( max_erp_dbm_tmp > real_const.const_tx_power_dbm ) ? real_const.const_tx_power_dbm : max_erp_dbm_tmp; + + lr1_mac->tx_power = ( lr1_mac->tx_power > lr1_mac->max_erp_dbm ) ? lr1_mac->max_erp_dbm : lr1_mac->tx_power; + smtc_real_set_uplink_dwell_time( lr1_mac->real, ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + 1] & 0x10 ) >> 4 ); @@ -2310,7 +2378,7 @@ static void dl_channel_parser( lr1_stack_mac_t* lr1_mac ) status_lorawan_t lr1mac_rx_payload_max_size_check( lr1_stack_mac_t* lr1_mac, uint8_t size, uint8_t rx_datarate ) { - uint8_t size_max = smtc_real_get_max_payload_size( lr1_mac->real, rx_datarate, DOWN_LINK ) + 1 + 4; // + MHDR + CRC + uint8_t size_max = smtc_real_get_max_payload_size( lr1_mac->real, rx_datarate, DOWN_LINK ) + MHDRSIZE + MICSIZE; if( size > size_max ) { SMTC_MODEM_HAL_TRACE_PRINTF( "size (%d)> size_max (%d)", size, size_max ); @@ -2348,7 +2416,7 @@ static status_lorawan_t device_time_ans_parser( lr1_stack_mac_t* lr1_mac ) lr1_mac->seconds_since_epoch |= ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + 3] << 16 ); lr1_mac->seconds_since_epoch |= ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + 4] << 24 ); - lr1_mac->fractional_second = ( uint32_t )( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + 5] * 1000 ) >> 8; + lr1_mac->fractional_second = ( uint32_t ) ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + 5] * 1000 ) >> 8; SMTC_MODEM_HAL_TRACE_PRINTF( "SecondsSinceEpoch %u, FractionalSecond %u\n", lr1_mac->seconds_since_epoch, lr1_mac->fractional_second ); diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.c b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.c index 01cb105..41d31e3 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.c @@ -3,11 +3,12 @@ * * \brief Beacon management for LoRaWAN class B devices * - * Revised BSD License - * Copyright Semtech Corporation 2020. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include "smtc_modem_hal_dbg_trace.h" @@ -608,10 +611,24 @@ static void compute_beacon_metadata( smtc_lr1_beacon_t* lr1_beacon_obj, uint32_t if( lr1_beacon_obj->is_valid_beacon == true ) { lr1_beacon_obj->lr1_mac->rx_down_data.rx_metadata.timestamp_ms = timestamp; - lr1_beacon_obj->lr1_mac->rx_down_data.rx_metadata.rx_snr = - lr1_beacon_obj->rp->radio_params[lr1_beacon_obj->beacon_sniff_id_rp].rx.lora_pkt_status.snr_pkt_in_db; - lr1_beacon_obj->lr1_mac->rx_down_data.rx_metadata.rx_rssi = - lr1_beacon_obj->rp->radio_params[lr1_beacon_obj->beacon_sniff_id_rp].rx.lora_pkt_status.rssi_pkt_in_dbm; + + if( lr1_beacon_obj->rp->radio_params[lr1_beacon_obj->beacon_sniff_id_rp].pkt_type == RAL_PKT_TYPE_LORA ) + { + lr1_beacon_obj->lr1_mac->rx_down_data.rx_metadata.rx_snr = + lr1_beacon_obj->rp->radio_params[lr1_beacon_obj->beacon_sniff_id_rp].rx.lora_pkt_status.snr_pkt_in_db; + lr1_beacon_obj->lr1_mac->rx_down_data.rx_metadata.rx_rssi = + lr1_beacon_obj->rp->radio_params[lr1_beacon_obj->beacon_sniff_id_rp].rx.lora_pkt_status.rssi_pkt_in_dbm; + } + else if( lr1_beacon_obj->rp->radio_params[lr1_beacon_obj->beacon_sniff_id_rp].pkt_type == RAL_PKT_TYPE_GFSK ) + { + lr1_beacon_obj->lr1_mac->rx_down_data.rx_metadata.rx_snr = 0; + lr1_beacon_obj->lr1_mac->rx_down_data.rx_metadata.rx_rssi = + lr1_beacon_obj->rp->radio_params[lr1_beacon_obj->beacon_sniff_id_rp].rx.gfsk_pkt_status.rssi_avg_in_dbm; + } + else + { + SMTC_MODEM_HAL_PANIC( ); + } lr1_beacon_obj->beacon_statistics.last_beacon_received_timestamp = timestamp; lr1_beacon_obj->ping_slot_obj->last_valid_rx_beacon_ms = timestamp; diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.h b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.h index bccf97a..80b5844 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_beacon_sniff.h @@ -2,11 +2,13 @@ * \file smtc_beacon_sniff.h * * \brief Beacon management for LoRaWAN class B devices - * Revised BSD License - * Copyright Semtech Corporation 2020. All rights reserved. + * + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -16,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __SMTC_BCN_SNIFF_H__ diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.c b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.c index 15a9fe7..b19a0ff 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.c @@ -3,11 +3,12 @@ * * \brief Ping Slot management for LoRaWAN class B devices * - * Revised BSD License - * Copyright Semtech Corporation 2020. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* @@ -358,9 +361,9 @@ void smtc_ping_slot_start( smtc_ping_slot_t* ping_slot_obj ) lora_param.pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; - // +5 for MIC + FPort lora_param.pkt_params.pld_len_in_bytes = - 5 + smtc_real_get_max_payload_size( ping_slot_obj->lr1_mac->real, ping_slot_dr, DOWN_LINK ); + smtc_real_get_max_payload_size( ping_slot_obj->lr1_mac->real, ping_slot_dr, DOWN_LINK ) + MHDRSIZE + + MICSIZE; lora_param.pkt_params.crc_is_on = false; lora_param.pkt_params.invert_iq_is_on = true; // lora_param.pkt_params.preamble_len_in_symb = 255; // for D2D with longue preamble @@ -506,7 +509,8 @@ void smtc_ping_slot_mac_rp_callback( smtc_ping_slot_t* ping_slot_obj ) case RP_STATUS_TX_DONE: break; - case RP_STATUS_RX_PACKET: { + case RP_STATUS_RX_PACKET: + { int status = OKLORAWAN; if( RX_SESSION_PARAM_CURRENT->enabled == false ) @@ -520,16 +524,27 @@ void smtc_ping_slot_mac_rp_callback( smtc_ping_slot_t* ping_slot_obj ) // save rssi and snr RX_DOWN_DATA.rx_metadata.timestamp_ms = tcurrent_ms; - RX_DOWN_DATA.rx_metadata.rx_snr = - ping_slot_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.snr_pkt_in_db; - RX_DOWN_DATA.rx_metadata.rx_rssi = - ping_slot_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm; - RX_DOWN_DATA.rx_payload_size = ( uint8_t ) ping_slot_obj->rp->rx_payload_size[from_hook_id]; - - SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( - "payload size receive = %u, snr = %u , rssi = %u\n", RX_DOWN_DATA.rx_payload_size, - ping_slot_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.snr_pkt_in_db, - ping_slot_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm ); + if( ping_slot_obj->rp->radio_params[from_hook_id].pkt_type == RAL_PKT_TYPE_LORA ) + { + RX_DOWN_DATA.rx_metadata.rx_snr = + ping_slot_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.snr_pkt_in_db; + RX_DOWN_DATA.rx_metadata.rx_rssi = + ping_slot_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm; + } + else if( ping_slot_obj->rp->radio_params[from_hook_id].pkt_type == RAL_PKT_TYPE_GFSK ) + { + RX_DOWN_DATA.rx_metadata.rx_snr = 0; + RX_DOWN_DATA.rx_metadata.rx_rssi = + ping_slot_obj->rp->radio_params[from_hook_id].rx.gfsk_pkt_status.rssi_avg_in_dbm; + } + else + { + SMTC_MODEM_HAL_PANIC( ); + } + + SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( "payload size receive = %u, snr = %u , rssi = %u\n", + RX_DOWN_DATA.rx_payload_size, RX_DOWN_DATA.rx_metadata.rx_snr, + RX_DOWN_DATA.rx_metadata.rx_rssi ); SMTC_MODEM_HAL_TRACE_ARRAY_DEBUG( "RxB Payload", RX_DOWN_DATA.rx_payload, RX_DOWN_DATA.rx_payload_size ); diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.h b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.h index 535e3d7..13e286f 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_b/smtc_ping_slot.h @@ -3,11 +3,12 @@ * * \brief Ping Slot management for LoRaWAN class B devices * - * Revised BSD License - * Copyright Semtech Corporation 2020. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,17 +18,20 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ + #ifndef __SMTC_PING_SLOT_H__ #define __SMTC_PING_SLOT_H__ diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.c b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.c index ee9b33c..3b32280 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.c @@ -228,10 +228,10 @@ void lr1mac_class_c_launch( lr1mac_class_c_t* class_c_obj ) lora_param.pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; - // +5 for MIC + FPort lora_param.pkt_params.pld_len_in_bytes = - 5 + smtc_real_get_max_payload_size( class_c_obj->lr1_mac->real, RX_SESSION_PARAM_CURRENT->rx_data_rate, - DOWN_LINK ); + MHDRSIZE + MICSIZE + + smtc_real_get_max_payload_size( class_c_obj->lr1_mac->real, RX_SESSION_PARAM_CURRENT->rx_data_rate, + DOWN_LINK ); lora_param.pkt_params.crc_is_on = false; lora_param.pkt_params.invert_iq_is_on = true; lora_param.pkt_params.preamble_len_in_symb = @@ -348,10 +348,25 @@ void lr1mac_class_c_mac_rp_callback( lr1mac_class_c_t* class_c_obj ) // save rssi and snr class_c_obj->lr1_mac->rx_down_data.rx_metadata.timestamp_ms = tcurrent_ms; - class_c_obj->lr1_mac->rx_down_data.rx_metadata.rx_snr = - class_c_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.snr_pkt_in_db; - class_c_obj->lr1_mac->rx_down_data.rx_metadata.rx_rssi = - class_c_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm; + + if( class_c_obj->rp->radio_params[from_hook_id].pkt_type == RAL_PKT_TYPE_LORA ) + { + class_c_obj->lr1_mac->rx_down_data.rx_metadata.rx_snr = + class_c_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.snr_pkt_in_db; + class_c_obj->lr1_mac->rx_down_data.rx_metadata.rx_rssi = + class_c_obj->rp->radio_params[from_hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm; + } + else if( class_c_obj->rp->radio_params[from_hook_id].pkt_type == RAL_PKT_TYPE_GFSK ) + { + class_c_obj->lr1_mac->rx_down_data.rx_metadata.rx_snr = 0; + class_c_obj->lr1_mac->rx_down_data.rx_metadata.rx_rssi = + class_c_obj->rp->radio_params[from_hook_id].rx.gfsk_pkt_status.rssi_avg_in_dbm; + } + else + { + SMTC_MODEM_HAL_PANIC( ); + } + class_c_obj->lr1_mac->rx_down_data.rx_payload_size = ( uint8_t ) class_c_obj->rp->rx_payload_size[from_hook_id]; SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.h b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.h index d4b3de8..18f5c75 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_class_c/lr1mac_class_c.h @@ -62,11 +62,11 @@ extern "C" { * ----------------------------------------------------------------------------- * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define LR1MAC_RCX_MIN_DURATION_MS 20 #define LR1MAC_NUMBER_OF_RXC_SESSION RX_SESSION_COUNT // Unicast + Multicast -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_core.c b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_core.c index 9323e81..bcd38c5 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_core.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_core.c @@ -46,10 +46,9 @@ #include "smtc_real_defs.h" #include "smtc_real_defs_str.h" - #include "lr1mac_config.h" -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) #include "relay_tx_api.h" #endif /* @@ -83,7 +82,6 @@ static const char* smtc_name_lr_fhss_cr[] = { "CR 5/6", "CR 2/3", "CR 1/2", "CR #define DISABLE_LORAWAN_RX_WINDOWS 0 #endif - /* *----------------------------------------------------------------------------------- *--- PRIVATE VARIABLES ------------------------------------------------------------- @@ -184,18 +182,7 @@ lr1mac_states_t lr1mac_core_process( lr1_stack_mac_t* lr1_mac_obj ) bool timer_in_past = false; rp_hook_get_id( lr1_mac_obj->rp, ( void* ) ( ( lr1_mac_obj ) ), &myhook_id ); -#if !defined( TEST_BYPASS_JOIN_DUTY_CYCLE ) - if( lr1_mac_obj->is_join_duty_cycle_backoff_bypass_enabled == false ) - { - if( ( lr1_mac_obj->join_status == JOINING ) && - ( ( int32_t ) ( lr1_mac_obj->next_time_to_join_seconds - smtc_modem_hal_get_time_in_s( ) ) > 0 ) ) - { - SMTC_MODEM_HAL_TRACE_PRINTF( "TOO SOON TO JOIN time is %d time target is : %d\n", - smtc_modem_hal_get_time_in_s( ), lr1_mac_obj->next_time_to_join_seconds ); - lr1_mac_obj->lr1mac_state = LWPSTATE_IDLE; - } - } -#endif + if( ( lr1_mac_obj->lr1mac_state != LWPSTATE_IDLE ) && ( ( int32_t ) ( smtc_modem_hal_get_time_in_s( ) - lr1_mac_obj->timestamp_failsafe - FAILSAFE_DURATION ) > 0 ) ) @@ -232,7 +219,8 @@ lr1mac_states_t lr1mac_core_process( lr1_stack_mac_t* lr1_mac_obj ) switch( lr1_mac_obj->radio_process_state ) { - case RADIOSTATE_IDLE: { + case RADIOSTATE_IDLE: + { lr1_mac_obj->radio_process_state = RADIOSTATE_PENDING; DBG_PRINT_WITH_LINE( "Send Payload for stack_id = %d", lr1_mac_obj->stack_id ); @@ -273,7 +261,8 @@ lr1mac_states_t lr1mac_core_process( lr1_stack_mac_t* lr1_mac_obj ) break; } - case RADIOSTATE_TX_FINISHED: { + case RADIOSTATE_TX_FINISHED: + { DBG_PRINT_WITH_LINE( " TX DONE" ); lr1_mac_obj->lr1mac_state = LWPSTATE_RX1; lr1_mac_obj->tx_duty_cycle_timestamp_ms = lr1_mac_obj->isr_tx_done_radio_timestamp; @@ -358,7 +347,7 @@ lr1mac_states_t lr1mac_core_process( lr1_stack_mac_t* lr1_mac_obj ) // STATE RX2 //********************************************************************************** case LWPSTATE_RX2: -#ifndef RELAY_TX +#if !defined( ADD_RELAY_TX ) if( lr1_mac_obj->radio_process_state == RADIOSTATE_RX_FINISHED ) { if( lr1_mac_obj->rp_planner_status == RP_STATUS_RX_PACKET ) @@ -404,7 +393,7 @@ lr1mac_states_t lr1mac_core_process( lr1_stack_mac_t* lr1_mac_obj ) { DBG_PRINT_WITH_LINE( "RX2 Timeout for stack_id = %d", lr1_mac_obj->stack_id ); } - + if( ( has_receive_valid_packet == false ) && ( smtc_relay_tx_is_enable( lr1_mac_obj->stack_id ) == true ) ) { lr1_mac_obj->lr1mac_state = LWPSTATE_RXR; @@ -476,6 +465,17 @@ status_lorawan_t lr1mac_core_join( lr1_stack_mac_t* lr1_mac_obj, uint32_t target SMTC_MODEM_HAL_TRACE_ERROR( "LP STATE NOT EQUAL TO IDLE\n" ); return ERRORLORAWAN; } +#if !defined( TEST_BYPASS_JOIN_DUTY_CYCLE ) + if( lr1_mac_obj->is_join_duty_cycle_backoff_bypass_enabled == false ) + { + if( ( int32_t ) ( lr1_mac_obj->next_time_to_join_seconds - smtc_modem_hal_get_time_in_s( ) ) > 0 ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "TOO SOON TO JOIN time is %d time target is : %d\n", + smtc_modem_hal_get_time_in_s( ), lr1_mac_obj->next_time_to_join_seconds ); + return ERRORLORAWAN; + } + } +#endif if( lr1_mac_obj->activation_mode == ACTIVATION_MODE_ABP ) { lr1_mac_obj->join_status = JOINED; @@ -539,6 +539,9 @@ void lr1mac_core_join_status_clear( lr1_stack_mac_t* lr1_mac_obj ) lr1mac_core_abort( lr1_mac_obj ); smtc_real_init_join_snapshot_channel_mask( lr1_mac_obj->real ); lr1_mac_obj->retry_join_cpt = 0; + + // Revert ADR modem in case the leave network command is called before join success + lr1_mac_obj->adr_mode_select = lr1_mac_obj->adr_mode_select_tmp; } /**************************************************/ @@ -605,8 +608,8 @@ status_lorawan_t lr1mac_core_send_stack_cid_req( lr1_stack_mac_t* lr1_mac_obj, u } status_lorawan_t lr1mac_core_payload_send_at_time( lr1_stack_mac_t* lr1_mac_obj, uint8_t fport, bool fport_enabled, - const uint8_t* data_in, uint8_t size_in, lr1mac_layer_param_t packet_type, - uint32_t target_time_ms ) + const uint8_t* data_in, uint8_t size_in, + lr1mac_layer_param_t packet_type, uint32_t target_time_ms ) { status_lorawan_t status = lr1mac_core_payload_send( lr1_mac_obj, fport, fport_enabled, data_in, size_in, packet_type, target_time_ms ); @@ -903,8 +906,6 @@ status_lorawan_t lr1mac_core_set_region( lr1_stack_mac_t* lr1_mac_obj, smtc_real lr1_stack_mac_region_config( lr1_mac_obj ); lr1mac_core_context_save( lr1_mac_obj ); - // After a region change a new join should happen, reset join counter - lr1_mac_obj->retry_join_cpt = 0; return OKLORAWAN; } return ERRORLORAWAN; @@ -1002,8 +1003,8 @@ bool lr1mac_core_convert_rtc_to_gps_epoch_time( lr1_stack_mac_t* lr1_mac_obj, ui tmp_seconds_since_epoch = lr1_mac_obj->seconds_since_epoch + tmp_s; - SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( "tx: %u, rx:%u, diff:%u\n", lr1_mac->timestamp_tx_done_device_time_req_ms, - lr1_mac->timestamp_last_device_time_ans_s, delta_tx_rx_ms ); + SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( "tx: %u, rx:%u, diff:%u\n", lr1_mac_obj->timestamp_tx_done_device_time_req_ms, + lr1_mac_obj->timestamp_last_device_time_ans_s, delta_tx_rx_ms ); SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( "DeviceTime GPS : %u.%u s\n", tmp_seconds_since_epoch, tmp_fractional_second ); *seconds_since_epoch = tmp_seconds_since_epoch; @@ -1166,59 +1167,49 @@ uint8_t lr1mac_core_get_no_rx_windows( lr1_stack_mac_t* lr1_mac_obj ) } status_lorawan_t lr1mac_core_update_join_channel( lr1_stack_mac_t* lr1_mac_obj ) { - lr1_stack_mac_region_config( lr1_mac_obj); - if( ( lr1_mac_obj->adr_mode_select != JOIN_DR_DISTRIBUTION ) || - ( ( lr1_mac_obj->retry_join_cpt == 0 ) && - ( lr1_mac_obj->adr_mode_select == JOIN_DR_DISTRIBUTION ) ) ) - { - // if it is the case force dr distribution to join - lr1_mac_obj->adr_mode_select_tmp = - lr1_mac_obj->adr_mode_select; - smtc_real_set_dr_distribution( lr1_mac_obj->real, - JOIN_DR_DISTRIBUTION, - &lr1_mac_obj->nb_trans ); - lr1_mac_obj->adr_mode_select = JOIN_DR_DISTRIBUTION; - } + lr1_stack_mac_region_config( lr1_mac_obj ); + + if( ( lr1_mac_obj->adr_mode_select != JOIN_DR_DISTRIBUTION ) && + ( lr1_mac_obj->adr_mode_select != JOIN_DR_DISTRIBUTION_LONG_TERM ) ) + { + // if it is the case force dr distribution to join + lr1_mac_obj->adr_mode_select_tmp = lr1_mac_obj->adr_mode_select; + smtc_real_set_dr_distribution( lr1_mac_obj->real, JOIN_DR_DISTRIBUTION, &lr1_mac_obj->nb_trans ); + lr1_mac_obj->adr_mode_select = JOIN_DR_DISTRIBUTION; + } + + if( lr1_mac_obj->adr_mode_select == JOIN_DR_DISTRIBUTION_LONG_TERM ) + { + smtc_real_set_dr_distribution( lr1_mac_obj->real, JOIN_DR_DISTRIBUTION_LONG_TERM, &lr1_mac_obj->nb_trans ); + } - smtc_real_get_next_tx_dr( lr1_mac_obj->real, - lr1_mac_obj->join_status, - &lr1_mac_obj->adr_mode_select, - &lr1_mac_obj->tx_data_rate, - lr1_mac_obj->tx_data_rate_adr, - &lr1_mac_obj->adr_enable ); - return ( smtc_real_get_join_next_channel( - lr1_mac_obj->real, - &( lr1_mac_obj->tx_data_rate ), - &( lr1_mac_obj->tx_frequency ), - &( lr1_mac_obj->rx1_frequency ), - &( lr1_mac_obj->rx2_frequency ), - &( lr1_mac_obj->nb_available_tx_channel ) ) ); + smtc_real_get_next_tx_dr( lr1_mac_obj->real, lr1_mac_obj->join_status, &lr1_mac_obj->adr_mode_select, + &lr1_mac_obj->tx_data_rate, lr1_mac_obj->tx_data_rate_adr, &lr1_mac_obj->adr_enable ); + return ( smtc_real_get_join_next_channel( + lr1_mac_obj->real, &( lr1_mac_obj->tx_data_rate ), &( lr1_mac_obj->tx_frequency ), + &( lr1_mac_obj->rx1_frequency ), &( lr1_mac_obj->rx2_frequency ), &( lr1_mac_obj->nb_available_tx_channel ) ) ); } status_lorawan_t lr1mac_core_update_next_tx_channel( lr1_stack_mac_t* lr1_mac_obj ) { - return( smtc_real_get_next_channel( - lr1_mac_obj->real, - lr1_mac_obj->tx_data_rate, - &( lr1_mac_obj->tx_frequency ), - &( lr1_mac_obj->rx1_frequency ), - &( lr1_mac_obj->nb_available_tx_channel ) ) ); + return ( smtc_real_get_next_channel( lr1_mac_obj->real, lr1_mac_obj->tx_data_rate, &( lr1_mac_obj->tx_frequency ), + &( lr1_mac_obj->rx1_frequency ), &( lr1_mac_obj->nb_available_tx_channel ) ) ); } uint32_t lr1mac_core_get_time_of_nwk_ans( lr1_stack_mac_t* lr1_mac_obj ) { - return (lr1_mac_obj->rtc_target_timer_ms); + return ( lr1_mac_obj->rtc_target_timer_ms ); } void lr1mac_core_set_time_of_nwk_ans( lr1_stack_mac_t* lr1_mac_obj, uint32_t target_time ) { lr1_mac_obj->rtc_target_timer_ms = target_time; } -void lr1mac_core_set_next_tx_at_time( lr1_stack_mac_t* lr1_mac_obj, bool is_send_at_time ) +void lr1mac_core_set_next_tx_at_time( lr1_stack_mac_t* lr1_mac_obj, bool is_send_at_time ) { - lr1_mac_obj->send_at_time=is_send_at_time; + lr1_mac_obj->send_at_time = is_send_at_time; } void lr1mac_core_set_join_status( lr1_stack_mac_t* lr1_mac_obj, join_status_t join_status ) { - lr1_mac_obj->join_status=join_status; + lr1_mac_obj->join_status = join_status; } /* *----------------------------------------------------------------------------------- @@ -1265,8 +1256,9 @@ static void lr1mac_mac_update( lr1_stack_mac_t* lr1_mac_obj ) //@note because datarate Distribution has been changed during join lr1_mac_obj->adr_mode_select = lr1_mac_obj->adr_mode_select_tmp; - // copy the join data rate to the default data_rate_adr => the first uplink will be transmit with the join dr (ease GW one chanel) - lr1_mac_obj->tx_data_rate_adr =lr1_mac_obj->tx_data_rate; + // copy the join data rate to the default data_rate_adr => the first uplink will be transmit with the join + // dr (ease GW one chanel) + lr1_mac_obj->tx_data_rate_adr = lr1_mac_obj->tx_data_rate; smtc_real_set_dr_distribution( lr1_mac_obj->real, lr1_mac_obj->adr_mode_select_tmp, &lr1_mac_obj->nb_trans ); lr1mac_core_context_save( lr1_mac_obj ); @@ -1332,7 +1324,7 @@ static void lr1mac_mac_update( lr1_stack_mac_t* lr1_mac_obj ) smtc_modem_hal_get_time_in_ms( ) + smtc_modem_hal_get_random_nb_in_range( 1000, 3000 ); lr1_mac_obj->lr1mac_state = LWPSTATE_TX_WAIT; // protected by tpm failsafe - lr1_mac_obj->timestamp_failsafe = smtc_modem_hal_get_time_in_s( ); + lr1_mac_obj->timestamp_failsafe = smtc_modem_hal_get_time_in_s( ); } } else diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_defs.h index 1ce15f4..b44ffc3 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_defs.h @@ -52,7 +52,7 @@ extern "C" { *----------------------------------------------------------------------------------- * --- PUBLIC CONSTANTS ------------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define LORAWAN_NVM_CTX_VERSION (0) #define LORAWAN_VERSION_MAJOR (1) @@ -94,6 +94,7 @@ extern "C" { #define MAX_TX_PAYLOAD_SIZE (255) #define FHDROFFSET (8) // MHDR+FHDR offset if OPT = 0 #define MICSIZE (4) +#define MHDRSIZE (1) #define LR1MAC_PROTOCOL_VERSION (0x00010300) #define GFSK_WHITENING_SEED (0x01FF) #define GFSK_CRC_SEED (0x1D0F) @@ -130,7 +131,7 @@ extern "C" { // #define MAX_FCNT_GAP 16384 -// clang-format on +/* clang-format on */ /* *----------------------------------------------------------------------------------- @@ -156,7 +157,7 @@ typedef enum lr1mac_states_e LWPSTATE_RX1, LWPSTATE_RX2, -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) LWPSTATE_RXR, #endif @@ -304,6 +305,7 @@ typedef enum dr_strategy_e MOBILE_LOWPER_DR_DISTRIBUTION, // for Mobile Devices with strong Low power requirement USER_DR_DISTRIBUTION, // User distribution JOIN_DR_DISTRIBUTION, // Dedicated for Join requests + JOIN_DR_DISTRIBUTION_LONG_TERM, // Dedicated for Join requests when join duty cycle = 1/10000 UNKNOWN_DR, } dr_strategy_t; @@ -332,7 +334,7 @@ typedef enum rx_win_type_e { RX1 = 0, RX2, -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) RXR, #endif } rx_win_type_t; @@ -433,7 +435,7 @@ typedef enum receive_win_s #endif RECEIVE_ON_RXBEACON = 13, -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) RECEIVE_ON_RXR = 14, #endif } receive_win_t; diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_utilities.c b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_utilities.c index 60dd5ba..0873d3c 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_utilities.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_utilities.c @@ -66,7 +66,7 @@ uint32_t lr1mac_utilities_get_symb_time_us( const uint16_t nb_symb, const ral_lo uint32_t sf_val; uint32_t bw_khz; - // clang-format off + /* clang-format off */ switch(sf) { case RAL_LORA_SF5: sf_val = 5; break; @@ -101,7 +101,7 @@ uint32_t lr1mac_utilities_get_symb_time_us( const uint16_t nb_symb, const ral_lo return 0; break; } - // clang-format on + /* clang-format on */ return ( ( ( uint32_t ) nb_symb * 1000 ) << sf_val ) / bw_khz; } diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_utilities.h b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_utilities.h index c0fa58b..2084435 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_utilities.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/lr1mac_utilities.h @@ -51,7 +51,6 @@ extern "C" { *----------------------------------------------------------------------------------- * --- PUBLIC MACROS ---------------------------------------------------------------- */ -#define SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( ... ) //@todo push it to the modem layer /*! * \brief Returns the minimum value between a and b diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/relay_real.c b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/relay_real.c index 993a690..de541e1 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/relay_real.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/relay_real.c @@ -55,7 +55,6 @@ static status_lorawan_t region_as_923_relay_get_default( uint8_t idx, uint8_t* d switch( idx ) { case 0: - case 1: *freq_wor = 923600000; *freq_ack = 923800000; break; @@ -281,16 +280,8 @@ static status_lorawan_t region_ru_864_relay_get_default( uint8_t idx, uint8_t* d break; } *datarate = 3; - smtc_duty_cycle_update( ); - if( smtc_duty_cycle_is_channel_free( *freq_wor ) == true ) - { - return OKLORAWAN; - } - else - { - SMTC_MODEM_HAL_TRACE_MSG( "NO More Duty cycle to transmit WOR\n" ); - return ERRORLORAWAN; - } + + return OKLORAWAN; } #endif @@ -362,16 +353,44 @@ static status_lorawan_t region_eu_868_relay_get_default( uint8_t idx, uint8_t* d break; } *datarate = 3; - smtc_duty_cycle_update( ); - if( smtc_duty_cycle_is_channel_free( *freq_wor ) == true ) - { - return OKLORAWAN; - } - else + + return OKLORAWAN; +} +#endif + +#if defined( REGION_WW2G4 ) +/** + * @brief Return default value for relay channel for WW2G4 + * + * @param[in] idx Index of the chanel (0 or 1) + * @param[out] datarate Datarate for the channel index idx + * @param[out] freq_wor Frequency in Hz for WOR + * @param[out] freq_ack Frequency in Hz for WOR ACK + * @return OKLORAWAN a valid config exist for this channel + * @return ERRORLORAWAN no valid config exist for this channel + */ +static status_lorawan_t region_ww2g4_relay_get_default( uint8_t idx, uint8_t* datarate, uint32_t* freq_wor, + uint32_t* freq_ack ) +{ + switch( idx ) { - SMTC_MODEM_HAL_TRACE_MSG( "NO More Duty cycle to transmit WOR\n" ); + case 0: + *freq_wor = 2423000000; + *freq_ack = 2477000000; + break; + + case 1: + *freq_wor = 2423000000; + *freq_ack = 2477000000; + break; + + default: return ERRORLORAWAN; + break; } + + *datarate = 3; + return OKLORAWAN; } #endif @@ -436,7 +455,10 @@ status_lorawan_t smtc_relay_get_default_channel_config( const smtc_real_t* real, #endif #if defined( REGION_WW2G4 ) - case SMTC_REAL_REGION_WW2G4: + case SMTC_REAL_REGION_WW2G4: { + return region_ww2g4_relay_get_default( idx, datarate, freq_wor, freq_ack ); + break; + } #endif default: SMTC_MODEM_HAL_PANIC( ); diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.c b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.c index e4bb2fd..7e55684 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.c @@ -129,9 +129,9 @@ uint8_t wor_generate_wor( uint8_t* buffer, const wor_infos_t* wor ) buffer[WOR_JOINREQ_HEADER] = WOR_MSG_TYPE_JOIN_REQUEST & 0x0F; buffer[WOR_JOINREQ_DR_PL] = wor->join_request.dr & 0x0F; - buffer[WOR_JOINREQ_FREQ_7_0] = ( uint8_t )( freq_step ); - buffer[WOR_JOINREQ_FREQ_15_8] = ( uint8_t )( freq_step >> 8 ); - buffer[WOR_JOINREQ_FREQ_23_16] = ( uint8_t )( freq_step >> 16 ); + buffer[WOR_JOINREQ_FREQ_7_0] = ( uint8_t ) ( freq_step ); + buffer[WOR_JOINREQ_FREQ_15_8] = ( uint8_t ) ( freq_step >> 8 ); + buffer[WOR_JOINREQ_FREQ_23_16] = ( uint8_t ) ( freq_step >> 16 ); return WOR_JOINREQ_LENGTH; } @@ -141,18 +141,18 @@ uint8_t wor_generate_wor( uint8_t* buffer, const wor_infos_t* wor ) buffer[WOR_UPLINK_HEADER] = WOR_MSG_TYPE_STANDARD_UPLINK & 0x0F; - buffer[WOR_UPLINK_DEVADDR_7_0] = ( uint8_t )( wor->uplink.devaddr ); - buffer[WOR_UPLINK_DEVADDR_15_8] = ( uint8_t )( wor->uplink.devaddr >> 8 ); - buffer[WOR_UPLINK_DEVADDR_23_16] = ( uint8_t )( wor->uplink.devaddr >> 16 ); - buffer[WOR_UPLINK_DEVADDR_31_24] = ( uint8_t )( wor->uplink.devaddr >> 24 ); - buffer[WOR_UPLINK_FCNT_7_0] = ( uint8_t )( wor->uplink.fcnt ); - buffer[WOR_UPLINK_FCNT_15_8] = ( uint8_t )( wor->uplink.fcnt >> 8 ); + buffer[WOR_UPLINK_DEVADDR_7_0] = ( uint8_t ) ( wor->uplink.devaddr ); + buffer[WOR_UPLINK_DEVADDR_15_8] = ( uint8_t ) ( wor->uplink.devaddr >> 8 ); + buffer[WOR_UPLINK_DEVADDR_23_16] = ( uint8_t ) ( wor->uplink.devaddr >> 16 ); + buffer[WOR_UPLINK_DEVADDR_31_24] = ( uint8_t ) ( wor->uplink.devaddr >> 24 ); + buffer[WOR_UPLINK_FCNT_7_0] = ( uint8_t ) ( wor->uplink.fcnt ); + buffer[WOR_UPLINK_FCNT_15_8] = ( uint8_t ) ( wor->uplink.fcnt >> 8 ); const uint8_t buffer_to_enc[4] = { [0] = wor->uplink.dr & 0x0F, - [1] = ( uint8_t )( freq_step ), - [2] = ( uint8_t )( freq_step >> 8 ), - [3] = ( uint8_t )( freq_step >> 16 ), + [1] = ( uint8_t ) ( freq_step ), + [2] = ( uint8_t ) ( freq_step >> 8 ), + [3] = ( uint8_t ) ( freq_step >> 16 ), }; wor_aes_wor_uplink_enc( buffer_to_enc, buffer + WOR_UPLINK_PAYLOAD_ENC_1, &wor->uplink, &wor->rf_infos, NULL ); @@ -185,26 +185,26 @@ uint32_t wor_compute_mic_wor( const wor_mic_infos_t* mic_info, const uint8_t* wo buffer_b0[3] = 0x00; buffer_b0[4] = 0x00; buffer_b0[5] = 0x00; // Direction - buffer_b0[6] = ( uint8_t )( mic_info->dev_addr ); - buffer_b0[7] = ( uint8_t )( mic_info->dev_addr >> 8 ); - buffer_b0[8] = ( uint8_t )( mic_info->dev_addr >> 16 ); - buffer_b0[9] = ( uint8_t )( mic_info->dev_addr >> 24 ); - buffer_b0[10] = ( uint8_t )( mic_info->wfcnt ); - buffer_b0[11] = ( uint8_t )( mic_info->wfcnt >> 8 ); - buffer_b0[12] = ( uint8_t )( mic_info->wfcnt >> 16 ); - buffer_b0[13] = ( uint8_t )( mic_info->wfcnt >> 24 ); + buffer_b0[6] = ( uint8_t ) ( mic_info->dev_addr ); + buffer_b0[7] = ( uint8_t ) ( mic_info->dev_addr >> 8 ); + buffer_b0[8] = ( uint8_t ) ( mic_info->dev_addr >> 16 ); + buffer_b0[9] = ( uint8_t ) ( mic_info->dev_addr >> 24 ); + buffer_b0[10] = ( uint8_t ) ( mic_info->wfcnt ); + buffer_b0[11] = ( uint8_t ) ( mic_info->wfcnt >> 8 ); + buffer_b0[12] = ( uint8_t ) ( mic_info->wfcnt >> 16 ); + buffer_b0[13] = ( uint8_t ) ( mic_info->wfcnt >> 24 ); buffer_b0[14] = 0x00; buffer_b0[15] = 0x0E; uint8_t tmp[10]; - tmp[0] = ( uint8_t )( mic_info->dev_addr ); - tmp[1] = ( uint8_t )( mic_info->dev_addr >> 8 ); - tmp[2] = ( uint8_t )( mic_info->dev_addr >> 16 ); - tmp[3] = ( uint8_t )( mic_info->dev_addr >> 24 ); + tmp[0] = ( uint8_t ) ( mic_info->dev_addr ); + tmp[1] = ( uint8_t ) ( mic_info->dev_addr >> 8 ); + tmp[2] = ( uint8_t ) ( mic_info->dev_addr >> 16 ); + tmp[3] = ( uint8_t ) ( mic_info->dev_addr >> 24 ); memcpy( tmp + 4, wor_enc, 4 ); - tmp[8] = ( uint8_t )( mic_info->wfcnt ); - tmp[9] = ( uint8_t )( mic_info->wfcnt >> 8 ); + tmp[8] = ( uint8_t ) ( mic_info->wfcnt ); + tmp[9] = ( uint8_t ) ( mic_info->wfcnt >> 8 ); return crypto_relay_compute_mic( wor_s_int_key, buffer_b0, tmp, sizeof( tmp ) ); } @@ -223,7 +223,7 @@ void wor_decrypt_ack( const uint8_t* buffer, const wor_ack_mic_info_t* mic_infos ack->cad_to_rx = WOR_ACK_UPLINK_GET_CAD_RX( state_sync ); ack->relay_fwd = WOR_ACK_UPLINK_GET_FWD( state_sync ); -#if( 0 ) +#if MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON // Un-comment to display more information on the WOR ACK const char* cad_periodd_str[] = { "1 s", "500 ms", "250 ms", "100 ms", "50 ms", "20 ms" }; const char* fwd_relay_str[] = { "OK", "RETRY_30MIN", "RETRY_60MIN", "DISABLED" }; @@ -265,32 +265,32 @@ uint32_t wor_compute_mic_ack( const wor_ack_mic_info_t* mic_info, const uint8_t* buffer_b0[3] = 0x00; buffer_b0[4] = 0x00; buffer_b0[5] = 0x01; // Direction - buffer_b0[6] = ( uint8_t )( mic_info->dev_addr ); - buffer_b0[7] = ( uint8_t )( mic_info->dev_addr >> 8 ); - buffer_b0[8] = ( uint8_t )( mic_info->dev_addr >> 16 ); - buffer_b0[9] = ( uint8_t )( mic_info->dev_addr >> 24 ); - buffer_b0[10] = ( uint8_t )( mic_info->wfcnt ); - buffer_b0[11] = ( uint8_t )( mic_info->wfcnt >> 8 ); - buffer_b0[12] = ( uint8_t )( mic_info->wfcnt >> 16 ); - buffer_b0[13] = ( uint8_t )( mic_info->wfcnt >> 24 ); + buffer_b0[6] = ( uint8_t ) ( mic_info->dev_addr ); + buffer_b0[7] = ( uint8_t ) ( mic_info->dev_addr >> 8 ); + buffer_b0[8] = ( uint8_t ) ( mic_info->dev_addr >> 16 ); + buffer_b0[9] = ( uint8_t ) ( mic_info->dev_addr >> 24 ); + buffer_b0[10] = ( uint8_t ) ( mic_info->wfcnt ); + buffer_b0[11] = ( uint8_t ) ( mic_info->wfcnt >> 8 ); + buffer_b0[12] = ( uint8_t ) ( mic_info->wfcnt >> 16 ); + buffer_b0[13] = ( uint8_t ) ( mic_info->wfcnt >> 24 ); buffer_b0[14] = 0x00; buffer_b0[15] = 0x07; - uint8_t tmp[13]; + uint8_t tmp[16] = { 0 }; memcpy( tmp, ack_uplink_enc, 3 ); - const uint32_t freq_step = mic_info->frequency_hz / 100; + const uint32_t freq_step = mic_info->wor_frequency_hz / 100; - tmp[3] = mic_info->datarate & 0x0F; - tmp[4] = ( uint8_t )( freq_step ); - tmp[5] = ( uint8_t )( freq_step >> 8 ); - tmp[6] = ( uint8_t )( freq_step >> 16 ); - tmp[7] = ( uint8_t )( mic_info->wfcnt ); - tmp[8] = ( uint8_t )( mic_info->wfcnt >> 8 ); - tmp[9] = ( uint8_t )( mic_info->dev_addr ); - tmp[10] = ( uint8_t )( mic_info->dev_addr >> 8 ); - tmp[11] = ( uint8_t )( mic_info->dev_addr >> 16 ); - tmp[12] = ( uint8_t )( mic_info->dev_addr >> 24 ); + tmp[3] = mic_info->wor_datarate & 0x0F; + tmp[4] = ( uint8_t ) ( freq_step ); + tmp[5] = ( uint8_t ) ( freq_step >> 8 ); + tmp[6] = ( uint8_t ) ( freq_step >> 16 ); + tmp[7] = ( uint8_t ) ( mic_info->wfcnt ); + tmp[8] = ( uint8_t ) ( mic_info->wfcnt >> 8 ); + tmp[9] = ( uint8_t ) ( mic_info->dev_addr ); + tmp[10] = ( uint8_t ) ( mic_info->dev_addr >> 8 ); + tmp[11] = ( uint8_t ) ( mic_info->dev_addr >> 16 ); + tmp[12] = ( uint8_t ) ( mic_info->dev_addr >> 24 ); return crypto_relay_compute_mic( wor_s_int_key, buffer_b0, tmp, sizeof( tmp ) ); } @@ -339,36 +339,119 @@ uint8_t wor_convert_cadtorx( const wor_ack_cad_to_rx_t cad_to_rx ) void wor_derive_root_skey( uint32_t dev_addr ) { - uint8_t block[16]; - memset( block, 0, sizeof( block ) ); - block[0] = 0x01; + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_modem_crypto_derive_relay_session_keys( dev_addr, RELAY_STACK_ID ) == + SMTC_MODEM_CRYPTO_RC_SUCCESS ); +} + +void wor_derive_keys( const uint8_t root_wor_s_key[16], uint32_t dev_addr, uint8_t wor_s_int_key[16], + uint8_t wor_s_enc_key[16] ) +{ + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_modem_crypto_set_key( SMTC_SE_RELAY_ROOT_WOR_S_KEY, root_wor_s_key, + RELAY_STACK_ID ) == SMTC_MODEM_CRYPTO_RC_SUCCESS ); - SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_derive_and_store_key( block, SMTC_SE_NWK_S_ENC_KEY, - SMTC_RELAY_ROOT_WOR_S_KEY, - RELAY_STACK_ID ) == SMTC_SE_RC_SUCCESS ); + uint8_t block[16] = { 0 }; - memset( block, 0, sizeof( block ) ); block[0] = 0x01; block[1] = ( uint8_t )( dev_addr ); block[2] = ( uint8_t )( dev_addr >> 8 ); block[3] = ( uint8_t )( dev_addr >> 16 ); block[4] = ( uint8_t )( dev_addr >> 24 ); - SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_derive_and_store_key( block, SMTC_RELAY_ROOT_WOR_S_KEY, - SMTC_RELAY_WOR_S_INT_KEY, - RELAY_STACK_ID ) == SMTC_SE_RC_SUCCESS ); + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_aes_encrypt( block, 16, SMTC_SE_RELAY_ROOT_WOR_S_KEY, + wor_s_int_key, + RELAY_STACK_ID ) == SMTC_SE_RC_SUCCESS ); - memset( block, 0, sizeof( block ) ); block[0] = 0x02; - block[1] = ( uint8_t )( dev_addr ); - block[2] = ( uint8_t )( dev_addr >> 8 ); - block[3] = ( uint8_t )( dev_addr >> 16 ); - block[4] = ( uint8_t )( dev_addr >> 24 ); - SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_derive_and_store_key( block, SMTC_RELAY_ROOT_WOR_S_KEY, - SMTC_RELAY_WOR_S_ENC_KEY, - RELAY_STACK_ID ) == SMTC_SE_RC_SUCCESS ); + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_aes_encrypt( block, 16, SMTC_SE_RELAY_ROOT_WOR_S_KEY, + wor_s_enc_key, + RELAY_STACK_ID ) == SMTC_SE_RC_SUCCESS ); + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_modem_crypto_set_key( SMTC_SE_RELAY_WOR_S_INT_KEY, wor_s_int_key, + RELAY_STACK_ID ) == SMTC_MODEM_CRYPTO_RC_SUCCESS ); + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_modem_crypto_set_key( SMTC_SE_RELAY_WOR_S_ENC_KEY, wor_s_enc_key, + RELAY_STACK_ID ) == SMTC_MODEM_CRYPTO_RC_SUCCESS ); } +bool wor_extract_wor_info( const uint8_t* buffer, const uint8_t length, wor_infos_t* wor ) +{ + wor->wor_type = ( wor_msg_type_t ) buffer[0] & 0x0F; + if( wor->wor_type == WOR_MSG_TYPE_JOIN_REQUEST ) + { + if( length != WOR_JOINREQ_LENGTH ) + { + SMTC_MODEM_HAL_TRACE_MSG( "Decode WOR: JOIN REQUEST wrong size\n" ); + return false; + } + wor->join_request.dr = buffer[WOR_JOINREQ_DR_PL] & 0x0F; + wor->join_request.freq_hz = ( buffer[WOR_JOINREQ_FREQ_23_16] << 16 ) + ( buffer[WOR_JOINREQ_FREQ_15_8] << 8 ) + + ( buffer[WOR_JOINREQ_FREQ_7_0] ); + wor->join_request.freq_hz *= 100; + // SMTC_MODEM_HAL_TRACE_MSG( "Decode WOR JOIN: ok\n" ); + return true; + } + + if( wor->wor_type == WOR_MSG_TYPE_STANDARD_UPLINK ) + { + if( length != WOR_UPLINK_LENGTH ) + { + SMTC_MODEM_HAL_TRACE_MSG( "Decode WOR: UPLINK wrong size\n" ); + return false; + } + + memcpy( wor->uplink.enc_data, buffer + WOR_UPLINK_PAYLOAD_ENC_1, 4 ); + + wor->uplink.devaddr = ( buffer[WOR_UPLINK_DEVADDR_31_24] << 24 ) + ( buffer[WOR_UPLINK_DEVADDR_23_16] << 16 ) + + ( buffer[WOR_UPLINK_DEVADDR_15_8] << 8 ) + ( buffer[WOR_UPLINK_DEVADDR_7_0] ); + wor->uplink.fcnt = ( buffer[WOR_UPLINK_FCNT_15_8] << 8 ) + ( buffer[WOR_UPLINK_FCNT_7_0] ); + + // SMTC_MODEM_HAL_TRACE_MSG( "Decode WOR STD UL: ok\n" ); + return true; + } + + SMTC_MODEM_HAL_TRACE_MSG( "Decode WOR: Unknow message\n" ); + return false; +} +uint32_t wor_extract_mic_wor_uplink( const uint8_t* buffer ) +{ + uint32_t mic; + memcpy( &mic, buffer + WOR_UPLINK_MIC_1, 4 ); + return mic; +} +void wor_decode_wor_enc_data( const uint8_t buffer_enc[4], wor_uplink_t* wor_ul, const wor_rf_infos_t* wor_rf, + const uint8_t wor_s_enc_key[16] ) +{ + uint8_t decoded_data[4]; + wor_aes_wor_uplink_enc( buffer_enc, decoded_data, wor_ul, wor_rf, wor_s_enc_key ); + + wor_ul->dr = decoded_data[0] & 0x0F; + wor_ul->freq_hz = ( decoded_data[1] + ( decoded_data[2] << 8 ) + ( decoded_data[3] << 16 ) ) * 100; +} +uint8_t wor_generate_ack( uint8_t* buffer, const wor_ack_infos_t* ack, const wor_ack_mic_info_t* mic_info, + const uint8_t* wor_s_int_key, const uint8_t wor_s_enc_key[16] ) +{ + uint32_t tmp = 0; + tmp |= WOR_ACK_UPLINK_SET_TOFFSET( ack->t_offset ); + tmp |= WOR_ACK_UPLINK_SET_CADP( ack->period ); + tmp |= WOR_ACK_UPLINK_SET_XTAL( ack->relay_ppm ); + tmp |= WOR_ACK_UPLINK_SET_GTW_DR( ack->dr_relay_gtw ); + tmp |= WOR_ACK_UPLINK_SET_FWD( ack->relay_fwd ); + tmp |= WOR_ACK_UPLINK_SET_CAD_RX( ack->cad_to_rx ); + + const uint8_t buffer_tmp[3] = { + [0] = ( uint8_t )( tmp ), + [1] = ( uint8_t )( tmp >> 8 ), + [2] = ( uint8_t )( tmp >> 16 ), + }; + + wor_aes_ack_uplink_enc( buffer_tmp, buffer + WOR_ACK_PAYLOAD_ENC_1, mic_info, wor_s_enc_key ); + + + const uint32_t mic = wor_compute_mic_ack( mic_info, buffer + WOR_ACK_PAYLOAD_ENC_1, wor_s_int_key ); + + memcpy( buffer + WOR_ACK_MIC_1, &mic, 4 ); + return WOR_ACK_LENGTH; +} /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- @@ -385,18 +468,18 @@ static void wor_aes_wor_uplink_enc( const uint8_t* buffer_in, uint8_t* buffer_ou a_block[1] = 0x00; a_block[2] = 0x00; a_block[3] = 0x00; // Uplink - a_block[4] = ( uint8_t )( wor_ul->devaddr ); - a_block[5] = ( uint8_t )( wor_ul->devaddr >> 8 ); - a_block[6] = ( uint8_t )( wor_ul->devaddr >> 16 ); - a_block[7] = ( uint8_t )( wor_ul->devaddr >> 24 ); - a_block[8] = ( uint8_t )( wor_ul->fcnt ); - a_block[9] = ( uint8_t )( wor_ul->fcnt >> 8 ); - a_block[10] = ( uint8_t )( wor_ul->fcnt >> 16 ); - a_block[11] = ( uint8_t )( wor_ul->fcnt >> 24 ); - a_block[12] = ( uint8_t )( freq_step ); - a_block[13] = ( uint8_t )( freq_step >> 8 ); - a_block[14] = ( uint8_t )( freq_step >> 16 ); - a_block[15] = ( uint8_t )( wor_rf->dr & 0x0F ); + a_block[4] = ( uint8_t ) ( wor_ul->devaddr ); + a_block[5] = ( uint8_t ) ( wor_ul->devaddr >> 8 ); + a_block[6] = ( uint8_t ) ( wor_ul->devaddr >> 16 ); + a_block[7] = ( uint8_t ) ( wor_ul->devaddr >> 24 ); + a_block[8] = ( uint8_t ) ( wor_ul->fcnt ); + a_block[9] = ( uint8_t ) ( wor_ul->fcnt >> 8 ); + a_block[10] = ( uint8_t ) ( wor_ul->fcnt >> 16 ); + a_block[11] = ( uint8_t ) ( wor_ul->fcnt >> 24 ); + a_block[12] = ( uint8_t ) ( freq_step ); + a_block[13] = ( uint8_t ) ( freq_step >> 8 ); + a_block[14] = ( uint8_t ) ( freq_step >> 16 ); + a_block[15] = ( uint8_t ) ( wor_rf->dr & 0x0F ); crypto_relay_encrypt( buffer_in, 4, wor_s_enc_key, a_block, buffer_out ); } @@ -412,18 +495,18 @@ static void wor_aes_ack_uplink_enc( const uint8_t* buffer_in, uint8_t* buffer_ou a_block[1] = 0x00; a_block[2] = 0x00; a_block[3] = 0x01; - a_block[4] = ( uint8_t )( crypto_info->dev_addr ); - a_block[5] = ( uint8_t )( crypto_info->dev_addr >> 8 ); - a_block[6] = ( uint8_t )( crypto_info->dev_addr >> 16 ); - a_block[7] = ( uint8_t )( crypto_info->dev_addr >> 24 ); - a_block[8] = ( uint8_t )( crypto_info->wfcnt ); - a_block[9] = ( uint8_t )( crypto_info->wfcnt >> 8 ); - a_block[10] = ( uint8_t )( crypto_info->wfcnt >> 16 ); - a_block[11] = ( uint8_t )( crypto_info->wfcnt >> 24 ); - a_block[12] = ( uint8_t )( freq_step ); - a_block[13] = ( uint8_t )( freq_step >> 8 ); - a_block[14] = ( uint8_t )( freq_step >> 16 ); - a_block[15] = ( uint8_t )( crypto_info->datarate & 0x0F ); + a_block[4] = ( uint8_t ) ( crypto_info->dev_addr ); + a_block[5] = ( uint8_t ) ( crypto_info->dev_addr >> 8 ); + a_block[6] = ( uint8_t ) ( crypto_info->dev_addr >> 16 ); + a_block[7] = ( uint8_t ) ( crypto_info->dev_addr >> 24 ); + a_block[8] = ( uint8_t ) ( crypto_info->wfcnt ); + a_block[9] = ( uint8_t ) ( crypto_info->wfcnt >> 8 ); + a_block[10] = ( uint8_t ) ( crypto_info->wfcnt >> 16 ); + a_block[11] = ( uint8_t ) ( crypto_info->wfcnt >> 24 ); + a_block[12] = ( uint8_t ) ( freq_step ); + a_block[13] = ( uint8_t ) ( freq_step >> 8 ); + a_block[14] = ( uint8_t ) ( freq_step >> 16 ); + a_block[15] = ( uint8_t ) ( crypto_info->datarate & 0x0F ); crypto_relay_encrypt( buffer_in, 3, wor_s_enc_key, a_block, buffer_out ); } @@ -433,7 +516,7 @@ static void crypto_relay_encrypt( const uint8_t* buffer, uint16_t len, const uin { if( wor_s_enc_key != NULL ) { - SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_modem_crypto_set_key( SMTC_RELAY_WOR_S_ENC_KEY, wor_s_enc_key, + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_modem_crypto_set_key( SMTC_SE_RELAY_WOR_S_ENC_KEY, wor_s_enc_key, RELAY_STACK_ID ) == SMTC_MODEM_CRYPTO_RC_SUCCESS ); } @@ -442,7 +525,7 @@ static void crypto_relay_encrypt( const uint8_t* buffer, uint16_t len, const uin int16_t local_size = len; // Length in relay communication is always less than 255. while( local_size > 0 ) { - SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_aes_encrypt( a_block, 16, SMTC_RELAY_WOR_S_ENC_KEY, + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_aes_encrypt( a_block, 16, SMTC_SE_RELAY_WOR_S_ENC_KEY, s_block, RELAY_STACK_ID ) == SMTC_SE_RC_SUCCESS ); @@ -460,14 +543,14 @@ static uint32_t crypto_relay_compute_mic( const uint8_t wor_s_int_key[16], const { if( wor_s_int_key != NULL ) { - SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_modem_crypto_set_key( SMTC_RELAY_WOR_S_INT_KEY, wor_s_int_key, + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_modem_crypto_set_key( SMTC_SE_RELAY_WOR_S_INT_KEY, wor_s_int_key, RELAY_STACK_ID ) == SMTC_MODEM_CRYPTO_RC_SUCCESS ); } uint32_t mic32 = 0; SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_compute_aes_cmac( mic_bx_buffer, buffer, size, - SMTC_RELAY_WOR_S_INT_KEY, &mic32, + SMTC_SE_RELAY_WOR_S_INT_KEY, &mic32, RELAY_STACK_ID ) == SMTC_SE_RC_SUCCESS ); return mic32; diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.h b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.h index 14d0862..3fb892b 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio.h @@ -158,6 +158,8 @@ typedef struct wor_ack_mic_info_s uint32_t wfcnt; uint8_t datarate; uint32_t frequency_hz; + uint8_t wor_datarate; + uint32_t wor_frequency_hz; } wor_ack_mic_info_t; /* @@ -262,6 +264,68 @@ uint8_t wor_convert_ppm( const wor_ack_ppm_error_t ppm ); */ uint8_t wor_convert_cadtorx( const wor_ack_cad_to_rx_t cad_to_rx ); +/** + * @brief Function called by RP to start the CAD + * + * @param rp_void radio planner pointer + */ +void wor_ral_callback_start_cad( void* rp_void ); + +/** + * @brief Allow a relay RX to derive integrity and encryption key from root key + * + * @param[in] root_wor_s_key Root WOR session key + * @param[in] dev_addr DevAddr of the ED + * @param[out] wor_s_int_key WOR Session Integrity Key + * @param[out] wor_s_enc_key WOR Session Encryption Key + */ +void wor_derive_keys( const uint8_t root_wor_s_key[16], uint32_t dev_addr, uint8_t wor_s_int_key[16], + uint8_t wor_s_enc_key[16] ); +/** + * @brief Extract WOR data from a buffer + * + * Encoded data are still unencrypted. + * + * @param[in] buffer Input buffer with WOR frame + * @param[in] length Length of input buffer + * @param[out] wor WOR info to filled + * @return true WOR type and payload length is coherent but content could still be NOK + * @return false WOR type or length is NOK + */ +bool wor_extract_wor_info( const uint8_t* buffer, const uint8_t length, wor_infos_t* wor ); + +/** + * @brief Extract MIC from the WOR payload + * + * Only used in relay RX to check MIC + * + * @param[in] buffer Input buffer with WOR frame + * @return uint32_t MIC value + */ +uint32_t wor_extract_mic_wor_uplink( const uint8_t* buffer ); +/** + * @brief Decode the WOR data + * + * @param[in] buffer_enc Encoded buffer + * @param[in,out] wor_ul WOR uplink data + * @param[in] wor_rf WOR Radiofrequency info + * @param[in] wor_s_enc_key WOR Session Encryption Key + */ +void wor_decode_wor_enc_data( const uint8_t buffer_enc[4], wor_uplink_t* wor_ul, const wor_rf_infos_t* wor_rf, + const uint8_t wor_s_enc_key[16] ); + +/** + * @brief Generate WOR ACK payload to be send + * + * @param[out] buffer Buffer to fill with WOR frame + * @param[in] ack WOR ACK infos + * @param[in] mic_info Info required to compute MIC + * @param[in] wor_s_int_key WOR Session Integrity Key + * @param[in] wor_s_enc_key WOR Session Encryption Key + * @return uint8_t Length of ouput buffer + */ +uint8_t wor_generate_ack( uint8_t* buffer, const wor_ack_infos_t* ack, const wor_ack_mic_info_t* mic_info, + const uint8_t* wor_s_int_key, const uint8_t wor_s_enc_key[16] ); #ifdef _cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.c b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.c index 84df0e0..3a2f7a2 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.c @@ -46,7 +46,7 @@ #include "smtc_real.h" #include "wake_on_radio_ral.h" #include "radio_planner_stats.h" - +#include "lr1mac_utilities.h" /* * ----------------------------------------------------------------------------- * --- PRIVATE MACROS ---------------------------------------------------------- @@ -66,25 +66,52 @@ *----------------------------------------------------------------------------------- *--- PRIVATE FUNCTIONS DECLARATION ------------------------------------------------- */ -/** - * @brief Function called by RP to send WOR and WOR ACK - * - * @param rp_void radio planner pointer - */ -static void wor_ral_callback_start_tx( void* rp_void ); - -/** - * @brief Function called by RP to receive WOR, WOR ACK and LoRaWAN uplink - * - * @param rp_void - */ -static void wor_ral_callback_start_rx( void* rp_void ); /* *----------------------------------------------------------------------------------- *--- PUBLIC FUNCTIONS DEFINITIONS -------------------------------------------------- */ +void wor_ral_init_tx_wor( smtc_real_t* real, uint8_t dr, uint32_t freq_hz, uint16_t preamble_len_symb, + uint8_t payload_len, rp_radio_params_t* param ) +{ + // assert_param( param != NULL ); + + modulation_type_t modulation_type = smtc_real_get_modulation_type_from_datarate( real, dr ); + + if( modulation_type == LORA ) + { + uint8_t sf; + lr1mac_bandwidth_t bw; + ralf_params_lora_t* lora = ¶m->tx.lora; + + smtc_real_lora_dr_to_sf_bw( real, dr, &sf, &bw ); + + lora->sync_word = smtc_real_get_sync_word( real ); + lora->symb_nb_timeout = 8; + lora->rf_freq_in_hz = freq_hz; + lora->output_pwr_in_dbm = smtc_real_clamp_output_power_eirp_vs_freq_and_dr( + real, smtc_real_get_default_max_eirp( real ), freq_hz, dr ); + + lora->mod_params.cr = smtc_real_get_coding_rate( real ); + lora->mod_params.sf = ( ral_lora_sf_t ) sf; + lora->mod_params.bw = ( ral_lora_bw_t ) bw; + lora->mod_params.ldro = ral_compute_lora_ldro( lora->mod_params.sf, lora->mod_params.bw ); + + lora->pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; + lora->pkt_params.pld_len_in_bytes = payload_len; + lora->pkt_params.crc_is_on = true; + lora->pkt_params.invert_iq_is_on = true; + lora->pkt_params.preamble_len_in_symb = preamble_len_symb; + + param->pkt_type = RAL_PKT_TYPE_LORA; + } + else + { + SMTC_MODEM_HAL_PANIC( "MODULATION NOT SUPPORTED\n" ); + } +} + bool wor_schedule_tx_wor( uint8_t hook_id, radio_planner_t* rp, wor_tx_param_t* wor_param ) { rp_radio_params_t param = { .pkt_type = RAL_PKT_TYPE_LORA }; @@ -201,7 +228,7 @@ bool wor_schedule_rx_wor_ack( uint8_t hook_id, radio_planner_t* rp, wor_ack_rx_p return false; } -static void wor_ral_callback_start_tx( void* rp_void ) +void wor_ral_callback_start_tx( void* rp_void ) { radio_planner_t* rp = ( radio_planner_t* ) rp_void; uint8_t id = rp->radio_task_id; @@ -213,7 +240,7 @@ static void wor_ral_callback_start_tx( void* rp_void ) ral_set_pkt_payload( &( rp->radio->ral ), rp->payload[id], rp->payload_buffer_size[id] ) == RAL_STATUS_OK ); // Wait the exact time - while( ( int32_t )( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) >= 0 ) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) >= 0 ) { // Do nothing } @@ -223,7 +250,7 @@ static void wor_ral_callback_start_tx( void* rp_void ) rp_stats_set_tx_timestamp( &rp->stats, smtc_modem_hal_get_time_in_ms( ) ); } -static void wor_ral_callback_start_rx( void* rp_void ) +void wor_ral_callback_start_rx( void* rp_void ) { radio_planner_t* rp = ( radio_planner_t* ) rp_void; uint8_t id = rp->radio_task_id; @@ -246,13 +273,213 @@ static void wor_ral_callback_start_rx( void* rp_void ) RAL_IRQ_RX_CRC_ERROR ) == RAL_STATUS_OK ); // Wait the exact time - while( ( int32_t )( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) { } smtc_modem_hal_start_radio_tcxo( ); smtc_modem_hal_set_ant_switch( false ); - SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_rx( &( rp->radio->ral ), rp->radio_params[id].rx.timeout_in_ms ) == + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_rx( &( rp->radio->ral ), rp->radio_params[id].rx.timeout_in_ms + 1000 ) == RAL_STATUS_OK ); rp_stats_set_rx_timestamp( &rp->stats, smtc_modem_hal_get_time_in_ms( ) ); } + +void wor_ral_init_rx_wor( smtc_real_t* real, uint8_t dr, uint32_t freq_hz, wor_cad_periodicity_t cad_period, + uint8_t max_payload, rp_radio_params_t* param ) +{ + const modulation_type_t modulation_type = smtc_real_get_modulation_type_from_datarate( real, dr ); + if( modulation_type == LORA ) + { + uint8_t sf; + lr1mac_bandwidth_t bw; + ralf_params_lora_t* lora = ¶m->rx.lora; + + smtc_real_lora_dr_to_sf_bw( real, dr, &sf, &bw ); + + const uint32_t symb_time_us = + lr1mac_utilities_get_symb_time_us( 1, ( ral_lora_sf_t ) sf, ( ral_lora_bw_t ) bw ); + + lora->symb_nb_timeout = 10; + lora->sync_word = smtc_real_get_sync_word( real ); + lora->rf_freq_in_hz = freq_hz; + + lora->mod_params.cr = smtc_real_get_coding_rate( real ); + lora->mod_params.sf = ( ral_lora_sf_t ) sf; + lora->mod_params.bw = ( ral_lora_bw_t ) bw; + lora->mod_params.ldro = ral_compute_lora_ldro( lora->mod_params.sf, lora->mod_params.bw ); + + lora->pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; + lora->pkt_params.pld_len_in_bytes = max_payload; + lora->pkt_params.crc_is_on = true; + lora->pkt_params.invert_iq_is_on = true; + lora->pkt_params.preamble_len_in_symb = wor_convert_cad_period_in_ms( cad_period ) * 1000 / symb_time_us + 30; + + param->pkt_type = RAL_PKT_TYPE_LORA; + } + else + { + SMTC_MODEM_HAL_PANIC( "MODULATION NOT SUPPORTED\n" ); + } +} + +void wor_ral_init_cad( smtc_real_t* real, uint8_t dr, wor_cad_periodicity_t cad_period, bool is_first, + uint32_t wor_toa_ms, ral_lora_cad_params_t* param ) +{ + uint8_t sf; + lr1mac_bandwidth_t bw; + + smtc_real_lora_dr_to_sf_bw( real, dr, &sf, &bw ); + +#if defined( LR11XX_TRANSCEIVER ) + + const uint8_t det_peak_bw500[] = { 65, 70, 77, 85, 78, 80, 79, 82 }; + const uint8_t det_peak_bw250[] = { 60, 61, 64, 72, 63, 71, 73, 75 }; + const uint8_t det_peak_bw125[] = { 56, 52, 52, 58, 58, 62, 66, 68 }; +#else + // following value from "SX126X CAD performance evaluation V2_1.pdf" + const uint8_t det_peak_bw125[] = { 21, 22, 22, 22, 23, 24, 25, 28 }; + const uint8_t det_peak_bw250[] = { 21, 22, 22, 22, 23, 24, 25, 28 }; + const uint8_t det_peak_bw500[] = { 21, 22, 22, 23, 23, 24, 26, 30 }; +#endif + + if( ( bw == BW500 ) && ( sf >= 5 ) ) + { + param->cad_det_peak_in_symb = det_peak_bw500[sf - 5]; + } + else if( ( bw == BW250 ) && ( sf >= 5 ) ) + { + param->cad_det_peak_in_symb = det_peak_bw250[sf - 5]; + } + else if( ( bw == BW125 ) && ( sf >= 5 ) ) + { + param->cad_det_peak_in_symb = det_peak_bw125[sf - 5]; + } + else + { + SMTC_MODEM_HAL_PANIC( "DR%d SF%d BW%d \n", dr, sf, bw ); + } + + param->cad_det_min_in_symb = 10; + param->cad_timeout_in_ms = wor_convert_cad_period_in_ms( cad_period ) + wor_toa_ms; + param->cad_timeout_in_ms += ( param->cad_timeout_in_ms >> 4 ); // Add a bit of margin + + if( is_first == true ) + { + if( smtc_modem_hal_get_radio_tcxo_startup_delay_ms( ) <= 1 ) + { + param->cad_exit_mode = RAL_LORA_CAD_ONLY; + param->cad_symb_nb = RAL_LORA_CAD_01_SYMB; + } + else + { + // In case of TCXO the radio is set in CAD_TO_RX to avoid to wait the TXCO startup delay + // The second CAD is setup while the radio is already in Rx mode and seems ignored by the radio + param->cad_exit_mode = RAL_LORA_CAD_RX; + param->cad_symb_nb = RAL_LORA_CAD_02_SYMB; + } + } + else + { + param->cad_exit_mode = RAL_LORA_CAD_RX; + + if( bw == BW500 ) + { + param->cad_symb_nb = ( sf == RAL_LORA_SF12 ) ? RAL_LORA_CAD_08_SYMB : RAL_LORA_CAD_04_SYMB; + } + else if( bw == BW250 ) + { + param->cad_symb_nb = ( sf <= RAL_LORA_SF8 ) ? RAL_LORA_CAD_08_SYMB : RAL_LORA_CAD_04_SYMB; + } + else if( bw == BW125 ) + { + param->cad_symb_nb = ( sf <= RAL_LORA_SF8 ) ? RAL_LORA_CAD_02_SYMB : RAL_LORA_CAD_04_SYMB; + } + } +} + +void wor_ral_init_rx_msg( smtc_real_t* real, uint8_t max_payload, uint8_t dr, uint32_t freq_hz, + rp_radio_params_t* param ) +{ + modulation_type_t modulation_type = smtc_real_get_modulation_type_from_datarate( real, dr ); + if( modulation_type == LORA ) + { + uint8_t sf; + lr1mac_bandwidth_t bw; + ralf_params_lora_t* lora = ¶m->rx.lora; + + smtc_real_lora_dr_to_sf_bw( real, dr, &sf, &bw ); + + const uint32_t symb_time_us = + lr1mac_utilities_get_symb_time_us( 1, ( ral_lora_sf_t ) sf, ( ral_lora_bw_t ) bw ); + + lora->sync_word = smtc_real_get_sync_word( real ); + lora->symb_nb_timeout = 10 + 1000 * smtc_modem_hal_get_radio_tcxo_startup_delay_ms( ) / symb_time_us; + lora->rf_freq_in_hz = freq_hz; + + lora->pkt_params.pld_len_in_bytes = max_payload; + lora->mod_params.cr = smtc_real_get_coding_rate( real ); + lora->mod_params.sf = ( ral_lora_sf_t ) sf; + lora->mod_params.bw = ( ral_lora_bw_t ) bw; + lora->mod_params.ldro = ral_compute_lora_ldro( lora->mod_params.sf, lora->mod_params.bw ); + + lora->pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; + lora->pkt_params.crc_is_on = true; + lora->pkt_params.invert_iq_is_on = false; + lora->pkt_params.preamble_len_in_symb = smtc_real_get_preamble_len( real, lora->mod_params.sf ); + + param->pkt_type = RAL_PKT_TYPE_LORA; + } + else if( modulation_type == FSK ) + { + ralf_params_gfsk_t* gfsk = ¶m->rx.gfsk; + uint8_t tx_bitrate; + smtc_real_fsk_dr_to_bitrate( real, dr, &tx_bitrate ); + + gfsk->sync_word = smtc_real_get_gfsk_sync_word( real ); + gfsk->crc_seed = GFSK_CRC_SEED; + gfsk->crc_polynomial = GFSK_CRC_POLYNOMIAL; + gfsk->rf_freq_in_hz = freq_hz; + + gfsk->pkt_params.pld_len_in_bytes = 255; + gfsk->pkt_params.header_type = RAL_GFSK_PKT_VAR_LEN; + gfsk->pkt_params.preamble_len_in_bits = 40; + gfsk->pkt_params.sync_word_len_in_bits = 24; + gfsk->pkt_params.dc_free = RAL_GFSK_DC_FREE_WHITENING; + gfsk->pkt_params.crc_type = RAL_GFSK_CRC_2_BYTES_INV; + + gfsk->mod_params.fdev_in_hz = 25000; + gfsk->mod_params.bw_dsb_in_hz = 100000; + gfsk->mod_params.pulse_shape = RAL_GFSK_PULSE_SHAPE_BT_1; + gfsk->mod_params.br_in_bps = tx_bitrate * 1000; + + param->pkt_type = RAL_PKT_TYPE_GFSK; + } + else + { + SMTC_MODEM_HAL_PANIC( "MODULATION NOT SUPPORTED\n" ); + } +} +void wor_ral_callback_start_cad( void* rp_void ) +{ + radio_planner_t* rp = ( radio_planner_t* ) rp_void; + const uint8_t id = rp->radio_task_id; + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ralf_setup_lora( rp->radio, &rp->radio_params[id].rx.lora ) == RAL_STATUS_OK ); + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + ral_set_dio_irq_params( &( rp->radio->ral ), RAL_IRQ_CAD_DONE | RAL_IRQ_CAD_OK | RAL_IRQ_RX_DONE | + RAL_IRQ_RX_TIMEOUT | RAL_IRQ_RX_HDR_ERROR | + RAL_IRQ_RX_CRC_ERROR ) == RAL_STATUS_OK ); + + ral_set_lora_cad_params( &( rp->radio->ral ), &rp->radio_params[id].rx.cad ); + + // Wait the exact time + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + { + } + // At this time only tcxo startup delay is remaining + smtc_modem_hal_start_radio_tcxo( ); + smtc_modem_hal_set_ant_switch( false ); + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_lora_cad( &( rp->radio->ral ) ) == RAL_STATUS_OK ); + rp_stats_set_rx_timestamp( &rp->stats, smtc_modem_hal_get_time_in_ms( ) ); +} diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.h b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.h index 5bad570..274c866 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/common/wake_on_radio_ral.h @@ -47,6 +47,8 @@ extern "C" { #include "radio_planner_types.h" #include "ral_defs.h" #include "smtc_real_defs.h" +#include "wake_on_radio.h" + /* * ----------------------------------------------------------------------------- @@ -129,6 +131,70 @@ void wor_ral_init_tx_ack( smtc_real_t* real, uint8_t dr, uint32_t freq_hz, uint8 */ bool wor_schedule_rx_wor_ack( uint8_t hook_id, radio_planner_t* rp, wor_ack_rx_param_t* wor_ack_param ); +/** + * @brief Fill rp_radio_params_t struct for RX WOR frame + * + * @param[in] real Regional Abstraction Layer object + * @param[in] dr Datarate of the WOR + * @param[in] freq_hz Frequency of the WOR + * @param[in] preamble_len_symb Preamble len + * @param[in] payload_len Payload len of the WOR + * @param[out] param Radio parameter structure with WOR infos + */ +void wor_ral_init_rx_wor( smtc_real_t* real, uint8_t dr, uint32_t freq_hz, wor_cad_periodicity_t cad_period, + uint8_t max_payload, rp_radio_params_t* param ); + + +/** + * @brief Fill rp_radio_params_t struct for TX WOR frame + * + * @param[in] real Regional Abstraction Layer object + * @param[in] dr Datarate of the WOR + * @param[in] freq_hz Frequency of the WOR + * @param[in] preamble_len_symb Preamble len + * @param[in] payload_len Payload len of the WOR + * @param[out] param Radio parameter structure with WOR infos + */ +void wor_ral_init_tx_wor( smtc_real_t* real, uint8_t dr, uint32_t freq_hz, uint16_t preamble_len_symb, + uint8_t payload_len, rp_radio_params_t* param ); + +/** + * @brief Function called by RP to send WOR and WOR ACK + * + * @param rp_void radio planner pointer + */ +void wor_ral_callback_start_tx( void* rp_void ); + +/** + * @brief Function called by RP to receive WOR, WOR ACK and LoRaWAN uplink + * + * @param rp_void + */ +void wor_ral_callback_start_rx( void* rp_void ); +/** + * @brief Fill rp_radio_params_t struct to received LoRaWAN Uplink after a WOR + * + * @param[in] real Regional Abstraction Layer object + * @param[in] max_payload Maximum payload to be received + * @param[in] dr Datarate of the uplink + * @param[in] freq_hz Frequency of the uplink + * @param[out] param Radio parameter structure with LoRaWAN Uplink + */ +void wor_ral_init_rx_msg( smtc_real_t* real, uint8_t max_payload, uint8_t dr, uint32_t freq_hz, + rp_radio_params_t* param ); + +/** + * @brief Fill rp_radio_params_t struct for periodic CAD + * + * @param[in] lr1_mac Lr1mac object + * @param[in] dr Datarate of the CAD + * @param[in] cad_period Period between 2 CAD + * @param[in] is_first true for the first single CAD, False for the second 4th symbols + * @param[in] wor_toa_ms TOA of the WOR to be received + * @param[out] param Radio parameter structure with CAD infos + */ +void wor_ral_init_cad( smtc_real_t* lr1_mac, uint8_t dr, wor_cad_periodicity_t cad_period, bool is_first, + uint32_t wor_toa_ms, ral_lora_cad_params_t* param ); #ifdef _cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx.c b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx.c new file mode 100755 index 0000000..69aa826 --- /dev/null +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx.c @@ -0,0 +1,1643 @@ +/*! + * \file relay_rx.c + * + * \brief Main function to interact with the relay RX (start,stop, configure,...) + * + * The Clear BSD License + * Copyright Semtech Corporation 2023. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + *----------------------------------------------------------------------------------- + * --- DEPENDENCIES ----------------------------------------------------------------- + */ +#include "relay_rx_api.h" +#include "relay_real.h" +#include "relay_def.h" +#include "wake_on_radio.h" +#include "wake_on_radio_def.h" +#include "wake_on_radio_ral.h" +#include "radio_planner.h" +#include "lorawan_api.h" +#include "lr1mac_utilities.h" +#include "smtc_modem_hal_dbg_trace.h" +#include "modem_core.h" +#include "lorawan_relay_rx_service.h" +#include "relay_mac_parser.h" +#include "smtc_duty_cycle.h" +#include "smtc_real.h" +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS ---------------------------------------------------------- + */ +#define ROOT_WOR_SKEY_LEN ( 16 ) +#define JOINREQ_EUI_LEN ( 16 ) +#define SIZE_TAB_DEV_ADDR_LIST ( 16 ) +#define SIZE_TAB_JOIN_REQ_LIST ( 16 ) +#define MAX_UINT16 ( 0x0000FFFF ) + +#define RELAY_FWD_UPLINK_SET_METADATA_WOR_CH( a ) ( ( uint32_t ) ( ( ( a ) & 0x0003 ) << 16 ) ) +#define RELAY_FWD_UPLINK_SET_METADATA_UPLINK_RSSI( a ) ( ( uint32_t ) ( ( ( a ) & 0x007F ) << 9 ) ) +#define RELAY_FWD_UPLINK_SET_METADATA_UPLINK_SNR( a ) ( ( uint32_t ) ( ( ( a ) & 0x001F ) << 4 ) ) +#define RELAY_FWD_UPLINK_SET_METADATA_UPLINK_DR( a ) ( ( uint32_t ) ( ( a ) & 0x000F ) ) + +#define RELAY_NOTIFY_POWER_LEVEL_UPLINK_RSSI( a ) ( ( uint16_t ) ( ( ( a ) & 0x7F ) << 5 ) ) +#define RELAY_NOTIFY_POWER_LEVEL_UPLINK_SNR( a ) ( ( uint16_t ) ( ( a ) & 0x001F ) ) + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ +typedef enum relay_fwd_uplink_byte_order_e +{ + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_METADATA_7_0, + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_METADATA_15_8, + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_METADATA_23_16, + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_FREQUENCY_7_0, + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_FREQUENCY_15_8, + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_FREQUENCY_23_16, + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_PAYLOAD, // First index of the payload +} relay_fwd_uplink_byte_order_t; + +typedef enum relay_notify_byte_order_e +{ + RELAY_NOTIFY_BYTE_CID_REQ, + RELAY_NOTIFY_BYTE_ORDER_DEV_ADDR_7_0, + RELAY_NOTIFY_BYTE_ORDER_DEV_ADDR_15_8, + RELAY_NOTIFY_BYTE_ORDER_DEV_ADDR_23_16, + RELAY_NOTIFY_BYTE_ORDER_DEV_ADDR_31_24, + RELAY_NOTIFY_BYTE_ORDER_POWER_LEVEL_7_0, + RELAY_NOTIFY_BYTE_ORDER_POWER_LEVEL_15_8, + RELAY_NOTIFY_BYTE_ORDER_POWER_LEVEL_LENGTH, // Not an element +} relay_notify_byte_order_t; + +typedef enum cad_state_e +{ + CAD_STATE_NO_CFG, + CAD_STATE_INIT, + CAD_STATE_ENQUEUE_CAD, + CAD_STATE_WAIT_CAD_COMPLETION, + CAD_STATE_WAIT_WOR_COMPLETION, + CAD_STATE_WAIT_TX_ACK_COMPLETION, + CAD_STATE_WAIT_RX_DATA_COMPLETION, +} cad_state_t; + +typedef struct relay_fwd_uplink_list_s +{ + bool in_use; + uint32_t dev_addr; + uint32_t wfcnt32; + uint8_t wor_s_int_key[ROOT_WOR_SKEY_LEN]; + uint8_t wor_s_enc_key[ROOT_WOR_SKEY_LEN]; + relay_fwd_config_t fwd_cfg; +} relay_fwd_uplink_list_t; + +typedef struct relay_fwd_join_list_s +{ + relay_filter_fwd_type_t action; + // Concatenation of JOIN EUI + DEV EUI : MSB(JOIN EUI) ... LSB(JOIN EUI) - MSB(DEV EUI) ... LSB(DEV EUI) + uint8_t eui[JOINREQ_EUI_LEN]; + uint8_t len; // Len of eui (len(JOIN EUI) + len(DEV EUI)) +} relay_fwd_join_list_t; + +typedef struct relay_infos_s +{ + lr1_stack_mac_t* lr1mac; + const ralf_t* radio; + bool is_started_by_network; + bool is_started; + cad_state_t state; + ral_lora_rx_pkt_status_t rx_status; + smtc_dtc_enablement_type_t dtc_state; + + uint32_t last_cad_ms; + uint32_t next_cad_ms; + uint32_t rx_wor_timestamp_ms; + uint32_t rx_uplink_timestamp_ms; + uint32_t tx_ack_timestamp_ms; + uint32_t wor_toa_ms[MAX_WOR_CH]; + uint32_t wor_preamble_ms[MAX_WOR_CH]; + int16_t t_irq_comp_wor_ms[MAX_WOR_CH]; + + uint16_t buffer_length; + uint8_t buffer[255]; // Uplink and downlink buffer + + const relay_channel_config_t* current_cfg; + uint8_t rx_msg_devaddr_idx; + uint8_t current_ch_idx; + uint16_t t_offset; + wor_ack_cad_to_rx_t cad_to_rx; + wor_ack_ppm_error_t error_ppm; +} relay_infos_t; + +/* + *----------------------------------------------------------------------------------- + *--- PRIVATE VARIABLES ------------------------------------------------------------- + */ +static relay_config_t relay_config = { 0 }; +static relay_fwd_config_t relay_fwd_cnt[LIMIT__LAST_ELT] = { 0 }; +static relay_fwd_join_list_t device_list_join[SIZE_TAB_JOIN_REQ_LIST] = { 0 }; +static relay_fwd_uplink_list_t device_list_dev_addr[SIZE_TAB_DEV_ADDR_LIST] = { 0 }; +static relay_infos_t relay_info = { 0 }; +static relay_stats_t relay_stat = { 0 }; +static wor_infos_t relay_wor_info = { 0 }; + +/* + *----------------------------------------------------------------------------------- + *--- PRIVATE FUNCTIONS DECLARATION ------------------------------------------------- + */ + +/** + * @brief Relay callback called by radio planner to manage CAD, WOR, WOR ACK and RX Uplink + * + * @param[in] context No used (NULL) + */ +static void callback_relay( void* context ); + +/** + * @brief Relay callback to manage downlink on RXR + * + * @param[in] context No used (NULL) + */ +static void callback_relay_fwd( void* context ); + +/** + * @brief Main relay FSM + * + * @param[in] irq_timestamp_ms Current time in ms + * @param[in] cad_success True if CAD is positive + * @param[in] rx_success True if a packet has been received + */ +static void manage_fsm( const uint32_t irq_timestamp_ms, const bool cad_success, const bool rx_success ); + +/** + * @brief Enqueue the next CAD + * + * @param[in] config Relay configuration + * @param[in] info Relay status + */ +static void config_enqueue_next_cad( const relay_config_t* config, relay_infos_t* info ); + +/** + * @brief Configure the radio to perform a CAD follow by reception + * + * @param[in] config Relay configuration + * @param[in] info Relay status + */ +static void config_cad_to_rx_wor( const relay_config_t* config, relay_infos_t* info ); + +/** + * @brief Program the reception of the LoRaWAN Uplink + * + * @param[in] config Relay configuration + * @param[in] wor Infos from the WOR + * @param[in] timestamp_wor Timestamp when WOR has been received + */ +static void config_enqueue_rx_msg( const relay_config_t* config, const wor_infos_t* wor, + const uint32_t timestamp_lr1_ul ); + +/** + * @brief Program the emission of the WOR ACK + * + * @param[in] config Relay configuration + * @param[in] wor WOR infos + * @param[in] time_rx Timestamp to send the WOR ACK + * @param[in,out] info Relay info + * @param[in] devaddr_idx ED Dev ADDR + */ +static void config_enqueue_ack( const relay_config_t* config, const wor_infos_t* wor, const uint32_t time_rx, + relay_infos_t* info, const uint8_t devaddr_idx ); + +/** + * @brief Compute the difference between the IRQ TX Done on the ED and RX Done on the relay + * + * @param[in] datarate Datarate of the message + * @param[in] payload_len Length of the messages + * @return int16_t Difference in µS + */ +static int16_t relay_compute_rx_done_correction( uint8_t datarate, uint16_t payload_len ); + +/** + * @brief Check if received MIC is valid + * + * @param[in] wor WOR infos + * @param[in] mic_receive MIC received + * @param[out] device_idx If MIC is valid, contain the index in the trusted tables + * @return true MIC is valid (device_idx has a value between 0 and 15) + * @return false MIC is invalid (device_idx is set to 16) + */ +static bool is_mic_wor_valid( const wor_infos_t* wor, uint32_t mic_receive, uint8_t* device_idx ); + +/** + * @brief Check if the relay is authorized to forward a new message + * + * @param[in] wor WOR infos + * @param[in] device_idx ED index in the trusted table + * @return true Relay is allow to forward + * @return false Relay is NOT allow to forward + */ +static bool check_fwd_limitation( const wor_infos_t* wor, uint8_t device_idx ); + +/** + * @brief Check if the relay could forward this Join Request + * + * @param[in] deveui ED Dev EUI + * @param[in] joineui ED Join EUI + * @return true Relay is allow to forward + * @return false Relay is NOT allow to forward + */ +static bool check_forward_filter_joinreq( const uint8_t joineui[8], const uint8_t deveui[8] ); + +/** + * @brief Get the datarate of the LoRaWAN uplink + * + * @param[in] wor WOR infos + * @return uint8_t Datarate value + */ +static uint8_t get_ul_dr( const wor_infos_t* wor ); + +/** + * @brief Get the frequency of the LoRaWAN uplink + * + * @param[in] wor WOR infos + * @return uint8_t frequency value + */ +static uint32_t get_ul_freq( const wor_infos_t* wor ); + +/** + * @brief Decrement the forward limit counter + * + * @param[in] limit_counter Limit counter + */ +static void decrement_fwd_counter( relay_fwd_config_t* limit_counter ); + +/** + * @brief Relay has received an WOR Uplink and is not able to valid the MIC + * + * @param[in] wor WOR infos + */ +static void notify_unknown_ed( const wor_infos_t* wor ); + +/** + * @brief Relay has received a LoRaWAN Uplink and need to send it + * + * @param[in] wor Wor infos + * @param[in] config Relay config + * @param[in] info Relay status + */ +static void fwd_rx_msg( const wor_infos_t* wor, const relay_config_t* config, const relay_infos_t* info ); + +/** + * @brief Relay Callback to send downlink on RXR + * + * @param[in] rp_void Radio planner pointer + */ +static void relay_rxr_tx_launch_callback( void* rp_void ); + +/* + *----------------------------------------------------------------------------------- + *--- PUBLIC FUNCTIONS DEFINITIONS -------------------------------------------------- + */ + +bool relay_init( lr1_stack_mac_t* lr1mac, wor_ack_ppm_error_t error_ppm, wor_ack_cad_to_rx_t cad_to_rx ) +{ + if( rp_hook_init( lr1mac->rp, RP_HOOK_ID_RELAY_RX_CAD, callback_relay, NULL ) != RP_HOOK_STATUS_OK ) + { + return false; + } + + if( rp_hook_init( lr1mac->rp, RP_HOOK_ID_RELAY_FORWARD_RXR, callback_relay_fwd, NULL ) != RP_HOOK_STATUS_OK ) + { + return false; + } + + // Clear credential in forwarding list + for( uint32_t i = 0; i < SIZE_TAB_DEV_ADDR_LIST; i++ ) + { + device_list_dev_addr[i].in_use = false; + } + + // Clean rules for join request forward + device_list_join[0].action = RELAY_FILTER_FWD_TYPE_FORWARD; // default is forward + for( uint32_t i = 1; i < SIZE_TAB_JOIN_REQ_LIST; i++ ) + { + device_list_join[i].action = RELAY_FILTER_FWD_TYPE_CLEAR; + } + + relay_info.lr1mac = lr1mac; + relay_info.radio = lr1mac->rp->radio; + relay_info.error_ppm = error_ppm; + relay_info.cad_to_rx = cad_to_rx; + relay_info.state = CAD_STATE_NO_CFG; + + relay_info.is_started_by_network = false; + + // Set fwd limit with recommanded value in specification + relay_fwd_cnt[LIMIT_OVERALL].reload_rate = 8; + relay_fwd_cnt[LIMIT_GLOBAL_UPLINK].reload_rate = 8; + relay_fwd_cnt[LIMIT_NOTIFY].reload_rate = 4; + relay_fwd_cnt[LIMIT_JOINREQ].reload_rate = 4; + + for( uint8_t i = 0; i < LIMIT__LAST_ELT; i++ ) + { + relay_fwd_cnt[i].token_available = relay_fwd_cnt[i].reload_rate; + relay_fwd_cnt[i].bucket_size = relay_fwd_cnt[i].reload_rate * 2; // Default bucket size is x2 reload rate + relay_fwd_cnt[i].unlimited_fwd = false; + } + + return true; +} + +bool relay_stop( bool stop_to_fwd ) +{ + if( rp_task_abort( relay_info.lr1mac->rp, RP_HOOK_ID_RELAY_RX_CAD ) != RP_HOOK_STATUS_OK ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Failed to abort RP CAD \n" ); + return false; + } + + if( rp_task_abort( relay_info.lr1mac->rp, RP_HOOK_ID_RELAY_FORWARD_RXR ) != RP_HOOK_STATUS_OK ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Failed to abort RP FWD RXR\n" ); + return false; + } + + if( relay_info.state != CAD_STATE_NO_CFG ) + { + relay_info.state = CAD_STATE_INIT; + } + SMTC_MODEM_HAL_TRACE_PRINTF( "Stop relay CAD\n" ); + relay_info.is_started = false; + + if( stop_to_fwd == true ) + { + relay_info.dtc_state = smtc_duty_cycle_enable_get( ); + + if( relay_info.dtc_state != SMTC_DTC_FULL_DISABLED ) + { + smtc_duty_cycle_enable_set( SMTC_DTC_PARTIAL_DISABLED ); + } + } + + return true; +} + +bool relay_start( void ) +{ + if( ( relay_info.state != CAD_STATE_INIT ) && ( relay_info.state != CAD_STATE_ENQUEUE_CAD ) ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Start CAD status (%d)\n", relay_info.state ); + relay_stop( true ); + } + + const smtc_dtc_enablement_type_t dtc_state = smtc_duty_cycle_enable_get( ); + if( dtc_state == SMTC_DTC_PARTIAL_DISABLED ) + { + smtc_duty_cycle_enable_set( relay_info.dtc_state ); + } + + relay_info.current_ch_idx = relay_config.nb_wor_channel; // to force to start at index 0 + relay_info.is_started = true; + + config_enqueue_next_cad( &relay_config, &relay_info ); + +#if MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON + const relay_channel_config_t* ch_cfg = &relay_config.channel_cfg[relay_info.current_ch_idx]; + + SMTC_MODEM_HAL_TRACE_PRINTF( "Start CAD at %d ms every %d ms at DR%d %d Hz\n", relay_info.next_cad_ms, + wor_convert_cad_period_in_ms( relay_config.cad_period ), ch_cfg->dr, ch_cfg->freq_hz ); +#endif + + return true; +} + +void relay_rx_set_flag_started( bool relay_rx_start ) +{ + relay_info.is_started_by_network = relay_rx_start; +} + +bool relay_rx_get_flag_started( void ) +{ + return relay_info.is_started_by_network; +} + +void relay_fwd_dl( uint8_t stack_id, const uint8_t* buffer, uint8_t len ) +{ + memcpy( relay_info.buffer, buffer, len ); + relay_info.buffer_length = len; + + smtc_real_t* real = relay_info.lr1mac->real; + + // Downlink on RXR use same frequency as WOR frame and same DR as LoRaWAN uplink + const uint8_t ul_dr = get_ul_dr( &relay_wor_info ); + const uint8_t dl_dr = smtc_real_get_rx1_datarate_config( real, ul_dr, 0 ); + const uint32_t dl_freq = relay_config.channel_cfg[relay_info.current_ch_idx].freq_hz; + smtc_duty_cycle_update( ); + if( smtc_duty_cycle_is_channel_free( dl_freq ) == false ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "no more duty cycle to forward downlink on RxR\n" ); + relay_start( ); + } + // Downlink could be LORA or FSK + const modulation_type_t modulation_type = smtc_real_get_modulation_type_from_datarate( real, dl_dr ); + rp_radio_params_t radio_params = { 0 }; + + rp_task_t rp_task = { + .start_time_ms = relay_info.rx_uplink_timestamp_ms + RXR_WINDOWS_DELAY_S * 1000 - + smtc_modem_hal_get_radio_tcxo_startup_delay_ms( ), + .hook_id = RP_HOOK_ID_RELAY_FORWARD_RXR, + .state = RP_TASK_STATE_SCHEDULE, + .launch_task_callbacks = relay_rxr_tx_launch_callback, + + }; + + if( modulation_type == LORA ) + { + uint8_t sf; + lr1mac_bandwidth_t bw; + ralf_params_lora_t* lora_param = &radio_params.tx.lora; + + smtc_real_lora_dr_to_sf_bw( real, dl_dr, &sf, &bw ); + + lora_param->rf_freq_in_hz = dl_freq; + lora_param->sync_word = smtc_real_get_sync_word( real ); + lora_param->output_pwr_in_dbm = smtc_real_clamp_output_power_eirp_vs_freq_and_dr( + real, smtc_real_get_default_max_eirp( real ), lora_param->rf_freq_in_hz, dl_dr ); + + lora_param->mod_params.sf = ( ral_lora_sf_t ) sf; + lora_param->mod_params.bw = ( ral_lora_bw_t ) bw; + lora_param->mod_params.cr = RAL_LORA_CR_4_5; + lora_param->mod_params.ldro = ral_compute_lora_ldro( lora_param->mod_params.sf, lora_param->mod_params.bw ); + + lora_param->pkt_params.preamble_len_in_symb = 8; + lora_param->pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; + lora_param->pkt_params.pld_len_in_bytes = len; + lora_param->pkt_params.crc_is_on = true; + lora_param->pkt_params.invert_iq_is_on = true; + + radio_params.pkt_type = RAL_PKT_TYPE_LORA; + + rp_task.type = RP_TASK_TYPE_TX_LORA; + rp_task.duration_time_ms = + ral_get_lora_time_on_air_in_ms( &relay_info.radio->ral, &lora_param->pkt_params, &lora_param->mod_params ); + + SMTC_MODEM_HAL_TRACE_PRINTF( "LORA Tx on RXR %d bytes at DR%d %d Hz - toa %d\n", len, dl_dr, + radio_params.tx.lora.rf_freq_in_hz, rp_task.duration_time_ms ); + } + else if( modulation_type == FSK ) + { + uint8_t kbitrate; + smtc_real_fsk_dr_to_bitrate( real, dl_dr, &kbitrate ); + + ralf_params_gfsk_t* gfsk_param = &radio_params.tx.gfsk; + + gfsk_param->whitening_seed = GFSK_WHITENING_SEED; + gfsk_param->crc_seed = GFSK_CRC_SEED; + gfsk_param->crc_polynomial = GFSK_CRC_POLYNOMIAL; + gfsk_param->rf_freq_in_hz = relay_config.channel_cfg[relay_info.current_ch_idx].freq_hz; + gfsk_param->sync_word = smtc_real_get_gfsk_sync_word( real ); + gfsk_param->output_pwr_in_dbm = smtc_real_clamp_output_power_eirp_vs_freq_and_dr( + real, smtc_real_get_default_max_eirp( real ), gfsk_param->rf_freq_in_hz, dl_dr ); + + gfsk_param->pkt_params.header_type = RAL_GFSK_PKT_VAR_LEN; + gfsk_param->pkt_params.pld_len_in_bytes = len; + gfsk_param->pkt_params.preamble_len_in_bits = 40; + gfsk_param->pkt_params.sync_word_len_in_bits = 24; + gfsk_param->pkt_params.dc_free = RAL_GFSK_DC_FREE_WHITENING; + gfsk_param->pkt_params.crc_type = RAL_GFSK_CRC_2_BYTES_INV; + + gfsk_param->mod_params.fdev_in_hz = 25000; + gfsk_param->mod_params.bw_dsb_in_hz = 100000; + gfsk_param->mod_params.pulse_shape = RAL_GFSK_PULSE_SHAPE_BT_1; + gfsk_param->mod_params.br_in_bps = kbitrate * 1000; + + radio_params.pkt_type = RAL_PKT_TYPE_GFSK; + + rp_task.type = RP_TASK_TYPE_TX_FSK; + rp_task.duration_time_ms = + ral_get_gfsk_time_on_air_in_ms( &relay_info.radio->ral, &gfsk_param->pkt_params, &gfsk_param->mod_params ); + + SMTC_MODEM_HAL_TRACE_PRINTF( "FSK Tx on RXR %d kbit at %d Hz - toa %d\n", kbitrate, + radio_params.tx.lora.rf_freq_in_hz, rp_task.duration_time_ms ); + } + else + { + SMTC_MODEM_HAL_PANIC( "MODULATION NOT SUPPORTED\n" ); + } + + if( rp_task_enqueue( relay_info.lr1mac->rp, &rp_task, relay_info.buffer, relay_info.buffer_length, + &radio_params ) != RP_HOOK_STATUS_OK ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "RP is busy,fail in relay_fwd_dl\n" ); + relay_start( ); + } +} + +bool relay_update_config( const relay_config_t* config ) +{ + if( config == NULL ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "relay config null pointer\n" ); + return false; + } + if( config->cad_period >= WOR_CAD_PERIOD_RFU ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Wrong cad_period\n" ); + return false; + } + if( config->nb_wor_channel > MAX_WOR_CH ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Wrong nb_wor_channel (too high)\n" ); + return false; + } + if( config->nb_wor_channel == 0 ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Wrong nb_wor_channel (too low)\n" ); + return false; + } + + for( uint8_t i = 0; i < config->nb_wor_channel; i++ ) + { + if( smtc_real_get_modulation_type_from_datarate( relay_info.lr1mac->real, config->channel_cfg[i].dr ) != LORA ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Invalid dr (%d) on ch %d\n", config->channel_cfg[i].dr, i ); + return false; + } + if( smtc_real_is_frequency_valid( relay_info.lr1mac->real, config->channel_cfg[i].freq_hz ) != OKLORAWAN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Invalid freq wor %d on ch %d\n", config->channel_cfg[i].freq_hz, i ); + return false; + } + if( smtc_real_is_frequency_valid( relay_info.lr1mac->real, config->channel_cfg[i].ack_freq_hz ) != OKLORAWAN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Invalid freq wor ack %d on ch %d\n", config->channel_cfg[i].ack_freq_hz, i ); + return false; + } + } + + // Memorize if relay is running to restart it (or not) at the end + // bool relay_is_running = false; + // if( relay_info.state > CAD_STATE_INIT ) + // { + // relay_stop( false ); + // relay_is_running = true; + // } + + // All parameters are valid -> save config + relay_config = *config; + + // Compute TOA of WOR and IRQ timing compensation + rp_radio_params_t param; + for( uint8_t i = 0; i < config->nb_wor_channel; i++ ) + { + wor_ral_init_tx_wor( relay_info.lr1mac->real, relay_config.channel_cfg[i].dr, + relay_config.channel_cfg[i].freq_hz, 0, WOR_UPLINK_LENGTH, ¶m ); + // Use WOR_UPLINK_LENGTH because WOR ACK is only send to uplink and there is almost no difference in t irq + // compensation between a join and an uplink + + relay_info.t_irq_comp_wor_ms[i] = + relay_compute_rx_done_correction( relay_config.channel_cfg[i].dr, WOR_UPLINK_LENGTH ) / 1000; + + relay_info.wor_toa_ms[i] = ral_get_lora_time_on_air_in_ms( &relay_info.radio->ral, ¶m.tx.lora.pkt_params, + ¶m.tx.lora.mod_params ); + } + + if( relay_info.state == CAD_STATE_NO_CFG ) + { + relay_info.state = CAD_STATE_INIT; + } + + return true; +} + +void relay_fwd_join_request_update_rule( const uint8_t idx, const uint8_t* join_eui, const uint8_t len_join_eui, + const uint8_t* dev_eui, const uint8_t len_dev_eui, + const relay_filter_fwd_type_t action ) +{ + // Rules are checked in parser + if( ( idx < SIZE_TAB_JOIN_REQ_LIST ) && ( len_join_eui <= 8 ) && ( len_dev_eui <= 8 ) ) + { + memcpy( device_list_join[idx].eui, join_eui, len_join_eui ); + memcpy( device_list_join[idx].eui + len_join_eui, dev_eui, len_dev_eui ); + device_list_join[idx].len = len_join_eui + len_dev_eui; + device_list_join[idx].action = action; + } +} + +bool relay_fwd_uplink_add_device( const uint8_t idx, const uint32_t dev_addr, const uint8_t* root_wor_skey, + const bool unlimited_fwd, const uint8_t bucket_factor, const uint8_t reload_rate, + const uint32_t wfcnt32 ) +{ + if( idx >= SIZE_TAB_DEV_ADDR_LIST ) + { + return false; + } + + relay_fwd_uplink_list_t* device = &device_list_dev_addr[idx]; + + wor_derive_keys( root_wor_skey, dev_addr, device->wor_s_int_key, device->wor_s_enc_key ); + + device->dev_addr = dev_addr; + device->wfcnt32 = wfcnt32; + device->in_use = true; + + device->fwd_cfg.unlimited_fwd = unlimited_fwd; + device->fwd_cfg.reload_rate = reload_rate; + device->fwd_cfg.bucket_size = bucket_factor * reload_rate; + device->fwd_cfg.token_available = bucket_factor * reload_rate; + + return true; +} + +bool relay_fwd_uplink_remove_device( const uint8_t idx ) +{ + if( ( idx < SIZE_TAB_DEV_ADDR_LIST ) && ( device_list_dev_addr[idx].in_use == true ) ) + { + device_list_dev_addr[idx].in_use = false; + return true; + } + + return false; +} + +bool relay_fwd_uplink_read_wfcnt32( const uint8_t idx, uint32_t* wfcnt32 ) +{ + if( ( idx < SIZE_TAB_DEV_ADDR_LIST ) && ( device_list_dev_addr[idx].in_use == true ) ) + { + if( wfcnt32 != NULL ) + { + *wfcnt32 = device_list_dev_addr[idx].wfcnt32; + } + return true; + } + + return false; +} + +void relay_get_stats( relay_stats_t* stat ) +{ + if( stat != NULL ) + { + *stat = relay_stat; + } +} + +void relay_print_stats( void ) +{ + SMTC_MODEM_HAL_TRACE_PRINTF( "------------------------\nRelay stat at %d s\n------------------------\n", + smtc_modem_hal_get_time_in_s( ) ); + SMTC_MODEM_HAL_TRACE_PRINTF( " - Cad1 %d \n", relay_stat.nb_cad1 ); + SMTC_MODEM_HAL_TRACE_PRINTF( " - Cad2 %d \n", relay_stat.nb_cad2 ); + SMTC_MODEM_HAL_TRACE_PRINTF( " - Cad2 OK %d \n", relay_stat.nb_cad2_ok ); + SMTC_MODEM_HAL_TRACE_PRINTF( " - WOR fail %d \n", relay_stat.nb_wor_fail ); + SMTC_MODEM_HAL_TRACE_PRINTF( " - WOR ok %d \n", relay_stat.nb_wor_ok ); + SMTC_MODEM_HAL_TRACE_PRINTF( " - Rx_ok %d \n", relay_stat.nb_rx_ok ); + SMTC_MODEM_HAL_TRACE_PRINTF( " - Rx_fail %d \n", relay_stat.nb_rx_fail ); + SMTC_MODEM_HAL_TRACE_PRINTF( " - Ack_tx %d \n", relay_stat.nb_ack_tx ); +} + +void relay_fwd_update_fwd_limit( const relay_forward_limit_list_t limit, const relay_forward_limit_action_t action, + const bool unlimited, const uint16_t reload_rate, const uint8_t factor ) +{ + if( limit < LIMIT__LAST_ELT ) + { + relay_fwd_cnt[limit].unlimited_fwd = unlimited; + relay_fwd_cnt[limit].reload_rate = reload_rate; + relay_fwd_cnt[limit].bucket_size = reload_rate * factor; + + switch( action ) + { + case LIMIT_CNT_SET_TO_0: + relay_fwd_cnt[limit].token_available = 0; + break; + case LIMIT_CNT_SET_TO_RELOAD_RATE: + relay_fwd_cnt[limit].token_available = reload_rate; + break; + case LIMIT_CNT_SET_TO_MAX_VAL: + relay_fwd_cnt[limit].token_available = reload_rate * factor; + break; + default: + case LIMIT_CNT_DONT_CHANGE: + break; + } + } +} + +/* + *----------------------------------------------------------------------------------- + *--- PRIVATE FUNCTIONS DEFINITIONS ------------------------------------------------- + */ +static void callback_relay_fwd( void* context ) +{ + uint32_t irq_timestamp_ms; + rp_status_t planner_status; + + rp_get_status( relay_info.lr1mac->rp, RP_HOOK_ID_RELAY_FORWARD_RXR, &irq_timestamp_ms, &planner_status ); + + switch( planner_status ) + { + case RP_STATUS_TX_DONE: + SMTC_MODEM_HAL_TRACE_PRINTF( "TX DONE on RXR\n" ); + break; + + case RP_STATUS_TASK_ABORTED: + SMTC_MODEM_HAL_TRACE_WARNING( "Fwd Task aborted\n" ); + break; + + default: + SMTC_MODEM_HAL_TRACE_WARNING( "callback_relay_fwd default switch: 0x%x\n", planner_status ); + break; + } + relay_start( ); +} + +static void callback_relay( void* context ) +{ + uint32_t irq_timestamp_ms; + rp_status_t planner_status; + bool cad_success = false; + bool rx_success = false; + + rp_get_status( relay_info.lr1mac->rp, RP_HOOK_ID_RELAY_RX_CAD, &irq_timestamp_ms, &planner_status ); + + switch( planner_status ) + { + case RP_STATUS_CAD_POSITIVE: + cad_success = true; + break; + + case RP_STATUS_RX_PACKET: + { + uint8_t sf; + lr1mac_bandwidth_t bw; + const relay_channel_config_t* channel_cfg = &relay_config.channel_cfg[relay_info.current_ch_idx]; + smtc_real_lora_dr_to_sf_bw( relay_info.lr1mac->real, channel_cfg->dr, &sf, &bw ); + + rx_success = true; + relay_info.buffer_length = relay_info.lr1mac->rp->rx_payload_size[RP_HOOK_ID_RELAY_RX_CAD]; + relay_info.rx_status = relay_info.lr1mac->rp->radio_params[RP_HOOK_ID_RELAY_RX_CAD].rx.lora_pkt_status; + } + break; + + case RP_STATUS_CAD_NEGATIVE: + case RP_STATUS_RX_TIMEOUT: + case RP_STATUS_RX_CRC_ERROR: + case RP_STATUS_TX_DONE: + break; + + case RP_STATUS_TASK_ABORTED: + SMTC_MODEM_HAL_TRACE_WARNING( "Relay Task aborted\n" ); + relay_info.state = CAD_STATE_ENQUEUE_CAD; + break; + + default: + SMTC_MODEM_HAL_TRACE_WARNING( "callback_relay default switch: 0x%x\n", planner_status ); + break; + } + + manage_fsm( irq_timestamp_ms, cad_success, rx_success ); +} + +static void manage_fsm( const uint32_t irq_timestamp_ms, const bool cad_success, const bool rx_success ) +{ + switch( relay_info.state ) + { + case CAD_STATE_INIT: + // Do nothing + break; + + case CAD_STATE_ENQUEUE_CAD: + config_enqueue_next_cad( &relay_config, &relay_info ); + break; + + case CAD_STATE_WAIT_CAD_COMPLETION: + // In case of TCXO the case CAD_STATE_WAIT_CAD_COMPLETION is "bypassed" because the radio settings were set to + // CAD_TO_RX. When the CAD POSITIVE fired, the config_cad_to_rx_wor() is performed but the radio is already in + // Rx mode and the next cad is ignored + relay_stat.nb_cad1 += 1; + if( cad_success == false ) + { + // CAD has failed, program the next CAD + config_enqueue_next_cad( &relay_config, &relay_info ); + } + else + { + // CAD has succeed, radio is still for us so configure cad to rx + config_cad_to_rx_wor( &relay_config, &relay_info ); + relay_stat.nb_cad2 += 1; + } + break; + + case CAD_STATE_WAIT_WOR_COMPLETION: + { + if( cad_success == true ) + { + relay_stat.nb_cad2_ok += 1; + + // This is an intermediate interrupt that should be ignore has the main wor message is being received + return; + } + // Here complete message has been received or radio is in timeout + + if( rx_success == false ) + { + // Failed to received WOR frame + relay_stat.nb_wor_fail += 1; + config_enqueue_next_cad( &relay_config, &relay_info ); + return; + } + + // SMTC_MODEM_HAL_TRACE_ARRAY( "WOR RX ", relay_info.buffer, relay_info.buffer_length ); + + if( wor_extract_wor_info( relay_info.buffer, relay_info.buffer_length, &relay_wor_info ) == false ) + { + SMTC_MODEM_HAL_TRACE_MSG( "Bad WOR\n" ); + config_enqueue_next_cad( &relay_config, &relay_info ); + return; + } + // A correct WOR has been received (MIC not yet checked) + relay_stat.nb_wor_ok += 1; + bool mic_is_valid = false; + + // Save RF WOR infos + relay_wor_info.rf_infos.freq_hz = relay_config.channel_cfg[relay_info.current_ch_idx].freq_hz; + relay_wor_info.rf_infos.dr = relay_config.channel_cfg[relay_info.current_ch_idx].dr; + relay_wor_info.rf_infos.rssi_in_dbm = relay_info.rx_status.rssi_pkt_in_dbm; + relay_wor_info.rf_infos.signal_rssi_in_db = relay_info.rx_status.signal_rssi_pkt_in_dbm; + relay_wor_info.rf_infos.snr_in_db = relay_info.rx_status.snr_pkt_in_db; + + // Raz to wrong value + // devaddr_idx = SIZE_TAB_DEV_ADDR_LIST; + relay_info.rx_msg_devaddr_idx = SIZE_TAB_DEV_ADDR_LIST; + + if( relay_wor_info.wor_type == WOR_MSG_TYPE_STANDARD_UPLINK ) + { + const uint32_t mic_receive = wor_extract_mic_wor_uplink( relay_info.buffer ); + mic_is_valid = is_mic_wor_valid( &relay_wor_info, mic_receive, &relay_info.rx_msg_devaddr_idx ); + if( mic_is_valid == true ) + { + wor_decode_wor_enc_data( relay_wor_info.uplink.enc_data, &relay_wor_info.uplink, + &relay_wor_info.rf_infos, + device_list_dev_addr[relay_info.rx_msg_devaddr_idx].wor_s_enc_key ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Invalid MIC\n" ); + } + } + + if( ( relay_wor_info.wor_type == WOR_MSG_TYPE_JOIN_REQUEST ) || + ( ( relay_wor_info.wor_type == WOR_MSG_TYPE_STANDARD_UPLINK ) && ( mic_is_valid == true ) ) ) + { + const uint8_t ul_dr = get_ul_dr( &relay_wor_info ); + const uint32_t ul_freq = get_ul_freq( &relay_wor_info ); + + if( smtc_real_is_tx_dr_valid( relay_info.lr1mac->real, ul_dr ) != OKLORAWAN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "WOR Wrong DR (%d)\n", ul_dr ); + config_enqueue_next_cad( &relay_config, &relay_info ); + return; + } + if( smtc_real_is_frequency_valid( relay_info.lr1mac->real, ul_freq ) != OKLORAWAN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "WOR wrong freq (%d)\n", ul_freq ); + config_enqueue_next_cad( &relay_config, &relay_info ); + return; + } + } + + if( check_fwd_limitation( &relay_wor_info, relay_info.rx_msg_devaddr_idx ) != true ) + { + SMTC_MODEM_HAL_TRACE_MSG( "Forward limitation exceed\n" ); + config_enqueue_next_cad( &relay_config, &relay_info ); + return; + } + + // Compensate RX TX done jitter + relay_info.rx_wor_timestamp_ms = irq_timestamp_ms - relay_info.t_irq_comp_wor_ms[relay_info.current_ch_idx]; + // SMTC_MODEM_HAL_TRACE_PRINTF( " Rx WOR %d %d %d\n", relay_info.rx_wor_timestamp_ms, irq_timestamp_ms, + // relay_info.t_irq_comp_wor_ms[relay_info.current_ch_idx] ); + + if( relay_wor_info.wor_type == WOR_MSG_TYPE_JOIN_REQUEST ) + { + // SMTC_MODEM_HAL_TRACE_MSG( "WOR Join Request receive\n" ); + config_enqueue_rx_msg( &relay_config, &relay_wor_info, + relay_info.rx_wor_timestamp_ms + DELAY_WOR_TO_JOINREQ_MS ); + return; + } + else if( relay_wor_info.wor_type == WOR_MSG_TYPE_STANDARD_UPLINK ) + { + relay_info.t_offset = relay_info.rx_wor_timestamp_ms - relay_info.last_cad_ms - + relay_info.wor_toa_ms[relay_info.current_ch_idx]; + + // SMTC_MODEM_HAL_TRACE_MSG( "WOR Standard Uplink receive:\n" ); + // SMTC_MODEM_HAL_TRACE_PRINTF( " - Dev Addr : 0x%08X\n", relay_wor_info.uplink.devaddr ); + // SMTC_MODEM_HAL_TRACE_PRINTF( " - FCNT : %d\n", relay_wor_info.uplink.fcnt ); + // SMTC_MODEM_HAL_TRACE_PRINTF( " - MIC : %s\n", ( mic_is_valid ? " ok" : "nok" ) ); + // SMTC_MODEM_HAL_TRACE_PRINTF( " - T offset : %d ( %d - %d - %d)\n", relay_info.t_offset, + // relay_info.rx_wor_timestamp_ms, relay_info.last_cad_ms, + // relay_info.wor_toa_ms[relay_info.current_ch_idx] ); + + if( mic_is_valid == true ) + { + // check duty cycle before to transmit wor_ack + smtc_duty_cycle_update( ); + if( smtc_duty_cycle_is_channel_free( + relay_config.channel_cfg[relay_info.current_ch_idx].ack_freq_hz ) == true ) + { + // Send ACK + relay_stat.nb_ack_tx += 1; + config_enqueue_ack( &relay_config, &relay_wor_info, relay_info.rx_wor_timestamp_ms, &relay_info, + relay_info.rx_msg_devaddr_idx ); + return; + } + else + { + config_enqueue_next_cad( &relay_config, &relay_info ); + SMTC_MODEM_HAL_TRACE_PRINTF( "No more duty cycle to transmit ack for ED (0x%08X) \n", + relay_wor_info.uplink.devaddr ); + return; + } + } + else + { + notify_unknown_ed( &relay_wor_info ); + config_enqueue_next_cad( &relay_config, &relay_info ); + SMTC_MODEM_HAL_TRACE_PRINTF( "Unknown ED (0x%08X) \n", relay_wor_info.uplink.devaddr ); + return; + } + } + else + { + SMTC_MODEM_HAL_PANIC( ); // never happen - manage earlier + } + } + break; + + case CAD_STATE_WAIT_TX_ACK_COMPLETION: + relay_info.tx_ack_timestamp_ms = irq_timestamp_ms; + config_enqueue_rx_msg( &relay_config, &relay_wor_info, + relay_info.tx_ack_timestamp_ms + DELAY_WORACK_TO_UPLINK_MS ); + break; + + case CAD_STATE_WAIT_RX_DATA_COMPLETION: + if( rx_success == false ) + { + relay_stat.nb_rx_fail += 1; + SMTC_MODEM_HAL_TRACE_MSG( "Missed data :( \n" ); + config_enqueue_next_cad( &relay_config, &relay_info ); + } + else + { + relay_stat.nb_rx_ok += 1; + // SMTC_MODEM_HAL_TRACE_MSG( "RX sucess :)\n" ); + bool fwd_msg = true; + + if( relay_wor_info.wor_type == WOR_MSG_TYPE_JOIN_REQUEST ) + { + fwd_msg = check_forward_filter_joinreq( relay_info.buffer + 1, relay_info.buffer + 9 ); + } + + // Standard uplink has already been check to forward (or not) when WOR MIC is check + const int16_t rx_correct_us = + relay_compute_rx_done_correction( get_ul_dr( &relay_wor_info ), relay_info.buffer_length ); + relay_info.rx_uplink_timestamp_ms = irq_timestamp_ms - ( rx_correct_us / 1000 ); + + if( fwd_msg == true ) + { + fwd_rx_msg( &relay_wor_info, &relay_config, &relay_info ); + } + else + { + config_enqueue_next_cad( &relay_config, &relay_info ); + } + } + break; + + default: + SMTC_MODEM_HAL_PANIC( "Impossible value\n" ); + break; + } +} + +static void config_enqueue_next_cad( const relay_config_t* config, relay_infos_t* info ) +{ + if( relay_info.is_started == false ) + { + SMTC_MODEM_HAL_TRACE_MSG( "Enqueue CAD but stop\n" ); + return; + } + + const int32_t duty_cycle_ms = modem_duty_cycle_get_status( RELAY_STACK_ID ); + uint32_t actual_ms = smtc_modem_hal_get_time_in_ms( ) + 10; + if( duty_cycle_ms > 0 ) // No DTC available until X ms -> move "now" to a time where DTC is OK + { + SMTC_MODEM_HAL_TRACE_PRINTF( "DTC - wait %d ms to re-enable relay\n", duty_cycle_ms ); + actual_ms += duty_cycle_ms; + } + + const uint32_t cad_period_ms = wor_convert_cad_period_in_ms( config->cad_period ) / config->nb_wor_channel; + uint32_t next_cad_start_ms = info->last_cad_ms; + + while( ( ( int ) ( next_cad_start_ms - smtc_modem_hal_get_radio_tcxo_startup_delay_ms( ) - actual_ms ) <= 0 ) ) + { + next_cad_start_ms += cad_period_ms; + info->current_ch_idx += 1; + } + // SMTC_MODEM_HAL_TRACE_PRINTF( "Next CAD at %d\n", next_cad_start_ms ); + + info->current_ch_idx %= config->nb_wor_channel; + info->next_cad_ms = next_cad_start_ms; + info->last_cad_ms = next_cad_start_ms; + + // default value of default channel even if cad period is smaller + wor_cad_periodicity_t cad_period = WOR_CAD_PERIOD_1S; + if( info->current_ch_idx != 0 ) + { + cad_period = config->cad_period; + } + + rp_radio_params_t rx_param = { 0 }; + const relay_channel_config_t* channel_cfg = &config->channel_cfg[info->current_ch_idx]; + wor_ral_init_rx_wor( relay_info.lr1mac->real, channel_cfg->dr, channel_cfg->freq_hz, cad_period, + MAX( ( uint8_t ) WOR_JOINREQ_LENGTH, ( uint8_t ) WOR_UPLINK_LENGTH ), &rx_param ); + wor_ral_init_cad( relay_info.lr1mac->real, channel_cfg->dr, cad_period, true, + relay_info.wor_toa_ms[info->current_ch_idx], &rx_param.rx.cad ); + + const rp_task_t rp_task_cad = { + .hook_id = RP_HOOK_ID_RELAY_RX_CAD, + .type = RP_TASK_TYPE_CAD_TO_RX, + .state = RP_TASK_STATE_SCHEDULE, + .schedule_task_low_priority = true, + .duration_time_ms = 20000, + .start_time_ms = info->next_cad_ms - smtc_modem_hal_get_radio_tcxo_startup_delay_ms( ), + .launch_task_callbacks = wor_ral_callback_start_cad, + }; + + if( rp_task_enqueue( relay_info.lr1mac->rp, &rp_task_cad, info->buffer, 255, &rx_param ) == RP_HOOK_STATUS_OK ) + { + info->state = CAD_STATE_WAIT_CAD_COMPLETION; + } + else + { + SMTC_MODEM_HAL_PANIC( "RP is busy, fail in config_enqueue_next_cad\n" ); + } +} + +static void config_cad_to_rx_wor( const relay_config_t* config, relay_infos_t* info ) +{ + const wor_cad_periodicity_t cad_period = ( info->current_ch_idx != 0 ) ? config->cad_period : WOR_CAD_PERIOD_1S; + const relay_channel_config_t* channel_cfg = &config->channel_cfg[info->current_ch_idx]; + + ral_lora_cad_params_t cad_param = { 0 }; + + wor_ral_init_cad( relay_info.lr1mac->real, channel_cfg->dr, cad_period, false, + relay_info.wor_toa_ms[info->current_ch_idx], &cad_param ); + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_lora_cad_params( &( relay_info.radio->ral ), &cad_param ) == + RAL_STATUS_OK ); + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_lora_cad( &( relay_info.radio->ral ) ) == RAL_STATUS_OK ); + + info->state = CAD_STATE_WAIT_WOR_COMPLETION; +} + +static void config_enqueue_rx_msg( const relay_config_t* config, const wor_infos_t* wor, + const uint32_t timestamp_lr1_ul ) +{ + const uint8_t ul_dr = get_ul_dr( &relay_wor_info ); + const uint32_t ul_freq = get_ul_freq( &relay_wor_info ); + + // SMTC_MODEM_HAL_TRACE_PRINTF( "Config RX at DR%d at %d Hz\n", ul_dr, ul_freq ); + + // Max payload to receive: min value of payload size between (ED/Relay) and (Relay/GTW minus relay overhead) + uint8_t max_rx = + smtc_real_get_max_payload_size( relay_info.lr1mac->real, relay_info.lr1mac->tx_data_rate, UP_LINK ) + MICSIZE + + MHDRSIZE; + if( max_rx > RELAY_OVERHEAD_FORWARD ) + { + max_rx -= RELAY_OVERHEAD_FORWARD; + max_rx = MIN( smtc_real_get_max_payload_size( relay_info.lr1mac->real, ul_dr, UP_LINK ) + MICSIZE + MHDRSIZE, + max_rx ); + } + else + { + max_rx = 0; + } + + rp_radio_params_t rp_radio_params = { 0 }; + wor_ral_init_rx_msg( relay_info.lr1mac->real, max_rx, ul_dr, ul_freq, &rp_radio_params ); + + rp_task_t rx_task = { + .hook_id = RP_HOOK_ID_RELAY_RX_CAD, + .state = RP_TASK_STATE_SCHEDULE, + .start_time_ms = timestamp_lr1_ul - smtc_modem_hal_get_radio_tcxo_startup_delay_ms( ), + .launch_task_callbacks = wor_ral_callback_start_rx, + }; + + if( rp_radio_params.pkt_type == RAL_PKT_TYPE_LORA ) + { + rx_task.type = RP_TASK_TYPE_RX_LORA; + rx_task.duration_time_ms = ral_get_lora_time_on_air_in_ms( + &relay_info.radio->ral, &rp_radio_params.rx.lora.pkt_params, &rp_radio_params.rx.lora.mod_params ); + } + else if( rp_radio_params.pkt_type == RAL_PKT_TYPE_GFSK ) + { + rx_task.type = RP_TASK_TYPE_RX_FSK; + rx_task.duration_time_ms = ral_get_gfsk_time_on_air_in_ms( + &relay_info.radio->ral, &rp_radio_params.rx.gfsk.pkt_params, &rp_radio_params.rx.gfsk.mod_params ); + } + else + { + SMTC_MODEM_HAL_PANIC( "RX message modulation unsupported\n" ); + } + + rp_radio_params.rx.timeout_in_ms = rx_task.duration_time_ms; + + if( rp_task_enqueue( relay_info.lr1mac->rp, &rx_task, relay_info.buffer, 255, &rp_radio_params ) == + RP_HOOK_STATUS_OK ) + { + relay_info.state = CAD_STATE_WAIT_RX_DATA_COMPLETION; + } + else + { + SMTC_MODEM_HAL_PANIC( "RP is busy\n" ); + } +} + +static void config_enqueue_ack( const relay_config_t* config, const wor_infos_t* wor, const uint32_t time_rx, + relay_infos_t* info, const uint8_t devaddr_idx ) +{ + // SMTC_MODEM_HAL_TRACE_MSG( "Prepare ACK \n" ); + + bool fwd_ok = true; + + if( modem_duty_cycle_get_status( RELAY_STACK_ID ) > 0 ) + { + fwd_ok = false; + } + else if( check_fwd_limitation( wor, devaddr_idx ) == false ) + { + fwd_ok = false; + } + + const wor_ack_infos_t ack = { + .dr_relay_gtw = info->lr1mac->tx_data_rate, + .t_offset = info->t_offset, + .period = config->cad_period, + .relay_ppm = info->error_ppm, + .cad_to_rx = info->cad_to_rx, + .relay_fwd = ( fwd_ok == true ? WOR_ACK_FORWARD_OK : WOR_ACK_FORWARD_RETRY_60MIN ), + }; + + const relay_channel_config_t* channel_cfg = &config->channel_cfg[info->current_ch_idx]; + + const wor_ack_mic_info_t mic_info = { + .dev_addr = device_list_dev_addr[devaddr_idx].dev_addr, + .wfcnt = device_list_dev_addr[devaddr_idx].wfcnt32, + .datarate = channel_cfg->dr, + .frequency_hz = channel_cfg->ack_freq_hz, + .wor_datarate = wor->uplink.dr, + .wor_frequency_hz = wor->uplink.freq_hz, + + }; + + info->buffer_length = + wor_generate_ack( info->buffer, &ack, &mic_info, device_list_dev_addr[devaddr_idx].wor_s_int_key, + device_list_dev_addr[devaddr_idx].wor_s_enc_key ); + + rp_radio_params_t radio_params = { 0 }; + wor_ral_init_tx_ack( relay_info.lr1mac->real, channel_cfg->dr, channel_cfg->ack_freq_hz, info->buffer_length, + &radio_params ); + + const rp_task_t rp_task = { + .start_time_ms = time_rx + DELAY_WOR_TO_WORACK_MS - smtc_modem_hal_get_radio_tcxo_startup_delay_ms( ), + .hook_id = RP_HOOK_ID_RELAY_RX_CAD, + .state = RP_TASK_STATE_SCHEDULE, + .launch_task_callbacks = wor_ral_callback_start_tx, + .type = RP_TASK_TYPE_TX_LORA, + .duration_time_ms = ral_get_lora_time_on_air_in_ms( + ( &relay_info.radio->ral ), ( &radio_params.tx.lora.pkt_params ), ( &radio_params.tx.lora.mod_params ) ), + }; + + // SMTC_MODEM_HAL_TRACE_ARRAY( "TX WOR ACK", info->buffer, info->buffer_length ); + // SMTC_MODEM_HAL_TRACE_PRINTF( "At DR%d at %d Hz - toa %d\n", channel_cfg->dr, channel_cfg->ack_freq_hz, + // rp_task.duration_time_ms ); + + if( rp_task_enqueue( info->lr1mac->rp, &rp_task, relay_info.buffer, relay_info.buffer_length, &radio_params ) == + RP_HOOK_STATUS_OK ) + { + relay_info.state = CAD_STATE_WAIT_TX_ACK_COMPLETION; + } + else + { + SMTC_MODEM_HAL_PANIC( "RP is busy,fail in config_enqueue_ack" ); + } +} + +static bool is_mic_wor_valid( const wor_infos_t* wor, uint32_t mic_receive, uint8_t* device_idx ) +{ + for( uint8_t i = 0; i < SIZE_TAB_DEV_ADDR_LIST; i++ ) + { + if( ( device_list_dev_addr[i].in_use == true ) && ( device_list_dev_addr[i].dev_addr == wor->uplink.devaddr ) ) + { + uint32_t fcnt = device_list_dev_addr[i].wfcnt32; + // Check if rollover on fcnt + if( wor->uplink.fcnt <= ( uint16_t ) ( fcnt & MAX_UINT16 ) ) + { + fcnt += MAX_UINT16; + } + // Clear 16 LSB and update with receive value + fcnt &= ~( MAX_UINT16 ); + fcnt += wor->uplink.fcnt; + + const wor_mic_infos_t wor_mic_info = { + .dev_addr = device_list_dev_addr[i].dev_addr, + .wfcnt = fcnt, + }; + + const uint32_t mic_calc = + wor_compute_mic_wor( &wor_mic_info, wor->uplink.enc_data, device_list_dev_addr[i].wor_s_int_key ); + + if( mic_receive == mic_calc ) + { + *device_idx = i; + device_list_dev_addr[i].wfcnt32 = fcnt; + return true; + } + } + } + + return false; +} + +static void fwd_rx_msg( const wor_infos_t* wor, const relay_config_t* config, const relay_infos_t* info ) +{ + if( wor->wor_type == WOR_MSG_TYPE_JOIN_REQUEST ) + { + decrement_fwd_counter( &relay_fwd_cnt[LIMIT_JOINREQ] ); + } + else if( wor->wor_type == WOR_MSG_TYPE_STANDARD_UPLINK ) + { + decrement_fwd_counter( &relay_fwd_cnt[LIMIT_GLOBAL_UPLINK] ); + decrement_fwd_counter( &device_list_dev_addr[info->rx_msg_devaddr_idx].fwd_cfg ); + } + else + { + SMTC_MODEM_HAL_PANIC( ); + } + + decrement_fwd_counter( &relay_fwd_cnt[LIMIT_OVERALL] ); + + SMTC_MODEM_HAL_TRACE_PRINTF( "UL metadata - %d bytes at DR%d %dHz, WOR ch%d\n", info->buffer_length, + get_ul_dr( &relay_wor_info ), get_ul_freq( &relay_wor_info ), info->current_ch_idx ); + SMTC_MODEM_HAL_TRACE_PRINTF( "rssi %d - snr %d - signal %d\n", info->rx_status.rssi_pkt_in_dbm, + info->rx_status.snr_pkt_in_db, info->rx_status.signal_rssi_pkt_in_dbm ); + + int16_t tmp; + uint32_t uplink_metadata = 0; + uplink_metadata |= RELAY_FWD_UPLINK_SET_METADATA_WOR_CH( info->current_ch_idx ); + + tmp = info->rx_status.rssi_pkt_in_dbm; + tmp = MIN( -15, tmp ); + tmp = MAX( -142, tmp ); + uplink_metadata |= RELAY_FWD_UPLINK_SET_METADATA_UPLINK_RSSI( ( uint8_t ) ( -( tmp + 15 ) ) ); + + tmp = info->rx_status.snr_pkt_in_db; + tmp = MIN( 11, tmp ); + tmp = MAX( -20, tmp ); + uplink_metadata |= RELAY_FWD_UPLINK_SET_METADATA_UPLINK_SNR( ( uint8_t ) ( tmp + 20 ) ); + + uplink_metadata |= RELAY_FWD_UPLINK_SET_METADATA_UPLINK_DR( get_ul_dr( &relay_wor_info ) ); + + uint8_t buffer[255]; + buffer[RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_METADATA_7_0] = ( uint8_t ) ( uplink_metadata ); + buffer[RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_METADATA_15_8] = ( uint8_t ) ( uplink_metadata >> 8 ); + buffer[RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_METADATA_23_16] = ( uint8_t ) ( uplink_metadata >> 16 ); + + const uint32_t freq_step = get_ul_freq( &relay_wor_info ) / 100; + + buffer[RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_FREQUENCY_7_0] = ( uint8_t ) ( freq_step ); + buffer[RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_FREQUENCY_15_8] = ( uint8_t ) ( freq_step >> 8 ); + buffer[RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_FREQUENCY_23_16] = ( uint8_t ) ( freq_step >> 16 ); + + memcpy( buffer + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_PAYLOAD, info->buffer, info->buffer_length ); + + lorawan_relay_rx_fwd_uplink( + RELAY_STACK_ID, buffer, info->buffer_length + RELAY_FWD_UPLINK_BYTE_ORDER_UPLINK_PAYLOAD, + info->rx_uplink_timestamp_ms + RELAY_FWD_DELAY, ( wor->wor_type == WOR_MSG_TYPE_JOIN_REQUEST ? true : false ) ); +} + +static void notify_unknown_ed( const wor_infos_t* wor ) +{ + decrement_fwd_counter( &relay_fwd_cnt[LIMIT_OVERALL] ); + decrement_fwd_counter( &relay_fwd_cnt[LIMIT_NOTIFY] ); + + int16_t tmp; + uint16_t power_level = 0; + + tmp = wor->rf_infos.rssi_in_dbm; + tmp = MIN( -15, tmp ); + tmp = MAX( -142, tmp ); + power_level |= RELAY_NOTIFY_POWER_LEVEL_UPLINK_RSSI( ( uint8_t ) ( -( tmp + 15 ) ) ); + + tmp = wor->rf_infos.snr_in_db; + tmp = MIN( 11, tmp ); + tmp = MAX( -20, tmp ); + power_level |= RELAY_NOTIFY_POWER_LEVEL_UPLINK_SNR( ( uint8_t ) ( tmp + 20 ) ); + + uint8_t buffer[RELAY_NOTIFY_BYTE_ORDER_POWER_LEVEL_LENGTH]; + + buffer[RELAY_NOTIFY_BYTE_CID_REQ] = RELAY_CID_NOTIFY; + buffer[RELAY_NOTIFY_BYTE_ORDER_DEV_ADDR_7_0] = ( uint8_t ) ( wor->uplink.devaddr ); + buffer[RELAY_NOTIFY_BYTE_ORDER_DEV_ADDR_15_8] = ( uint8_t ) ( wor->uplink.devaddr >> 8 ); + buffer[RELAY_NOTIFY_BYTE_ORDER_DEV_ADDR_23_16] = ( uint8_t ) ( wor->uplink.devaddr >> 16 ); + buffer[RELAY_NOTIFY_BYTE_ORDER_DEV_ADDR_31_24] = ( uint8_t ) ( wor->uplink.devaddr >> 24 ); + buffer[RELAY_NOTIFY_BYTE_ORDER_POWER_LEVEL_7_0] = ( uint8_t ) ( power_level ); + buffer[RELAY_NOTIFY_BYTE_ORDER_POWER_LEVEL_15_8] = ( uint8_t ) ( power_level >> 8 ); + + lorawan_api_payload_send( 0, true, buffer, RELAY_NOTIFY_BYTE_ORDER_POWER_LEVEL_LENGTH, UNCONF_DATA_UP, + smtc_modem_hal_get_time_in_ms( ) + 20, RELAY_STACK_ID ); +} + +static int16_t relay_compute_rx_done_correction( uint8_t datarate, uint16_t payload_len ) +{ + const uint16_t delay_fft_sf[12 - 5 + 1] = { 23, 45, 91, 181, 362, 724, 1448, 2896 }; //(1<real, datarate ) != LORA ) + { + return 0; + } + smtc_real_lora_dr_to_sf_bw( relay_info.lr1mac->real, datarate, &sf, &bw ); + + // CRC is ON and Header explicit and CR45 for SX126x + payload_len += 2; // For the CRC + + switch( bw ) + { + case RAL_LORA_BW_500_KHZ: + delay_filter_irq = -3 + ( delay_fft_sf[sf - 5] >> 2 ); + clock_shift = 4; + break; + + case RAL_LORA_BW_250_KHZ: + delay_filter_irq = 12 + ( delay_fft_sf[sf - 5] >> 1 ); + clock_shift = 3; + if( sf == 12 ) + { + ppm = 2; + } + break; + + case RAL_LORA_BW_125_KHZ: + delay_filter_irq = 38 + delay_fft_sf[sf - 5]; + clock_shift = 2; + if( sf >= 11 ) + { + ppm = 2; + } + break; + + default: + return 0; + } + + const uint32_t fft_delay = ( sf + 1 ) << ( sf + 1 ); + const uint32_t demap_delay = ( 1 << sf ); + const uint8_t fine_sync = ( sf <= 6 ) ? 4 : 6; + const uint32_t dec_delay = ( ( ( payload_len << 1 ) - sf + fine_sync ) % ( sf - ppm ) ) * 80 + 5; + const uint32_t phy_delay = ( ( fft_delay + demap_delay + dec_delay - 1 ) >> clock_shift ) + 1; + const uint32_t delay = delay_filter_irq + phy_delay; + + return delay; +} + +static bool check_fwd_limitation( const wor_infos_t* wor, uint8_t device_idx ) +{ + static bool is_first_init = true; + static uint32_t relay_fwd_time = 0; + const uint32_t current_hour = smtc_modem_hal_get_time_in_ms( ) / 3600000; + + if( is_first_init == true ) + { + is_first_init = false; + relay_fwd_time = current_hour; + } + + // SMTC_MODEM_HAL_TRACE_PRINTF( "Check FWD Limit %d vs %d\n", relay_fwd_time, current_hour ); + if( current_hour != relay_fwd_time ) + { + uint16_t diff_hour = 0; + if( current_hour > relay_fwd_time ) + { + diff_hour = current_hour - relay_fwd_time; + } + else + { + // 1193 is 0xFFFFFFFF/3600000 + // There is no +1 as 1193 is 167s from the max of 0xFFFFFFFF + diff_hour = current_hour + 1193 - relay_fwd_time; + } + + relay_fwd_time = current_hour; + + for( uint8_t i = 0; i < LIMIT__LAST_ELT; i++ ) + { + relay_fwd_cnt[i].token_available += relay_fwd_cnt[i].reload_rate * diff_hour; + if( relay_fwd_cnt[i].token_available > relay_fwd_cnt[i].bucket_size ) + { + relay_fwd_cnt[i].token_available = relay_fwd_cnt[i].bucket_size; + } + } + + for( uint16_t i = 0; i < SIZE_TAB_DEV_ADDR_LIST; i++ ) + { + relay_fwd_uplink_list_t* device = &device_list_dev_addr[i]; + + if( device->in_use == true ) + { + device->fwd_cfg.token_available += device->fwd_cfg.reload_rate * diff_hour; + + if( device->fwd_cfg.token_available > device->fwd_cfg.bucket_size ) + { + device->fwd_cfg.token_available = device->fwd_cfg.bucket_size; + } + } + } + } + + // SMTC_MODEM_HAL_TRACE_PRINTF( "- Overall : %d\n", relay_fwd_cnt[0].token_available ); + // SMTC_MODEM_HAL_TRACE_PRINTF( "- GlobalUplink : %d\n", relay_fwd_cnt[1].token_available ); + // SMTC_MODEM_HAL_TRACE_PRINTF( "- Notify : %d\n", relay_fwd_cnt[2].token_available ); + // SMTC_MODEM_HAL_TRACE_PRINTF( "- JoinReq : %d\n", relay_fwd_cnt[3].token_available ); + + if( ( relay_fwd_cnt[LIMIT_OVERALL].unlimited_fwd == false ) && + ( relay_fwd_cnt[LIMIT_OVERALL].token_available == 0 ) ) + { + return false; + } + + if( wor->wor_type == WOR_MSG_TYPE_JOIN_REQUEST ) + { + if( ( relay_fwd_cnt[LIMIT_JOINREQ].unlimited_fwd == false ) && + ( relay_fwd_cnt[LIMIT_JOINREQ].token_available == 0 ) ) + { + return false; + } + } + else if( wor->wor_type == WOR_MSG_TYPE_STANDARD_UPLINK ) + { + if( ( relay_fwd_cnt[LIMIT_GLOBAL_UPLINK].unlimited_fwd == false ) && + ( relay_fwd_cnt[LIMIT_GLOBAL_UPLINK].token_available == 0 ) ) + { + return false; + } + + if( device_idx != SIZE_TAB_DEV_ADDR_LIST ) // Known ED with valid MIC on WOR + { + if( ( device_list_dev_addr[device_idx].fwd_cfg.unlimited_fwd == false ) && + ( device_list_dev_addr[device_idx].fwd_cfg.token_available == 0 ) ) + { + return false; + } + } + else + { + if( ( relay_fwd_cnt[LIMIT_NOTIFY].unlimited_fwd == false ) && + ( relay_fwd_cnt[LIMIT_NOTIFY].token_available == 0 ) ) + { + return false; + } + } + } + + return true; +} + +static bool check_forward_filter_joinreq( const uint8_t joineui[8], const uint8_t deveui[8] ) +{ + bool msg_to_fwd = ( device_list_join[0].action == RELAY_FILTER_FWD_TYPE_FORWARD ) ? true : false; + uint8_t max_match = 0; + + for( uint16_t i = 1; i < SIZE_TAB_JOIN_REQ_LIST; i++ ) + { + if( ( device_list_join[i].action != RELAY_FILTER_FWD_TYPE_CLEAR ) && ( device_list_join[i].len >= max_match ) ) + { + const uint8_t compare_length_joineui = MIN( device_list_join[i].len, 8 ); + bool is_a_match = true; + + for( uint16_t j = 0; j < compare_length_joineui; j++ ) + { + if( device_list_join[i].eui[j] != joineui[7 - j] ) + { + is_a_match = false; + } + } + + if( is_a_match == true ) // -> JOIN EUI is a match + { + if( device_list_join[i].len > 8 ) + { + const uint8_t compare_length_deveui = device_list_join[i].len - 8; + for( uint16_t j = 0; j < compare_length_deveui; j++ ) + { + // Compare DEV EUI + if( device_list_join[i].eui[j + 8] != deveui[7 - j] ) + { + is_a_match = false; + } + } + } + + if( is_a_match == true ) // Check of JOIN EUI & DEV EUI is still a match + { + max_match = device_list_join[i].len; + msg_to_fwd = ( device_list_join[i].action == RELAY_FILTER_FWD_TYPE_FILTER ) ? false : true; + } + } + } + } + + // SMTC_MODEM_HAL_TRACE_PRINTF( "JoinRequest will be %s\n", ( msg_to_fwd ? "forward" : "filter" ) ); + + return msg_to_fwd; +} + +static void relay_rxr_tx_launch_callback( void* rp_void ) +{ + radio_planner_t* rp = ( radio_planner_t* ) rp_void; + const uint8_t id = rp->radio_task_id; + + if( rp->radio_params[id].pkt_type == RAL_PKT_TYPE_LORA ) + { + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ralf_setup_lora( rp->radio, &rp->radio_params[id].tx.lora ) == RAL_STATUS_OK ); + } + else + { + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ralf_setup_gfsk( rp->radio, &rp->radio_params[id].tx.gfsk ) == RAL_STATUS_OK ); + } + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_dio_irq_params( &( rp->radio->ral ), RAL_IRQ_TX_DONE ) == RAL_STATUS_OK ); + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + ral_set_pkt_payload( &( rp->radio->ral ), rp->payload[id], rp->payload_buffer_size[id] ) == RAL_STATUS_OK ); + // Wait the exact expected time (ie target - tcxo startup delay) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + { + // Do nothing + } + // At this time only tcxo startup delay is remaining + smtc_modem_hal_start_radio_tcxo( ); + smtc_modem_hal_set_ant_switch( true ); + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_tx( &( rp->radio->ral ) ) == RAL_STATUS_OK ); + rp_stats_set_tx_timestamp( &rp->stats, smtc_modem_hal_get_time_in_ms( ) ); +} + +static uint8_t get_ul_dr( const wor_infos_t* wor ) +{ + return ( ( relay_wor_info.wor_type == WOR_MSG_TYPE_JOIN_REQUEST ) ? relay_wor_info.join_request.dr + : relay_wor_info.uplink.dr ); +} +static uint32_t get_ul_freq( const wor_infos_t* wor ) +{ + return ( ( relay_wor_info.wor_type == WOR_MSG_TYPE_JOIN_REQUEST ) ? relay_wor_info.join_request.freq_hz + : relay_wor_info.uplink.freq_hz ); +} + +static void decrement_fwd_counter( relay_fwd_config_t* limit_counter ) +{ + if( ( limit_counter->unlimited_fwd == false ) && ( limit_counter->token_available > 0 ) ) + { + limit_counter->token_available -= 1; + } +} diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_api.h b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_api.h new file mode 100755 index 0000000..6b5c23c --- /dev/null +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_api.h @@ -0,0 +1,248 @@ +/*! + * \file relay_rx_api.h + * + * \brief Main function to interact with the relay (start,stop, configure,...) + * + * The Clear BSD License + * Copyright Semtech Corporation 2023. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __RELAY_RX_API_H__ +#define __RELAY_RX_API_H__ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "lr1_stack_mac_layer.h" +#include "wake_on_radio.h" + +typedef struct relay_channel_config_s +{ + uint32_t freq_hz; + uint32_t ack_freq_hz; + uint8_t dr; +} relay_channel_config_t; + +typedef struct relay_fwd_config_s +{ + uint32_t token_available; + uint16_t bucket_size; + uint16_t reload_rate; + bool unlimited_fwd; +} relay_fwd_config_t; + +typedef enum relay_forward_limit_action_e +{ + LIMIT_CNT_SET_TO_0, + LIMIT_CNT_SET_TO_RELOAD_RATE, + LIMIT_CNT_SET_TO_MAX_VAL, + LIMIT_CNT_DONT_CHANGE +} relay_forward_limit_action_t; + +typedef enum relay_forward_limit_list_e +{ + LIMIT_OVERALL, + LIMIT_GLOBAL_UPLINK, + LIMIT_NOTIFY, + LIMIT_JOINREQ, + LIMIT__LAST_ELT, +} relay_forward_limit_list_t; + +typedef struct relay_config_s +{ + wor_cad_periodicity_t cad_period; + relay_channel_config_t channel_cfg[MAX_WOR_CH]; + uint8_t nb_wor_channel; +} relay_config_t; + +typedef enum relay_filter_fwd_type_s +{ + RELAY_FILTER_FWD_TYPE_CLEAR, + RELAY_FILTER_FWD_TYPE_FORWARD, + RELAY_FILTER_FWD_TYPE_FILTER, + RELAY_FILTER_FWD_TYPE_RFU, +} relay_filter_fwd_type_t; + +typedef struct relay_stats_s +{ + uint32_t nb_cad1; // Total CAD1 since start + uint32_t nb_cad2; // Total CAD2 since start + uint32_t nb_cad2_ok; + uint16_t nb_wor_fail; // No WUS after double cad + uint16_t nb_wor_ok; // WUS ok (no mic check) + uint16_t nb_rx_ok; // RX receive + uint16_t nb_rx_fail; // No RX after a WUS + uint16_t nb_ack_tx; // +} relay_stats_t; + +/** + * @brief Init the relay data structure and FSM. + * + * Do only once + * + * @param[in] lr1mac LoRaWAN stack pointer + * @param[in] error_ppm Relay crystal error + * @param[in] cad_to_rx Relay CAD to RX in symbols + * @return true Init success + * @return false Init failed + */ +bool relay_init( lr1_stack_mac_t* lr1mac, wor_ack_ppm_error_t error_ppm, wor_ack_cad_to_rx_t cad_to_rx ); + +/** + * @brief Stop the periodic CAD + * + * @param[in] stop_to_fwd true if relay is temporally stop (to forward uplink) + * @return true Success + * @return false Failed + */ +bool relay_stop( bool stop_to_fwd ); + +/** + * @brief Start the periodic CAD + * + * @return true Success + * @return false Failed + */ +bool relay_start( void ); + +/** + * @brief Set a flag when the relay is started/stopped from a MAC command + * + * @param[in] relay_rx_start true when started by MAC command, false when stop by a MAC command + */ +void relay_rx_set_flag_started( bool relay_rx_start ); + +/** + * @brief + * + * @return true The relay is running (since started by a MAC command) + * @return false The relay is not running (since stopped by a MAC command) + */ +bool relay_rx_get_flag_started( void ); + +/** + * @brief Send a downlink to an ED on RXR + * + * @param[in] stack_id LoRaWAN stack ID + * @param[in] buffer Buffer to send + * @param[in] len Length of buffer + */ +void relay_fwd_dl( uint8_t stack_id, const uint8_t* buffer, uint8_t len ); + +/** + * @brief Update relay config + * + * If relay is running, the relay will stop, apply the new config and restart. + * + * @param[in] config New config + * @return true Successfully applied + * @return false Failed to applied the new config + */ +bool relay_update_config( const relay_config_t* config ); + +/** + * @brief Update join request filter/fwd list + * + * @param[in] idx Index of the rule + * @param[in] join_eui Join EUI (could be partial) + * @param[in] len_join_eui Length of Join EUI + * @param[in] dev_eui Dev EUI (could be partial) + * @param[in] len_dev_eui length of Dev EUI + * @param[in] action Clear,Filter Or Forward + */ +void relay_fwd_join_request_update_rule( const uint8_t idx, const uint8_t* join_eui, const uint8_t len_join_eui, + const uint8_t* dev_eui, const uint8_t len_dev_eui, + const relay_filter_fwd_type_t action ); + +/** + * @brief Add a trusted ED to the list + * + * @param[in] idx Index of the ED (between 0 and 15) + * @param[in] dev_addr ED Dev ADDR + * @param[in] root_wor_skey Root WOR session key + * @param[in] unlimited_fwd True if ED has no fwd restriction + * @param[in] bucket_factor Bucket factor + * @param[in] reload_rate Reload rate + * @param[in] wfcnt32 Last known wfcnt32 + * @return true ED has been added to the list + * @return false Failed to add the ED + */ +bool relay_fwd_uplink_add_device( const uint8_t idx, const uint32_t dev_addr, const uint8_t* root_wor_skey, + const bool unlimited_fwd, const uint8_t bucket_factor, const uint8_t reload_rate, + const uint32_t wfcnt32 ); + +/** + * @brief Remove an ED from the trusted list + * + * @param[in] idx Index of the ED (between 0 and 15) + * @return true ED has been removed from the list + * @return false Failed to remove the ED + */ +bool relay_fwd_uplink_remove_device( const uint8_t idx ); + +/** + * @brief Return last knwown WFCNT32 + * + * @param[in] idx Index of the ED (between 0 and 15) + * @param[out] wfcnt32 Last known wfcnt32 + * @return true Success + * @return false Failed to read WFCNT32 + */ +bool relay_fwd_uplink_read_wfcnt32( const uint8_t idx, uint32_t* wfcnt32 ); + +/** + * @brief Update forward limit of the relay + * + * @param[in] limit Limit type (global, notify, ...) + * @param[in] action Action on current limit (set to 0/max, ...) + * @param[in] unlimited True for no fwd restriction + * @param[in] reload_rate Reload rate + * @param[in] factor Multiplier factor + */ +void relay_fwd_update_fwd_limit( const relay_forward_limit_list_t limit, const relay_forward_limit_action_t action, + const bool unlimited, const uint16_t reload_rate, const uint8_t factor ); + +/** + * @brief Return statistics + * + * @param[in] stat relay statistics + */ +void relay_get_stats( relay_stats_t* stat ); + +/** + * @brief Print relay statistics + * + */ +void relay_print_stats( void ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_mac_parser.c b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_mac_parser.c new file mode 100755 index 0000000..961f528 --- /dev/null +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_mac_parser.c @@ -0,0 +1,610 @@ +/*! + * \file relay_rx_mac_parser.c + * + * \brief MAC command parser for Relay RX + * + * The Clear BSD License + * Copyright Semtech Corporation 2022. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + *----------------------------------------------------------------------------------- + * --- DEPENDENCIES ----------------------------------------------------------------- + */ + +#include "relay_rx_mac_parser.h" +#include "relay_mac_parser.h" +#include "relay_rx_api.h" +#include "relay_real.h" +#include "smtc_real.h" +#include "smtc_modem_hal_dbg_trace.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +#ifndef MIN +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + +#ifndef MAX +#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#endif +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +#define RELAY_CID_CONFIG_RELAY_ACK_BIT_CAD_PERIOD ( 5 ) +#define RELAY_CID_CONFIG_RELAY_ACK_BIT_DEFAULT_CH_IDX ( 4 ) +#define RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_IDX ( 3 ) +#define RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_DR ( 2 ) +#define RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_OFFSET ( 1 ) +#define RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_FREQUENCY ( 0 ) + +#define RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_ACTION ( 0 ) +#define RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_LEN ( 1 ) +#define RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_COMBINED_RULE ( 2 ) + +#define RELAY_CID_REMOVE_TRUSTED_ED_ACK_BIT_IDX ( 0 ) + +/* + *----------------------------------------------------------------------------------- + *--- PRIVATE FUNCTIONS DECLARATION ------------------------------------------------- + */ + +/** + * @brief Parse MAC Command 0x40 - RELAY_CID_CONFIG_RELAY + * + * @param[in] lr1_mac LoRaWAN stack pointer + * @param[in,out] cmd Mac command info + * @return true MAC command successfully decoded + * @return false Incorrect MAC command + */ +static bool relay_mac_update_config_relay_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ); + +/** + * @brief Parse MAC Command 0x42 - RELAY_CID_JOINREQ_FILTER + * + * @param[in] lr1_mac LoRaWAN stack pointer + * @param[in,out] cmd Mac command info + * @return true MAC command successfully decoded + * @return false Incorrect MAC command + */ +static bool relay_mac_update_joinreq_list_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ); + +/** + * @brief Parse MAC Command 0x43 - RELAY_CID_ADD_TRUSTED_ED + * + * @param[in] lr1_mac LoRaWAN stack pointer + * @param[in,out] cmd Mac command info + * @return true MAC command successfully decoded + * @return false Incorrect MAC command + */ +static bool relay_mac_add_trusted_ed_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ); + +/** + * @brief Parse MAC Command 0x44 - RELAY_CID_REMOVE_TRUSTED_ED + * + * @param[in] lr1_mac LoRaWAN stack pointer + * @param[in,out] cmd Mac command info + * @return true MAC command successfully decoded + * @return false Incorrect MAC command + */ +static bool relay_mac_manage_trusted_ed_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ); + +/** + * @brief Parse MAC Command 0x45 - RELAY_CID_FWD_LIMIT + * + * @param[in] lr1_mac LoRaWAN stack pointer + * @param[in,out] cmd Mac command info + * @return true MAC command successfully decoded + * @return false Incorrect MAC command + */ +static bool relay_mac_manage_fwd_list_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ); + +/** + * @brief Concatenate 4 LSB bytes into uint32 + * + * @param buffer[in] Input buffer + * @return uint32_t value + */ +static uint32_t concatenate_byte_lsb_to_uint32( const uint8_t* buffer ); + +static uint32_t get_symbol_time_ms( smtc_real_t* real, uint8_t dr ); +/* + *----------------------------------------------------------------------------------- + *--- PRIVATE VARIABLES ------------------------------------------------------------- + */ + +const relay_cid_info_t relay_rx_cid_infos[] = { + { + .cid_req = RELAY_CID_CONFIG_RELAY, + .name = "CONFIG_RELAY", + .parse_cmd = relay_mac_update_config_relay_parser, + .cid_req_min_size = 5, + .valid_req_ret = 0x3F, + }, + { + .cid_req = RELAY_CID_JOINREQ_FILTER, + .name = "JOINREQ_FILTER", + .parse_cmd = relay_mac_update_joinreq_list_parser, + .cid_req_min_size = 2, // 2 bytes + variable (up to 16) + .valid_req_ret = 0x07, + }, + { + .cid_req = RELAY_CID_ADD_TRUSTED_ED, + .name = "ADD_TRUSTED_ED", + .parse_cmd = relay_mac_add_trusted_ed_parser, + .cid_req_min_size = 26, + // .valid_req_ret = No return for this cmd + + }, + { + .cid_req = RELAY_CID_REMOVE_TRUSTED_ED, + .name = "REMOVE_TRUSTED_ED", + .parse_cmd = relay_mac_manage_trusted_ed_parser, + .cid_req_min_size = 1, + .valid_req_ret = 0x01, + }, + { + .cid_req = RELAY_CID_FWD_LIMIT, + .name = "FWD_LIMIT", + .parse_cmd = relay_mac_manage_fwd_list_parser, + .cid_req_min_size = 5, + // .valid_req_ret = No return for this cmd + }, +}; +const uint8_t nb_relay_mac_cmd = ( sizeof( relay_rx_cid_infos ) / sizeof( relay_cid_info_t ) ); +const uint16_t ack_offset_khz[SECOND_CH_ACK_OFFSET__LAST_ELT] = { 0, 200, 400, 800, 1600, 3200 }; +const uint16_t convert_bucket_size_factor[] = { 1, 2, 4, 12 }; + +#if ( MODEM_HAL_DBG_TRACE ) +const char* cad_period_str[] = { "1 s", "500 ms", "250 ms", "100 ms", "50 ms", "20 ms" }; +const char* ack_offset_khz_str[] = { "0 kHz", "2 kHz", "4 kHz", "8 kHz", "16 kHz", "32 kHz" }; +const char* action_fwd_str[] = { "FWD_CLEAR", "FWD_FORWARD", "FWD_FILTER", "FWD_RFU" }; +const char* limit_fwd_str[] = { "Overall ", "Global ", "Notify ", "Join Req" }; +const char* rst_limit_action_str[] = { "Set to 0", "Set to reload rate", "Set to max val", "Dont change" }; +#endif +/* + *----------------------------------------------------------------------------------- + *--- PUBLIC FUNCTIONS DEFINITIONS -------------------------------------------------- + */ + +bool relay_rx_mac_parser( lr1_stack_mac_t* lr1_mac ) +{ + return relay_mac_parser( lr1_mac, relay_rx_cid_infos, nb_relay_mac_cmd ); +} + +/* + *----------------------------------------------------------------------------------- + *--- PRIVATE FUNCTIONS DEFINITIONS ------------------------------------------------- + */ + +static bool relay_mac_update_config_relay_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ) +{ + uint8_t ack_ret = cmd->valid_req_ret; + const uint16_t settings_relay = ( uint16_t ) ( cmd->cmd_buffer[0] + ( cmd->cmd_buffer[1] << 8 ) ); + const bool start_stop = TAKE_N_BITS_FROM( settings_relay, 13, 1 ); + + if( start_stop == false ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Stop relay\n" ); + relay_stop( false ); + relay_rx_set_flag_started( false ); + } + else + { + relay_config_t config = { 0 }; + uint32_t cad_period_ms = 1000; + uint8_t second_ch_idx = TAKE_N_BITS_FROM( settings_relay, 7, 2 ); + + // Parse CAD Period + config.cad_period = TAKE_N_BITS_FROM( settings_relay, 10, 3 ); + + if( config.cad_period >= WOR_CAD_PERIOD_RFU ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "CAD period : wrong value \n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_CAD_PERIOD ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "CAD period : %s\n", cad_period_str[config.cad_period] ); + cad_period_ms = wor_convert_cad_period_in_ms( config.cad_period ) >> second_ch_idx; + } + + uint8_t default_chx_idx = TAKE_N_BITS_FROM( settings_relay, 9, 1 ); + if( smtc_relay_get_default_channel_config( lr1_mac->real, default_chx_idx, &( config.channel_cfg[0].dr ), + &( config.channel_cfg[0].freq_hz ), + &( config.channel_cfg[0].ack_freq_hz ) ) != OKLORAWAN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Default channel : Index %d is not supported\n", default_chx_idx ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_DEFAULT_CH_IDX ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Default channel : Index %d (DR %d - WOR %d Hz - ACK %d Hz)\n", + default_chx_idx, config.channel_cfg[0].dr, config.channel_cfg[0].freq_hz, + config.channel_cfg[0].ack_freq_hz ); + + const uint32_t symb_toa = 2 * get_symbol_time_ms( lr1_mac->real, config.channel_cfg[0].dr ) + 10; + + if( cad_period_ms < symb_toa ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "CAD period too short \n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_CAD_PERIOD ); + } + } + + // Parse second channel index + + if( second_ch_idx == 0 ) + { + config.nb_wor_channel = 1; + SMTC_MODEM_HAL_TRACE_PRINTF( "No additionnal channel \n" ); + } + else if( second_ch_idx == 1 ) + { + config.nb_wor_channel = 2; + config.channel_cfg[1].freq_hz = + ( uint32_t ) ( cmd->cmd_buffer[2] + ( cmd->cmd_buffer[3] << 8 ) + ( cmd->cmd_buffer[4] << 16 ) ) * 100; + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel freq: %d Hz\n", config.channel_cfg[1].freq_hz ); + + if( smtc_real_is_frequency_valid( lr1_mac->real, config.channel_cfg[1].freq_hz ) != OKLORAWAN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel freq: Invalid value\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_FREQUENCY ); + } + + config.channel_cfg[1].dr = TAKE_N_BITS_FROM( settings_relay, 3, 4 ); + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel DR: %d \n", config.channel_cfg[1].dr ); + + if( smtc_real_is_tx_dr_valid( lr1_mac->real, config.channel_cfg[1].dr ) != OKLORAWAN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel DR: Invalid value\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_DR ); + } + else if( smtc_real_get_modulation_type_from_datarate( lr1_mac->real, config.channel_cfg[1].dr ) != LORA ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel DR: Non LORA\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_DR ); + } + else + { + const uint32_t symb_toa = 2 * get_symbol_time_ms( lr1_mac->real, config.channel_cfg[1].dr ) + 10; + if( cad_period_ms < symb_toa ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "CAD period 2 too short \n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_CAD_PERIOD ); + } + } + + uint8_t ack_offset_khz_idx = TAKE_N_BITS_FROM( settings_relay, 0, 3 ); + + if( ack_offset_khz_idx < SECOND_CH_ACK_OFFSET__LAST_ELT ) + { + config.channel_cfg[1].ack_freq_hz = + config.channel_cfg[1].freq_hz + ack_offset_khz[ack_offset_khz_idx] * 1000; + + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel ACK offset: %s\n", + ack_offset_khz_str[ack_offset_khz_idx] ); + + if( smtc_real_is_frequency_valid( lr1_mac->real, config.channel_cfg[1].ack_freq_hz ) != OKLORAWAN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel ACK freq: Invalid value (%d Hz)\n", + config.channel_cfg[1].ack_freq_hz ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_OFFSET ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel ACK freq: %d Hz\n", + config.channel_cfg[1].ack_freq_hz ); + } + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel ACK offset: Invalid offset (%d)\n", ack_offset_khz_idx ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_OFFSET ); + } + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Additionnal channel index not supported\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_CONFIG_RELAY_ACK_BIT_SECOND_CH_IDX ); + } + + if( ack_ret == cmd->valid_req_ret ) + { + if( relay_update_config( &config ) == true ) + { + relay_start( ); + relay_rx_set_flag_started( true ); + SMTC_MODEM_HAL_TRACE_PRINTF( "New config has been accepted and relay has started\n" ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Wrong config\n" ); + ack_ret = 0; // config has been refused + } + } + } + + cmd->cmd_len -= cmd->cmd_min_len; + + cmd->out_buff[0] = ack_ret; + cmd->out_len = 1; + return true; +} + +static bool relay_mac_update_joinreq_list_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ) +{ + uint8_t ack_ret = cmd->valid_req_ret; + const uint16_t filter_list_param = ( uint16_t ) ( cmd->cmd_buffer[0] + ( cmd->cmd_buffer[1] << 8 ) ); + const uint8_t len = TAKE_N_BITS_FROM( filter_list_param, 0, 5 ); + const uint8_t action = TAKE_N_BITS_FROM( filter_list_param, 5, 2 ); + const uint8_t idx = TAKE_N_BITS_FROM( filter_list_param, 7, 4 ); + + // Variable size command, check param len + if( ( cmd->cmd_min_len + len ) > cmd->cmd_len ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Not enough param\n" ); + return false; + } + + if( len > 16 ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Lengh is too long (%d)\n", len ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_LEN ); + } + + if( action >= RELAY_FILTER_FWD_TYPE_RFU ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Action is not supported (%d)\n", action ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_ACTION ); + } + + if( idx == 0 ) + { + if( len != 0 ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Rule 0 should have a 0 len\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_COMBINED_RULE ); + } + + if( ( action != RELAY_FILTER_FWD_TYPE_FILTER ) && ( action != RELAY_FILTER_FWD_TYPE_FORWARD ) ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Rule 0 should be filter or forward\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_COMBINED_RULE ); + } + } + else // idx != 0 + { + if( ( len == 0 ) && ( action != RELAY_FILTER_FWD_TYPE_CLEAR ) ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Rule 1-15 should not have a 0 len with FWD or FILTER\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_COMBINED_RULE ); + } + + if( ( len != 0 ) && ( action == RELAY_FILTER_FWD_TYPE_CLEAR ) ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Rule 1-15 should have a 0 len with CLEAR\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_JOINREQ_FWD_FILTER_LIST_ACK_BIT_COMBINED_RULE ); + } + } + + if( ack_ret == cmd->valid_req_ret ) + { + uint8_t join_eui[8]; + uint8_t dev_eui[8]; + uint8_t len_join_eui = MIN( 8, len ); + uint8_t len_dev_eui = ( ( len > 8 ) ? len - 8 : 0 ); + + for( uint8_t i = 0; i < len_join_eui; i++ ) + { + join_eui[i] = cmd->cmd_buffer[2 + len - 1 - i]; + } + + for( uint8_t i = 0; i < len_dev_eui; i++ ) + { + dev_eui[i] = cmd->cmd_buffer[2 + len - 1 - i - len_join_eui]; + } + + SMTC_MODEM_HAL_TRACE_PRINTF( "Update rule %d with %s \n", idx, action_fwd_str[action] ); + if( len > 0 ) + { + SMTC_MODEM_HAL_TRACE_PACKARRAY( "Join EUI ", join_eui, len_join_eui ); + } + if( len > 8 ) + { + SMTC_MODEM_HAL_TRACE_PACKARRAY( "Dev EUI ", dev_eui, len_dev_eui ); + } + + relay_fwd_join_request_update_rule( idx, join_eui, len_join_eui, dev_eui, len_dev_eui, action ); + } + + cmd->cmd_len -= ( cmd->cmd_min_len + len ); + cmd->out_buff[0] = ack_ret; + cmd->out_len = 1; + return true; +} + +static bool relay_mac_add_trusted_ed_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ) +{ + const uint8_t idx = TAKE_N_BITS_FROM( cmd->cmd_buffer[0], 0, 4 ); + const uint8_t reload_rate = TAKE_N_BITS_FROM( cmd->cmd_buffer[1], 0, 6 ); + const uint8_t factor = TAKE_N_BITS_FROM( cmd->cmd_buffer[1], 6, 2 ); + const uint32_t dev_addr = concatenate_byte_lsb_to_uint32( cmd->cmd_buffer + 2 ); + const uint32_t wfcnt32 = concatenate_byte_lsb_to_uint32( cmd->cmd_buffer + 6 ); + + const bool unlimited_fwd = ( reload_rate == 63 ) ? true : false; + + uint8_t wor_s_key[16]; + // Manage WOR S KEY as MSB + memcpy( wor_s_key, cmd->cmd_buffer + 10, 16 ); + + // // Manage WOR S KEY as LSB + // for( uint8_t i = 0; i < 16; i++ ) + // { + // wor_s_key[15 - i] = cmd->cmd_buffer[10 + i]; + // } + + SMTC_MODEM_HAL_TRACE_PRINTF( "Idx %d\n", idx ); + SMTC_MODEM_HAL_TRACE_PRINTF( "DevAddr 0x%0X\n", dev_addr ); + SMTC_MODEM_HAL_TRACE_PRINTF( "WFCnt32 %d\n", wfcnt32 ); + SMTC_MODEM_HAL_TRACE_PACKARRAY( "WOR S KEY ", wor_s_key, 16 ); + if( unlimited_fwd == true ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Bucket Unlimited\n" ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Bucket %d x %d\n", reload_rate, convert_bucket_size_factor[factor] ); + } + + relay_fwd_uplink_add_device( idx, dev_addr, wor_s_key, unlimited_fwd, reload_rate, + convert_bucket_size_factor[factor], wfcnt32 ); + + cmd->cmd_len -= cmd->cmd_min_len; + cmd->out_len = 0; // No output param + return true; +} + +static bool relay_mac_manage_trusted_ed_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ) +{ + uint8_t ack_ret = cmd->valid_req_ret; + const uint8_t idx = TAKE_N_BITS_FROM( cmd->cmd_buffer[0], 0, 4 ); + const uint8_t action = TAKE_N_BITS_FROM( cmd->cmd_buffer[0], 4, 1 ); + + uint32_t wfcnt32 = 0; + + if( relay_fwd_uplink_read_wfcnt32( idx, &wfcnt32 ) == false ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Idx : invalid value (%d)\n", idx ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_REMOVE_TRUSTED_ED_ACK_BIT_IDX ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Idx : %d\n", idx ); + SMTC_MODEM_HAL_TRACE_PRINTF( "WFCnt32 : %d\n", wfcnt32 ); + SMTC_MODEM_HAL_TRACE_PRINTF( "Action : %s\n", ( action == 0 ? "read" : "remove" ) ); + + if( action != 0 ) + { + if( relay_fwd_uplink_remove_device( idx ) == false ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Idx : invalid value (failed to remove)\n" ); + ack_ret = RELAY_CLEAR_BIT( ack_ret, RELAY_CID_REMOVE_TRUSTED_ED_ACK_BIT_IDX ); + } + } + } + + cmd->cmd_len -= cmd->cmd_min_len; + + cmd->out_buff[0] = ack_ret; + cmd->out_buff[1] = ( wfcnt32 >> 0 ) & 0xFF; + cmd->out_buff[2] = ( wfcnt32 >> 8 ) & 0xFF; + cmd->out_buff[3] = ( wfcnt32 >> 16 ) & 0xFF; + cmd->out_buff[4] = ( wfcnt32 >> 24 ) & 0xFF; + cmd->out_len = 5; + return true; +} + +static bool relay_mac_manage_fwd_list_parser( lr1_stack_mac_t* lr1_mac, relay_cmd_parser_t* cmd ) +{ + const uint32_t reload_rate = concatenate_byte_lsb_to_uint32( cmd->cmd_buffer ); + const uint8_t factor = cmd->cmd_buffer[4]; + + const relay_forward_limit_action_t reset_limit = + ( relay_forward_limit_action_t ) TAKE_N_BITS_FROM( reload_rate, 28, 2 ); + + SMTC_MODEM_HAL_TRACE_PRINTF( "Reset : %s\n", rst_limit_action_str[reset_limit] ); + + for( uint8_t i = 0; i < LIMIT__LAST_ELT; i++ ) + { + const uint16_t limit_reload_rate = TAKE_N_BITS_FROM( reload_rate, 7 * i, 7 ); + const uint8_t limit_factor = convert_bucket_size_factor[TAKE_N_BITS_FROM( factor, 2 * i, 2 )]; + const bool unlimited_fwd = ( limit_reload_rate == 127 ) ? true : false; + + if( unlimited_fwd == true ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "- %s Unlimited\n", limit_fwd_str[i] ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( " - %s %d x %d\n", limit_fwd_str[i], limit_reload_rate, limit_factor ); + } + + relay_fwd_update_fwd_limit( i, reset_limit, unlimited_fwd, limit_reload_rate, limit_factor ); + } + + cmd->cmd_len -= cmd->cmd_min_len; + + cmd->out_len = 0; // No output param + return true; +} + +static uint32_t concatenate_byte_lsb_to_uint32( const uint8_t* buffer ) +{ + return ( uint32_t ) ( ( ( uint32_t ) buffer[0] ) + ( ( uint32_t ) buffer[1] << 8 ) + + ( ( uint32_t ) buffer[2] << 16 ) + ( ( uint32_t ) buffer[3] << 24 ) ); +} + +static uint32_t get_symbol_time_ms( smtc_real_t* real, uint8_t dr ) +{ + uint8_t sf; + lr1mac_bandwidth_t bw; + smtc_real_lora_dr_to_sf_bw( real, dr, &sf, &bw ); + + uint32_t toa_symb = 1 << sf; + + switch( bw ) + { + case BW125: + toa_symb = toa_symb / 125; + break; + case BW250: + toa_symb = toa_symb / 250; + break; + case BW500: + toa_symb = toa_symb / 500; + break; + case BW800: + toa_symb = toa_symb / 800; + break; + case BW1600: + toa_symb = toa_symb / 1600; + break; + + default: + break; + } + + SMTC_MODEM_HAL_TRACE_PRINTF( "TOA symbol DR%d : %d ms\n", dr, toa_symb ); + + return toa_symb; +} \ No newline at end of file diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_mac_parser.h b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_mac_parser.h new file mode 100755 index 0000000..8c6cbc5 --- /dev/null +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_rx/relay_rx_mac_parser.h @@ -0,0 +1,81 @@ +/*! + * \file relay_rx_mac_parser.h + * + * \brief MAC command parser for Relay RX + * + * The Clear BSD License + * Copyright Semtech Corporation 2023. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __RELAY_RX_MAC_PARSER__ +#define __RELAY_RX_MAC_PARSER__ + +#ifdef __cplusplus +extern "C" { +#endif +/* + *----------------------------------------------------------------------------------- + * --- DEPENDENCIES ----------------------------------------------------------------- + */ +#include "lr1_stack_mac_layer.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ +/* + *----------------------------------------------------------------------------------- + *--- PRIVATE VARIABLES ------------------------------------------------------------- + */ +/* + *----------------------------------------------------------------------------------- + *--- PRIVATE FUNCTIONS DECLARATION ------------------------------------------------- + */ + +/* + *----------------------------------------------------------------------------------- + *--- PUBLIC FUNCTIONS DEFINITIONS -------------------------------------------------- + */ + +/** + * @brief Dedicated parser for relay RX MAC Command + * + * @param[in,out] lr1_mac LoRaWAN stack pointer + * @return true MAC command is know + * @return false MAC command is unknow + */ +bool relay_rx_mac_parser( lr1_stack_mac_t* lr1_mac ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx.c b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx.c index f8c9ff9..1003ba4 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx.c @@ -36,21 +36,19 @@ * --- DEPENDENCIES ----------------------------------------------------------------- */ #include "relay_tx_api.h" - #include "wake_on_radio.h" #include "wake_on_radio_ral.h" #include "radio_planner.h" - #include "relay_real.h" #include "lr1mac_core.h" #include "lr1mac_defs.h" #include "lr1mac_utilities.h" - #include "smtc_modem_hal_dbg_trace.h" #include "smtc_modem_api.h" #include "modem_event_utilities.h" #include "lorawan_api.h" #include "smtc_real.h" +#include "smtc_duty_cycle.h" /* * ----------------------------------------------------------------------------- @@ -84,7 +82,7 @@ typedef struct relay_tx_s uint32_t ref_timestamp_ms; // Estimated time when the relay performed CAD uint8_t ref_channel_idx; // Channel use - uint8_t ref_defaut_idx; // Index (0 or 1) of the default channel + uint8_t ref_default_idx; // Index (0 or 1) of the default channel wor_cad_periodicity_t ref_cad_period; // Real period used by relay (default is 1s) // Information about the last WOR frame @@ -92,7 +90,7 @@ typedef struct relay_tx_s uint32_t last_preamble_len_ms; // preamble length in ms uint32_t last_timestamp_ms; // Time of send uint8_t last_ch_idx; // Channel used (default or additionnal) - uint8_t last_defaut_idx; // Index (0 or 1) of the default channel + uint8_t last_default_idx; // Index (0 or 1) of the default channel uint8_t relay_xtal_drift_ppm; // xtal drift of the relay uint8_t relay_cad_to_rx; // Delay for a relay to switch from CAD to RX @@ -106,17 +104,20 @@ typedef struct relay_tx_s uint8_t backoff_cnt; // Number of WOR without valid WOR ACK uint8_t lr1_payload_len; - bool last_ack_valid; - wor_ack_infos_t last_ack; - bool need_key_derivation; - relay_tx_config_t relay_tx_config; + bool last_ack_valid; + wor_ack_infos_t last_ack; + bool need_key_derivation; + relay_tx_config_t relay_tx_config; + wor_ack_mic_info_t ack_mic_info; + + uint32_t target_timer_lr1; } relay_tx_t; /* *----------------------------------------------------------------------------------- *--- PRIVATE VARIABLES ------------------------------------------------------------- */ -static relay_tx_t relay_tx_declare[NUMBER_OF_STACKS] = { 0 }; +static relay_tx_t relay_tx_declare[NUMBER_OF_STACKS]; /* *----------------------------------------------------------------------------------- @@ -163,10 +164,8 @@ bool smtc_relay_tx_init( uint8_t relay_stack_id, radio_planner_t* rp, smtc_real_ void ( *busy_callback )( void* busy_context ), void* busy_context, void ( *abort_callback )( void* abort_context ), void* abort_context ) { - relay_tx_t* relay_tx_declare_temp = &( relay_tx_declare[relay_stack_id] ); - memset( relay_tx_declare_temp, 0, sizeof( relay_tx_t ) ); - relay_tx_t* infos = &( relay_tx_declare[relay_stack_id] ); + memset( infos, 0, sizeof( relay_tx_t ) ); if( ( free_callback == NULL ) || ( abort_callback == NULL ) ) { @@ -194,7 +193,7 @@ bool smtc_relay_tx_init( uint8_t relay_stack_id, radio_planner_t* rp, smtc_real_ infos->relay_cad_to_rx = DEFAULT_CAD_TO_RX; infos->ref_cad_period = DEFAULT_CAD_PERIOD; infos->activation_mode = DEFAULT_ACTIVATION_MODE; - infos->last_defaut_idx = 1; + infos->last_default_idx = 1; memset( &( infos->relay_tx_config ), 0, sizeof( relay_tx_config_t ) ); infos->relay_tx_config.second_ch_enable = false; @@ -283,7 +282,6 @@ bool smtc_relay_tx_update_config( uint8_t relay_stack_id, const relay_tx_config_ uint8_t temp_number_of_miss_wor_ack_to_switch_in_nosync_mode = 8; if( relay_config->activation == RELAY_TX_ACTIVATION_MODE_ED_CONTROLED ) { - temp_number_of_miss_wor_ack_to_switch_in_nosync_mode = infos->relay_tx_config.number_of_miss_wor_ack_to_switch_in_nosync_mode; } @@ -344,16 +342,12 @@ bool smtc_relay_tx_prepare_wor( uint8_t relay_stack_id, uint32_t target_time, co infos->last_ch_idx = 0; if( infos->sync_status == RELAY_TX_SYNC_STATUS_INIT ) { - // Manage the 2 value of the default channel - infos->last_defaut_idx = ( infos->last_defaut_idx == 0 ? 1 : 0 ); + // Manage the 2 values of the default channel + infos->last_default_idx = ( infos->last_default_idx == 0 ? 1 : 0 ); - if( smtc_relay_get_default_channel_config( infos->real, infos->last_defaut_idx, &infos->default_ch_config.dr, - &infos->default_ch_config.freq_hz, - &infos->default_ch_config.ack_freq_hz ) == ERRORLORAWAN ) - { - // no more duty cycle - return false; - } + smtc_relay_get_default_channel_config( infos->real, infos->last_default_idx, &infos->default_ch_config.dr, + &infos->default_ch_config.freq_hz, + &infos->default_ch_config.ack_freq_hz ); } else { @@ -365,17 +359,19 @@ bool smtc_relay_tx_prepare_wor( uint8_t relay_stack_id, uint32_t target_time, co // If last channel used was the default -> remove half cad period ref_timestamp -= cad_period_ms >> 1; } - } - else - { - if( smtc_relay_get_default_channel_config( infos->real, infos->last_defaut_idx, - &infos->default_ch_config.dr, &infos->default_ch_config.freq_hz, - &infos->default_ch_config.ack_freq_hz ) == ERRORLORAWAN ) + smtc_duty_cycle_update( ); + if( smtc_duty_cycle_is_channel_free( infos->relay_tx_config.second_ch.freq_hz) == false ) { - // no more duty cycle + SMTC_MODEM_HAL_TRACE_PRINTF( "no more duty cycle for second_ch wor channel\n" ); return false; } } + else + { + smtc_relay_get_default_channel_config( infos->real, infos->last_default_idx, &infos->default_ch_config.dr, + &infos->default_ch_config.freq_hz, + &infos->default_ch_config.ack_freq_hz ); + } } // ----------------------------------------------------------------- @@ -430,6 +426,9 @@ bool smtc_relay_tx_prepare_wor( uint8_t relay_stack_id, uint32_t target_time, co .rf_infos.freq_hz = conf->freq_hz, .rf_infos.dr = conf->dr, }; + // store wor frequency and wor datarate for future mic wor_ack computation + infos->ack_mic_info.wor_frequency_hz = wor.uplink.freq_hz; + infos->ack_mic_info.wor_datarate = wor.uplink.dr; infos->buffer_len = wor_generate_wor( infos->buffer, &wor ); } @@ -576,6 +575,19 @@ void smtc_relay_tx_data_receive_on_rxr( uint8_t relay_stack_id ) } } +int32_t smtc_relay_tx_free_duty_cycle_ms_get( uint8_t relay_stack_id ) +{ + relay_tx_t* infos = &( relay_tx_declare[relay_stack_id] ); + uint32_t tx_freq_list = infos->default_ch_config.freq_hz; + if( infos->relay_tx_config.second_ch_enable == true ) + { + tx_freq_list = infos->relay_tx_config.second_ch.freq_hz; + } + int32_t relay_tx_duty_cycle = + smtc_relay_tx_is_enable( relay_stack_id ) ? smtc_duty_cycle_get_next_free_time_ms( 1, &tx_freq_list ) : 0; + SMTC_MODEM_HAL_TRACE_PRINTF_DEBUG( "relay_tx_duty_cycle = %d\n", relay_tx_duty_cycle ); + return ( relay_tx_duty_cycle ); +} /* *----------------------------------------------------------------------------------- *--- PRIVATE FUNCTIONS DEFINITIONS ------------------------------------------------- @@ -596,17 +608,13 @@ static bool relay_tx_check_decode_ack( uint8_t relay_stack_id, wor_ack_infos_t* const relay_tx_channel_config_t* conf = ( infos->last_ch_idx == 0 ) ? &infos->default_ch_config : &( infos->relay_tx_config.second_ch ); - wor_ack_mic_info_t ack_mic_info = { - .dev_addr = lorawan_api_devaddr_get( relay_stack_id ), - .wfcnt = infos->fcnt, - .frequency_hz = conf->freq_hz, - .datarate = conf->dr, - }; + infos->ack_mic_info.dev_addr = lorawan_api_devaddr_get( relay_stack_id ); + infos->ack_mic_info.wfcnt = infos->fcnt; // SMTC_MODEM_HAL_TRACE_PRINTF( "frequency_hz = %d, infos->last_ch_idx = %d , .dev_addr = %x, datarate = %d\n", // conf->ack_freq_hz,infos->last_ch_idx,lorawan_api_devaddr_get( relay_stack_id ),conf->dr); // Key is set to NULL because it is already save in the crypto element (soft or hard) - const uint32_t mic_calc = wor_compute_mic_ack( &ack_mic_info, infos->buffer, NULL ); + const uint32_t mic_calc = wor_compute_mic_ack( &( infos->ack_mic_info ), infos->buffer, NULL ); const uint32_t mic_receive = wor_extract_mic_ack( infos->buffer ); if( mic_calc != mic_receive ) @@ -616,21 +624,20 @@ static bool relay_tx_check_decode_ack( uint8_t relay_stack_id, wor_ack_infos_t* return false; } - ack_mic_info.frequency_hz = conf->ack_freq_hz; - - wor_decrypt_ack( infos->buffer, &ack_mic_info, ack, NULL ); + infos->ack_mic_info.frequency_hz = conf->ack_freq_hz; + infos->ack_mic_info.datarate = conf->dr; + wor_decrypt_ack( infos->buffer, &( infos->ack_mic_info ), ack, NULL ); return true; } static void relay_tx_callback_rp( uint8_t* stack_id ) { - rp_status_t rp_status; - uint32_t timestamp_irq; - static uint32_t target_timer_lr1 = 0; - bool has_to_send_data = false; - bool cancel_lr1mac_process = false; - const uint8_t relay_stack_id = *stack_id; - relay_tx_t* infos = &( relay_tx_declare[relay_stack_id] ); + rp_status_t rp_status; + uint32_t timestamp_irq; + bool has_to_send_data = false; + bool cancel_lr1mac_process = false; + const uint8_t relay_stack_id = *stack_id; + relay_tx_t* infos = &( relay_tx_declare[relay_stack_id] ); rp_get_status( infos->rp, RP_HOOK_ID_RELAY_TX + relay_stack_id, ×tamp_irq, &rp_status ); @@ -675,7 +682,7 @@ static void relay_tx_callback_rp( uint8_t* stack_id ) has_to_send_data = true; } } - target_timer_lr1 = + infos->target_timer_lr1 = infos->time_tx_done + infos->toa_ack[infos->last_ch_idx] + DELAY_WOR_TO_WORACK_MS + DELAY_WORACK_TO_UPLINK_MS; // don't add "- smtc_modem_hal_get_radio_tcxo_startup_delay_ms( )" due to // the fact that lr1mac do it by itself- @@ -685,9 +692,10 @@ static void relay_tx_callback_rp( uint8_t* stack_id ) { // WOR join Req has been send, send uplink has_to_send_data = true; - target_timer_lr1 = timestamp_irq + - DELAY_WOR_TO_JOINREQ_MS; // don't add "- smtc_modem_hal_get_radio_tcxo_startup_delay_ms( - // )" due to the fact that lr1mac do it by itself + infos->target_timer_lr1 = + timestamp_irq + + DELAY_WOR_TO_JOINREQ_MS; // don't add "- smtc_modem_hal_get_radio_tcxo_startup_delay_ms( + // )" due to the fact that lr1mac do it by itself } break; } @@ -720,7 +728,7 @@ static void relay_tx_callback_rp( uint8_t* stack_id ) relay_tx_update_sync_status( relay_stack_id, RELAY_TX_SYNC_STATUS_SYNC ); infos->ref_cad_period = ack.period; infos->ref_channel_idx = infos->last_ch_idx; - infos->ref_defaut_idx = infos->last_defaut_idx; + infos->ref_default_idx = infos->last_default_idx; infos->relay_xtal_drift_ppm = wor_convert_ppm( ack.relay_ppm ); infos->relay_cad_to_rx = wor_convert_cadtorx( ack.cad_to_rx ); @@ -797,7 +805,7 @@ static void relay_tx_callback_rp( uint8_t* stack_id ) { cb_return_param_t cb_param = { .abort = false, - .lr1_timing = target_timer_lr1, + .lr1_timing = infos->target_timer_lr1, .stack_id = relay_stack_id, }; @@ -820,9 +828,9 @@ static void relay_tx_update_sync_status( uint8_t relay_stack_id, relay_tx_sync_s static void relay_tx_print_conf( uint8_t relay_stack_id ) { relay_tx_t* infos = &( relay_tx_declare[relay_stack_id] ); - +#if( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) const char* name_activation[] = { "DISABLED", "ENABLE", "DYNAMIC", "ED_CONTROLED" }; - +#endif SMTC_MODEM_HAL_TRACE_PRINTF( "\n------------------------------\n" ); SMTC_MODEM_HAL_TRACE_PRINTF( "END DEVICE RELAY CONFIGURATION\n" ); SMTC_MODEM_HAL_TRACE_PRINTF( "Activation : %s\n", name_activation[infos->relay_tx_config.activation] ); diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx_api.h b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx_api.h index 901244f..138b156 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx_api.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx_api.h @@ -220,6 +220,12 @@ uint32_t smtc_relay_tx_get_crystal_error( uint8_t relay_stack_id ); */ void smtc_relay_tx_data_receive_on_rxr( uint8_t relay_stack_id ); +/** + * @brief return the relay duty cycle consumption in ms + * + * @param[in] relay_stack_id relay stack id +*/ +int32_t smtc_relay_tx_free_duty_cycle_ms_get( uint8_t relay_stack_id ); #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx_mac_parser.c b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx_mac_parser.c index c24c9cf..21e80e0 100755 --- a/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx_mac_parser.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/relay/relay_tx/relay_tx_mac_parser.c @@ -94,9 +94,9 @@ const relay_cid_info_t relay_tx_cid_infos[] = { }, }; -const uint8_t nb_relay_mac_cmd = ( sizeof( relay_tx_cid_infos ) / sizeof( relay_cid_info_t ) ); -const uint16_t ack_offset_khz[] = { 0, 200, 400, 800, 1600, 3200 }; -const char* ack_offset_khz_str[] = { "0 kHz", "2 kHz", "4 kHz", "8 kHz", "16 kHz", "32 kHz" }; +const uint8_t nb_relay_mac_cmd_relay_tx = ( sizeof( relay_tx_cid_infos ) / sizeof( relay_cid_info_t ) ); +const uint16_t ack_offset_khz_realy_tx[] = { 0, 200, 400, 800, 1600, 3200 }; + /* *----------------------------------------------------------------------------------- @@ -105,7 +105,7 @@ const char* ack_offset_khz_str[] = { "0 kHz", "2 kHz", "4 kHz", "8 kHz", "16 bool relay_tx_mac_parser( lr1_stack_mac_t* lr1_mac ) { - return relay_mac_parser( lr1_mac, relay_tx_cid_infos, nb_relay_mac_cmd ); + return relay_mac_parser( lr1_mac, relay_tx_cid_infos, nb_relay_mac_cmd_relay_tx ); } /* @@ -167,7 +167,7 @@ static bool relay_tx_mac_update_config_ed_parser( lr1_stack_mac_t* lr1_mac, rela } else { - config.second_ch.ack_freq_hz = config.second_ch.freq_hz + ack_offset_khz[ack_offset_khz_idx] * 1000; + config.second_ch.ack_freq_hz = config.second_ch.freq_hz + ack_offset_khz_realy_tx[ack_offset_khz_idx] * 1000; SMTC_MODEM_HAL_TRACE_PRINTF( "Second channel ACK freq: %d Hz\n", config.second_ch.ack_freq_hz ); if( smtc_real_is_frequency_valid( lr1_mac->real, config.second_ch.ack_freq_hz ) != OKLORAWAN ) diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_duty_cycle.h b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_duty_cycle.h index e97c7d8..7688748 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_duty_cycle.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_duty_cycle.h @@ -55,7 +55,7 @@ extern "C" { * ----------------------------------------------------------------------------- * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define SMTC_DTC_BANDS_MAX ( 6 ) // Number of ETSI band supported by this algo #define SMTC_DTC_PERIOD_MS ( 3600000UL ) // Number of miliseconds in one period (3600000 for period 1h) #define SMTC_DTC_SECONDS_BY_UNIT ( 120 ) // Sum TOA by step of N seconds, MIN VALUE IS 60s to avoid division by 0 @@ -75,7 +75,7 @@ extern "C" { // RTC 0s 120s 240s 360s 3360s 3480s 3600s // -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_lora_cad_bt.c b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_lora_cad_bt.c index 9e7a4e7..47047d4 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_lora_cad_bt.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_lora_cad_bt.c @@ -100,15 +100,18 @@ * --- PRIVATE VARIABLES ------------------------------------------------------- */ +static smtc_lora_cad_bt_t cad_obj_declare[NUMBER_OF_STACKS]; + /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ -static void smtc_cad_bt_launch_radio_callback_for_rp( void* rp_void ); -static void smtc_lora_cad_bt_rp_callback( smtc_lora_cad_bt_t* cad_obj ); -static void smtc_lora_cad_bt_reset_to_difs_phase( smtc_lora_cad_bt_t* cad_obj ); -static void smtc_lora_cad_bt_channel_is_free( smtc_lora_cad_bt_t* cad_obj ); -static smtc_lora_cad_bt_t cad_obj_declare[NUMBER_OF_STACKS]; +static void smtc_cad_bt_launch_radio_callback_for_rp( void* rp_void ); +static void smtc_lora_cad_bt_rp_callback( smtc_lora_cad_bt_t* cad_obj ); +static void smtc_lora_cad_bt_reset_to_difs_phase( smtc_lora_cad_bt_t* cad_obj ); +static void smtc_lora_cad_bt_channel_is_free( smtc_lora_cad_bt_t* cad_obj ); +static uint32_t smtc_lora_cad_bt_get_symbol_duration_us( ral_lora_bw_t bw, ral_lora_sf_t sf ); + /* * ----------------------------------------------------------------------------- * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- @@ -154,8 +157,8 @@ void smtc_lora_cad_bt_init( smtc_lora_cad_bt_t* cad_obj, radio_planner_t* rp, ui rp_hook_init( rp, cad_id_rp, ( void ( * )( void* ) )( smtc_lora_cad_bt_rp_callback ), cad_obj ); } -smtc_lora_cad_status_t smtc_lora_cad_bt_set_parameters( smtc_lora_cad_bt_t* cad_obj, uint8_t nb_bo_max, bool bo_enabled, - uint8_t max_ch_change ) +smtc_lora_cad_status_t smtc_lora_cad_bt_set_parameters( smtc_lora_cad_bt_t* cad_obj, uint8_t max_ch_change, + bool bo_enabled, uint8_t nb_bo_max ) { if( ( max_ch_change > 0 ) && ( max_ch_change <= MAX_CH_CHANGES ) ) { @@ -198,10 +201,9 @@ bool smtc_lora_cad_bt_get_state( smtc_lora_cad_bt_t* cad_obj ) return cad_obj->enabled; } -void smtc_lora_cad_bt_listen_channel( smtc_lora_cad_bt_t* cad_obj, uint32_t freq_hz, uint8_t sf, +void smtc_lora_cad_bt_listen_channel( smtc_lora_cad_bt_t* cad_obj, uint32_t freq_hz, ral_lora_sf_t sf, ral_lora_bw_t bandwidth, bool is_at_time, uint32_t target_time_ms, - uint32_t symbol_duration_us, uint32_t tx_duration_ms, - uint8_t nb_available_channel, bool invert_iq_is_on ) + uint32_t tx_duration_ms, uint8_t nb_available_channel, bool invert_iq_is_on ) { // SMTC_MODEM_HAL_TRACE_PRINTF( "smtc_lora_cad_bt_listen_channel\n" ); if( cad_obj->is_cad_running == true ) @@ -221,6 +223,8 @@ void smtc_lora_cad_bt_listen_channel( smtc_lora_cad_bt_t* cad_obj, uint32_t freq rp_task_t rp_task = { 0 }; uint32_t listen_duration_ms = 0; + uint32_t symbol_duration_us = smtc_lora_cad_bt_get_symbol_duration_us( bandwidth, sf ); + cad_obj->max_ch_change_cnt = MIN( cad_obj->max_ch_change_cnt, nb_available_channel ); // If the BO is enabled and we are in the first step of the diagram, set the random nb_bo @@ -356,6 +360,11 @@ static void smtc_cad_bt_launch_radio_callback_for_rp( void* rp_void ) SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_dio_irq_params( &( rp->radio->ral ), RAL_IRQ_CAD_DONE | RAL_IRQ_CAD_OK ) == RAL_STATUS_OK ); + // Wait the exact expected time (ie target - tcxo startup delay) + while( ( int32_t ) ( rp->tasks[id].start_time_ms - smtc_modem_hal_get_time_in_ms( ) ) > 0 ) + { + // Do nothing + } smtc_modem_hal_start_radio_tcxo( ); SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_lora_cad( &( rp->radio->ral ) ) == RAL_STATUS_OK ); @@ -448,4 +457,58 @@ static void smtc_lora_cad_bt_channel_is_free( smtc_lora_cad_bt_t* cad_obj ) smtc_lora_cad_bt_reset_to_difs_phase( cad_obj ); } +static uint32_t smtc_lora_cad_bt_get_symbol_duration_us( ral_lora_bw_t bw, ral_lora_sf_t sf ) +{ + uint32_t bw_temp = 125; // temporary variable to store the bandwidth + switch( bw ) + { + case RAL_LORA_BW_007_KHZ: + bw_temp = 7; + break; + case RAL_LORA_BW_010_KHZ: + bw_temp = 10; + break; + case RAL_LORA_BW_015_KHZ: + bw_temp = 15; + break; + case RAL_LORA_BW_020_KHZ: + bw_temp = 20; + break; + case RAL_LORA_BW_031_KHZ: + bw_temp = 31; + break; + case RAL_LORA_BW_041_KHZ: + bw_temp = 41; + break; + case RAL_LORA_BW_062_KHZ: + bw_temp = 62; + break; + case RAL_LORA_BW_125_KHZ: + bw_temp = 125; + break; + case RAL_LORA_BW_200_KHZ: + bw_temp = 200; + break; + case RAL_LORA_BW_250_KHZ: + bw_temp = 250; + break; + case RAL_LORA_BW_400_KHZ: + bw_temp = 400; + break; + case RAL_LORA_BW_500_KHZ: + bw_temp = 500; + break; + case RAL_LORA_BW_800_KHZ: + bw_temp = 800; + break; + case RAL_LORA_BW_1600_KHZ: + bw_temp = 1600; + break; + default: + SMTC_MODEM_HAL_PANIC( " invalid BW " ); + break; + } + return ( ( ( uint32_t ) ( ( 1 << sf ) * 1000 ) / bw_temp ) ); +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_lora_cad_bt.h b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_lora_cad_bt.h index 0e414b1..1b7fab1 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_lora_cad_bt.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_lora_cad_bt.h @@ -82,13 +82,13 @@ typedef struct smtc_lora_cad_bt_s bool is_at_time; /* Callback */ - void ( *ch_free_callback )( void* ); + void ( *ch_free_callback )( void* ); void* ch_free_context; - void ( *ch_busy_callback_update_channel )( void* ); + void ( *ch_busy_callback_update_channel )( void* ); void* ch_busy_context_update_channel; - void ( *ch_free_callback_on_back_off )( void* ); + void ( *ch_free_callback_on_back_off )( void* ); void* ch_free_context_on_back_off; - void ( *abort_callback )( void* ); + void ( *abort_callback )( void* ); void* abort_context; /* data */ @@ -126,9 +126,9 @@ typedef struct smtc_lora_cad_bt_s */ void smtc_lora_cad_bt_init( smtc_lora_cad_bt_t* cad_obj, radio_planner_t* rp, uint8_t cad_id_rp, void ( *ch_free_callback )( void* ch_free_context ), void* ch_free_context, - void ( *ch_busy_callback_update_channel )( void* ch_busy_context_update_channel ), + void ( *ch_busy_callback_update_channel )( void* ch_busy_context_update_channel ), void* ch_busy_context_update_channel, - void ( *ch_free_callback_on_back_off )( void* ch_free_context_on_back_off ), + void ( *ch_free_callback_on_back_off )( void* ch_free_context_on_back_off ), void* ch_free_context_on_back_off, void ( *abort_callback )( void* abort_context ), void* abort_context ); @@ -141,8 +141,8 @@ void smtc_lora_cad_bt_init( smtc_lora_cad_bt_t* cad_obj, radio_planner_t* rp, ui * @param [in] nb_bo_max Set the number max of multiple little CAD * @return smtc_lora_cad_status_t */ -smtc_lora_cad_status_t smtc_lora_cad_bt_set_parameters( smtc_lora_cad_bt_t* cad_obj, uint8_t nb_bo_max, bool bo_enabled, - uint8_t max_ch_change ); +smtc_lora_cad_status_t smtc_lora_cad_bt_set_parameters( smtc_lora_cad_bt_t* cad_obj, uint8_t max_ch_change, + bool bo_enabled, uint8_t nb_bo_max ); /** * @brief Get the configured LoRa CAD parameters @@ -178,30 +178,27 @@ bool smtc_lora_cad_bt_get_state( smtc_lora_cad_bt_t* cad_obj ); * * @param cad_obj pointer to cad_obj itself * @param freq_hz targeted listen frequency in hertz - * @param sf targeted listen spreading factor - * @param bandwidth targeted listen bandwidth + * @param sf targeted listen spreading factor (ral_lora_sf_t) + * @param bandwidth targeted listen bandwidth (ral_lora_bw_t) * @param is_at_time is a listen at time or asap * @param target_time_ms time to start the listening - * @param symbol_duration_us duration of one symbols regarding ths SF and the bandwidth * @param tx_duration_ms duration of the transmission if channel is free ( allow to book the radio planer ) * @param nb_available_channel the number of available channels in region for max_change - * @param invert_iq_is_on target iq invert + * @param invert_iq_is_on target iq invert */ -void smtc_lora_cad_bt_listen_channel( smtc_lora_cad_bt_t* cad_obj, uint32_t freq_hz, uint8_t sf, +void smtc_lora_cad_bt_listen_channel( smtc_lora_cad_bt_t* cad_obj, uint32_t freq_hz, ral_lora_sf_t sf, ral_lora_bw_t bandwidth, bool is_at_time, uint32_t target_time_ms, - uint32_t symbol_duration_us, uint32_t tx_duration_ms, - uint8_t nb_available_channel, bool invert_iq_is_on ); + uint32_t tx_duration_ms, uint8_t nb_available_channel, bool invert_iq_is_on ); /** * @brief return the cad obj pointer with stack id as parameter * task * * @param stack_id stack_id - * @return smtc_lora_cad_bt_t object pointer + * @return smtc_lora_cad_bt_t object pointer */ smtc_lora_cad_bt_t* smtc_cad_get_obj( uint8_t stack_id ); - #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_multicast/smtc_multicast.c b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_multicast/smtc_multicast.c index 761418d..5fc21f0 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_multicast/smtc_multicast.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_multicast/smtc_multicast.c @@ -75,26 +75,34 @@ typedef struct smtc_multicast_key_s */ static const smtc_multicast_key_t smtc_mc_skey_tab[LR1MAC_MC_NUMBER_OF_SESSION] = { +#if LR1MAC_MC_NUMBER_OF_SESSION > 0 { .mc_key = SMTC_SE_MC_KEY_0, .mc_app_skey = SMTC_SE_MC_APP_S_KEY_0, .mc_ntw_skey = SMTC_SE_MC_NWK_S_KEY_0, }, +#endif +#if LR1MAC_MC_NUMBER_OF_SESSION > 1 { .mc_key = SMTC_SE_MC_KEY_1, .mc_app_skey = SMTC_SE_MC_APP_S_KEY_1, .mc_ntw_skey = SMTC_SE_MC_NWK_S_KEY_1, }, +#endif +#if LR1MAC_MC_NUMBER_OF_SESSION > 2 { .mc_key = SMTC_SE_MC_KEY_2, .mc_app_skey = SMTC_SE_MC_APP_S_KEY_2, .mc_ntw_skey = SMTC_SE_MC_NWK_S_KEY_2, }, +#endif +#if LR1MAC_MC_NUMBER_OF_SESSION > 3 { .mc_key = SMTC_SE_MC_KEY_3, .mc_app_skey = SMTC_SE_MC_APP_S_KEY_3, .mc_ntw_skey = SMTC_SE_MC_NWK_S_KEY_3, }, +#endif }; /* diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_multicast/smtc_multicast.h b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_multicast/smtc_multicast.h index 6fe6d15..0ed47bf 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_multicast/smtc_multicast.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/services/smtc_multicast/smtc_multicast.h @@ -3,11 +3,12 @@ * * \brief Multicast implementation * - * Revised BSD License - * Copyright Semtech Corporation 2020. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,17 +18,20 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ + #ifndef __SMTC_MULTICAST_H__ #define __SMTC_MULTICAST_H__ @@ -55,10 +59,15 @@ extern "C" { * ----------------------------------------------------------------------------- * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off -#define LR1MAC_MC_NUMBER_OF_SESSION ( RX_SESSION_COUNT - 1 ) // Remove the unicast session +#if !defined( LR1MAC_MC_NUMBER_OF_SESSION ) +#define LR1MAC_MC_NUMBER_OF_SESSION 4 +#else +#if ( LR1MAC_MC_NUMBER_OF_SESSION > 4 ) +#error "LR1MAC_MC_NUMBER_OF_SESSION MAX is 4" +#endif +#endif + #define LR1MAC_MC_NO_DATARATE 0xFF -// clang-format on /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_as_923.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_as_923.c index 773f4f3..a12b52f 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_as_923.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_as_923.c @@ -298,11 +298,11 @@ status_channel_t region_as_923_build_channel_mask( smtc_real_t* real, uint8_t ch modulation_type_t region_as_923_get_modulation_type_from_datarate( uint8_t datarate ) { - if( datarate <= 6 ) + if( datarate <= DR6 ) { return LORA; } - else if( datarate == 7 ) + else if( datarate == DR7 ) { return FSK; } @@ -315,7 +315,7 @@ modulation_type_t region_as_923_get_modulation_type_from_datarate( uint8_t datar void region_as_923_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_bandwidth_t* out_bw ) { - if( in_dr <= 6 ) + if( in_dr <= DR6 ) { *out_sf = datarates_to_sf_as_923[in_dr]; *out_bw = datarates_to_bandwidths_as_923[in_dr]; @@ -328,7 +328,7 @@ void region_as_923_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_band void region_as_923_fsk_dr_to_bitrate( uint8_t in_dr, uint8_t* out_bitrate ) { - if( in_dr == 7 ) + if( in_dr == DR7 ) { *out_bitrate = 50; } diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_as_923_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_as_923_defs.h index 7f437eb..a2fa4f5 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_as_923_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_as_923_defs.h @@ -54,7 +54,7 @@ extern "C" { * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define NUMBER_OF_CHANNEL_AS_923 (16) #define NUMBER_OF_BOOT_TX_CHANNEL_AS_923 (2) // define the number of channel at boot #define JOIN_ACCEPT_DELAY1_AS_923 (5) // define in seconds @@ -104,7 +104,7 @@ extern "C" { #define BEACON_DR_AS_923 (3) #define PING_SLOT_FREQ_AS_923 (923400000) // Hz -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915_defs.h index 84af4fc..66a2a9c 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915_defs.h @@ -126,7 +126,7 @@ extern "C" { #define PING_SLOT_FREQ_START_AU_915 (923300000) // Hz #define PING_SLOT_STEP_AU_915 (600000) // Hz -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470.c index a7fdec0..b811435 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470.c @@ -531,7 +531,7 @@ modulation_type_t region_cn_470_get_modulation_type_from_datarate( uint8_t datar void region_cn_470_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_bandwidth_t* out_bw ) { - if( in_dr <= 6 ) + if( in_dr <= DR6 ) { *out_sf = datarates_to_sf_cn_470[in_dr]; *out_bw = datarates_to_bandwidths_cn_470[in_dr]; @@ -544,7 +544,7 @@ void region_cn_470_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_band void region_cn_470_fsk_dr_to_bitrate( uint8_t in_dr, uint8_t* out_bitrate ) { - if( in_dr == 7 ) + if( in_dr == DR7 ) { *out_bitrate = 50; // Kbit } diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_defs.h index 2c3ab91..b73ce57 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_defs.h @@ -162,7 +162,7 @@ extern uint32_t freq_tx_cn470_mono_channel_mhz; #define DEFAULT_TX_STEP_CN_470 (200000) // Hz #define DEFAULT_RX_STEP_CN_470 (200000) // Hz #endif -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0.c index 0b1185c..97c37f2 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0.c @@ -389,7 +389,7 @@ void region_cn_470_rp_1_0_enable_all_channels_with_valid_freq( smtc_real_t* real modulation_type_t region_cn_470_rp_1_0_get_modulation_type_from_datarate( uint8_t datarate ) { - if( datarate <= 5 ) + if( datarate <= DR5 ) { return LORA; } @@ -402,7 +402,7 @@ modulation_type_t region_cn_470_rp_1_0_get_modulation_type_from_datarate( uint8_ void region_cn_470_rp_1_0_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_bandwidth_t* out_bw ) { - if( in_dr <= 5 ) + if( in_dr <= DR5 ) { *out_sf = datarates_to_sf_cn_470_rp_1_0[in_dr]; *out_bw = datarates_to_bandwidths_cn_470_rp_1_0[in_dr]; diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0.h index 00e19f5..7a3cd57 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0.h @@ -85,13 +85,6 @@ void region_cn_470_rp_1_0_init( smtc_real_t* real ); * \param [OUT] return */ void region_cn_470_rp_1_0_config( smtc_real_t* real ); -/** - * \brief - * \remark - * \param [IN] none - * \param [OUT] return - */ -void region_cn_470_rp_1_0_init_session( smtc_real_t* real ); /** * \brief * \remark diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0_defs.h index 5fb12fc..0d3feb5 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_cn_470_rp_1_0_defs.h @@ -114,7 +114,7 @@ extern uint32_t freq_tx_cn470_mono_channel_mhz; #define BEACON_STEP_CN_470_RP_1_0 (200000) // Hz #define PING_SLOT_FREQ_START_CN_470_RP_1_0 (923300000) // Hz #define PING_SLOT_STEP_CN_470_RP_1_0 (200000) // Hz -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_eu_868_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_eu_868_defs.h index 5504ab9..ee299bf 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_eu_868_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_eu_868_defs.h @@ -54,7 +54,7 @@ extern "C" { * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define NUMBER_OF_CHANNEL_EU_868 (16) #define NUMBER_OF_BOOT_TX_CHANNEL_EU_868 (3) // define the number of channel at boot #define JOIN_ACCEPT_DELAY1_EU_868 (5) // define in seconds @@ -104,7 +104,7 @@ extern "C" { // LR-FHSS #define LR_FHSS_NA (0xFFFFFFFF) // LR-FHSS Not Applicable -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865.c index c7ecf6b..96141e8 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865.c @@ -171,12 +171,6 @@ void region_in_865_config( smtc_real_t* real ) memset( &unwrapped_channel_mask[0], 0xFF, BANK_MAX_IN865 ); } -void region_in_865_init_session( smtc_real_t* real ) -{ - // Not used for IN865 - return; -} - status_lorawan_t region_in_865_get_join_next_channel( smtc_real_t* real, uint8_t tx_data_rate, uint32_t* out_tx_frequency, uint32_t* out_rx1_frequency, uint8_t* active_channel_nb ) @@ -274,11 +268,11 @@ status_channel_t region_in_865_build_channel_mask( smtc_real_t* real, uint8_t ch modulation_type_t region_in_865_get_modulation_type_from_datarate( uint8_t datarate ) { - if( datarate <= 5 ) + if( datarate <= DR5 ) { return LORA; } - else if( datarate == 7 ) + else if( datarate == DR7 ) { return FSK; } @@ -291,7 +285,7 @@ modulation_type_t region_in_865_get_modulation_type_from_datarate( uint8_t datar void region_in_865_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_bandwidth_t* out_bw ) { - if( in_dr <= 5 ) + if( in_dr <= DR5 ) { *out_sf = datarates_to_sf_in_865[in_dr]; *out_bw = datarates_to_bandwidths_in_865[in_dr]; @@ -304,7 +298,7 @@ void region_in_865_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_band void region_in_865_fsk_dr_to_bitrate( uint8_t in_dr, uint8_t* out_bitrate ) { - if( in_dr == 7 ) + if( in_dr == DR7 ) { *out_bitrate = 50; // Kbit } diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865.h index 94772c0..3de891f 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865.h @@ -80,13 +80,6 @@ void region_in_865_init( smtc_real_t* real ); * \param [OUT] return */ void region_in_865_config( smtc_real_t* real ); -/** - * \brief - * \remark - * \param [IN] none - * \param [OUT] return - */ -void region_in_865_init_session( smtc_real_t* real ); /** * \brief * \remark diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865_defs.h index a05e30a..0432400 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_in_865_defs.h @@ -54,7 +54,7 @@ extern "C" { * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define NUMBER_OF_CHANNEL_IN_865 (16) #define NUMBER_OF_BOOT_TX_CHANNEL_IN_865 (3) // define the number of channel at boot #define JOIN_ACCEPT_DELAY1_IN_865 (5) // define in seconds @@ -95,7 +95,7 @@ extern "C" { #define BEACON_FREQ_IN_865 (866550000) // Hz #define PING_SLOT_FREQ_IN_865 (866550000) // Hz -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920.c index 72caff0..f98de41 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920.c @@ -174,12 +174,6 @@ void region_kr_920_config( smtc_real_t* real ) memset( &unwrapped_channel_mask[0], 0xFF, BANK_MAX_KR920 ); } -void region_kr_920_init_session( smtc_real_t* real ) -{ - // Not used for KR920 - return; -} - status_lorawan_t region_kr_920_get_join_next_channel( smtc_real_t* real, uint8_t tx_data_rate, uint32_t* out_tx_frequency, uint32_t* out_rx1_frequency, uint8_t* active_channel_nb ) @@ -288,7 +282,7 @@ status_channel_t region_kr_920_build_channel_mask( smtc_real_t* real, uint8_t ch modulation_type_t region_kr_920_get_modulation_type_from_datarate( uint8_t datarate ) { - if( datarate <= 5 ) + if( datarate <= DR5 ) { return LORA; } @@ -301,7 +295,7 @@ modulation_type_t region_kr_920_get_modulation_type_from_datarate( uint8_t datar void region_kr_920_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_bandwidth_t* out_bw ) { - if( in_dr <= 5 ) + if( in_dr <= DR5 ) { *out_sf = datarates_to_sf_kr_920[in_dr]; *out_bw = datarates_to_bandwidths_kr_920[in_dr]; diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920.h index 5affba8..711f061 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920.h @@ -80,13 +80,6 @@ void region_kr_920_init( smtc_real_t* real ); * \param [OUT] return */ void region_kr_920_config( smtc_real_t* real ); -/** - * \brief - * \remark - * \param [IN] none - * \param [OUT] return - */ -void region_kr_920_init_session( smtc_real_t* real ); /** * \brief * \remark diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920_defs.h index 6ce9516..1e99850 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_kr_920_defs.h @@ -54,7 +54,7 @@ extern "C" { * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define NUMBER_OF_CHANNEL_KR_920 (16) #define NUMBER_OF_BOOT_TX_CHANNEL_KR_920 (3) // define the number of channel at boot #define JOIN_ACCEPT_DELAY1_KR_920 (5) // define in seconds @@ -91,7 +91,7 @@ extern "C" { #define BEACON_DR_KR_920 (3) #define BEACON_FREQ_KR_920 (923100000) // Hz #define PING_SLOT_FREQ_KR_920 (923100000) // Hz -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ru_864.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ru_864.c index c81b193..2ce46be 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ru_864.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ru_864.c @@ -294,7 +294,7 @@ modulation_type_t region_ru_864_get_modulation_type_from_datarate( uint8_t datar void region_ru_864_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_bandwidth_t* out_bw ) { - if( in_dr <= 6 ) + if( in_dr <= DR6 ) { *out_sf = datarates_to_sf_ru_864[in_dr]; *out_bw = datarates_to_bandwidths_ru_864[in_dr]; @@ -307,7 +307,7 @@ void region_ru_864_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_band void region_ru_864_fsk_dr_to_bitrate( uint8_t in_dr, uint8_t* out_bitrate ) { - if( in_dr == 7 ) + if( in_dr == DR7 ) { *out_bitrate = 50; // Kbit } diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ru_864_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ru_864_defs.h index ccbf054..cebebd9 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ru_864_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ru_864_defs.h @@ -54,7 +54,7 @@ extern "C" { * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define NUMBER_OF_CHANNEL_RU_864 (16) #define NUMBER_OF_BOOT_TX_CHANNEL_RU_864 (2) // define the number of channel at boot #define JOIN_ACCEPT_DELAY1_RU_864 (5) // define in seconds @@ -92,7 +92,7 @@ extern "C" { #define BEACON_DR_RU_864 (3) #define BEACON_FREQ_RU_864 (869100000) // Hz #define PING_SLOT_FREQ_RU_864 (868900000) // Hz -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915_defs.h index 3ad428e..dab7b44 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915_defs.h @@ -126,7 +126,7 @@ extern "C" { // LR-FHSS #define LR_FHSS_NA (0xFFFFFFFF) // LR-FHSS Not Applicable -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ww2g4.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ww2g4.c index e271da4..3300315 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ww2g4.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ww2g4.c @@ -286,7 +286,7 @@ void region_ww2g4_enable_all_channels_with_valid_freq( smtc_real_t* real ) modulation_type_t region_ww2g4_get_modulation_type_from_datarate( uint8_t datarate ) { - if( datarate <= 7 ) + if( datarate <= DR7 ) { return LORA; } @@ -299,7 +299,7 @@ modulation_type_t region_ww2g4_get_modulation_type_from_datarate( uint8_t datara void region_ww2g4_lora_dr_to_sf_bw( uint8_t in_dr, uint8_t* out_sf, lr1mac_bandwidth_t* out_bw ) { - if( in_dr <= 7 ) + if( in_dr <= DR7 ) { *out_sf = datarates_to_sf_ww2g4[in_dr]; *out_bw = datarates_to_bandwidths_ww2g4[in_dr]; diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ww2g4_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ww2g4_defs.h index abac4e1..00b6bb1 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ww2g4_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_ww2g4_defs.h @@ -54,7 +54,7 @@ extern "C" { * --- PUBLIC MACROS ----------------------------------------------------------- */ -// clang-format off +/* clang-format off */ #define NUMBER_OF_CHANNEL_WW2G4 (16) #define NUMBER_OF_BOOT_TX_CHANNEL_WW2G4 (3) // define the number of channel at boot #define JOIN_ACCEPT_DELAY1_WW2G4 (5) // define in seconds @@ -90,7 +90,7 @@ extern "C" { #define BEACON_FREQ_WW2G4 (2424000000) // Hz #define PING_SLOT_FREQ_WW2G4 (2424000000) // Hz -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c index a54583a..f2fbe59 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real.c @@ -391,6 +391,7 @@ void smtc_real_set_dr_distribution( smtc_real_t* real, uint8_t adr_mode, uint8_t memcpy( dr_distribution_ctx, dr_distribution_init_ctx, real_const.const_number_of_tx_dr ); *out_nb_trans = BSP_USER_NUMBER_OF_RETRANSMISSION; break; + case JOIN_DR_DISTRIBUTION_LONG_TERM: default: memcpy( dr_distribution_init_ctx, real_const.const_default_dr_distri, real_const.const_number_of_tx_dr ); memcpy( dr_distribution_ctx, dr_distribution_init_ctx, real_const.const_number_of_tx_dr ); @@ -1240,14 +1241,10 @@ void smtc_real_enable_all_channels_with_valid_freq( smtc_real_t* real ) #if defined( REGION_WW2G4 ) || defined( REGION_EU_868 ) || defined( REGION_AS_923 ) || defined( REGION_IN_865 ) || \ defined( REGION_KR_920 ) || defined( REGION_RU_864 ) { - for( uint8_t i = 0; i < real_const.const_number_of_tx_channel; i++ ) + for( uint8_t i = 0; i < real_const.const_number_of_boot_tx_channel; i++ ) { - if( ( tx_frequency_channel_ctx[i] != 0 ) && - ( SMTC_GET_BIT8( channel_index_enabled_ctx, i ) == CHANNEL_DISABLED ) ) - { - SMTC_PUT_BIT8( channel_index_enabled_ctx, i, CHANNEL_ENABLED ); - dr_bitfield_tx_channel_ctx[i] = real_const.const_default_tx_dr_bit_field; - } + SMTC_PUT_BIT8( channel_index_enabled_ctx, i, CHANNEL_ENABLED ); + dr_bitfield_tx_channel_ctx[i] = real_const.const_default_tx_dr_bit_field; } break; } diff --git a/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_rx_service.c b/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_rx_service.c new file mode 100755 index 0000000..7c9518d --- /dev/null +++ b/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_rx_service.c @@ -0,0 +1,325 @@ +/** + * @file lorawan_relay_rx_service.c + * + * @brief Relay RX service, handle forward message, automatic start/stop of the relay, ... + * + * The Clear BSD License + * Copyright Semtech Corporation 2023. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ + +#include // C99 types +#include // bool type +#include "lorawan_relay_rx_service.h" +#include "modem_core.h" +#include "modem_supervisor_light.h" +#include "modem_event_utilities.h" +#include "lorawan_send_management.h" +#include "smtc_modem_hal.h" +#include "smtc_modem_api.h" +#include "smtc_modem_hal_dbg_trace.h" +#include "lorawan_api.h" + +#include "relay_rx_api.h" +#include "relay_def.h" +#include "relay_real.h" + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE MACROS----------------------------------------------------------- + */ +#define CURRENT_STACK ( task_id / NUMBER_OF_TASKS ) +#define NUMBER_MAX_OF_LORAWAN_RELAY_RX_OBJ 1 // modify in case of multiple obj + +/** + * @brief Check is the index is valid before accessing ALCSync object + * + */ +#define IS_VALID_OBJECT_ID( x ) \ + do \ + { \ + SMTC_MODEM_HAL_PANIC_ON_FAILURE( x < NUMBER_MAX_OF_LORAWAN_RELAY_RX_OBJ ); \ + } while( 0 ) + +/** + * @brief Check is the index is valid before accessing the object + * + */ +#define IS_VALID_STACK_ID( x ) \ + do \ + { \ + SMTC_MODEM_HAL_PANIC_ON_FAILURE( x < NUMBER_OF_STACKS ); \ + } while( 0 ) + +/** + * @brief Check is the service is initialized before accessing the object + * + */ +#define IS_SERVICE_INITIALIZED( ) \ + do \ + { \ + if( relay_rx_obj.initialized == false ) \ + { \ + SMTC_MODEM_HAL_TRACE_WARNING( "relay_rx_obj service not initialized\n" ); \ + return; \ + } \ + } while( 0 ) +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE CONSTANTS ------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE TYPES ----------------------------------------------------------- + */ +typedef enum service_fwd_e +{ + SERVICE_FWD_DONE, + SERVICE_FWD_FWD_JOIN, + SERVICE_FWD_FWD_UL, + SERVICE_FWD_EMPTY_UL, + SERVICE_FWD_DL, +} service_fwd_t; + +/** + * @brief LoRaWAN template Object + * + * @struct lorawan_relay_rx_s + * + */ +typedef struct lorawan_relay_rx_s +{ + uint8_t stack_id; + uint8_t task_id; + bool initialized; + uint8_t buffer[255]; + uint8_t buffer_len; + uint32_t time_to_tx; + service_fwd_t service_state; + bool relay_running_flag_prev; +} lorawan_relay_rx_t; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE VARIABLES ------------------------------------------------------- + */ +static lorawan_relay_rx_t relay_rx_obj = { 0 }; + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- + */ +/** + * @brief Callback called at task launch + * + * @param context_callback + */ +static void lorawan_relay_rx_service_on_launch( void* context ); + +/** + * @brief Callback called at the end of the task + * + * @param context_callback + */ +static void lorawan_relay_rx_service_on_update( void* context ); + +/** + * @brief Callback to handle the downlink received by the LoRaWAN layer + * + * @param rx_down_data + */ +static uint8_t lorawan_relay_rx_service_downlink_handler( lr1_stack_mac_down_data_t* rx_down_data ); + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- + */ +void lorawan_relay_rx_services_init( uint8_t* service_id, uint8_t task_id, + uint8_t ( **downlink_callback )( lr1_stack_mac_down_data_t* ), + void ( **on_lunch_callback )( void* ), void ( **on_update_callback )( void* ), + void** context_callback ) +{ + IS_VALID_OBJECT_ID( *service_id ); + *downlink_callback = lorawan_relay_rx_service_downlink_handler; + *on_lunch_callback = lorawan_relay_rx_service_on_launch; + *on_update_callback = lorawan_relay_rx_service_on_update; + *context_callback = ( void* ) service_id; + relay_rx_obj.task_id = task_id; + relay_rx_obj.stack_id = CURRENT_STACK; + relay_rx_obj.initialized = true; + relay_rx_obj.service_state = SERVICE_FWD_DONE; + relay_rx_obj.relay_running_flag_prev = false; + + SMTC_MODEM_HAL_TRACE_PRINTF( " lorawan_relay_rx_services_init task_id %d, service_id %d, CURRENT_STACK:%d \n", + task_id, *service_id, CURRENT_STACK ); + + lr1_stack_mac_t* lr1_ptr = lorawan_api_stack_mac_get( CURRENT_STACK ); + + const uint32_t ppm_error = lr1_stack_get_crystal_error( lr1_ptr ); + + wor_ack_ppm_error_t ppm_relay = WOR_ACK_PPM_ERROR_40PPM; + + if( ppm_error < 10 ) + { + ppm_relay = WOR_ACK_PPM_ERROR_10PPM; + } + else if( ppm_error < 20 ) + { + ppm_relay = WOR_ACK_PPM_ERROR_20PPM; + } + else if( ppm_error < 30 ) + { + ppm_relay = WOR_ACK_PPM_ERROR_30PPM; + } + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( relay_init( lr1_ptr, ppm_relay, WOR_ACK_CAD_TO_RX_8SYMB ) == true ); +} + +void lorawan_relay_rx_fwd_uplink( uint8_t stack_id, const uint8_t* data, uint8_t data_len, uint32_t time_tx, + bool is_join ) +{ + IS_VALID_STACK_ID( stack_id ); + IS_SERVICE_INITIALIZED( ); + + // SMTC_MODEM_HAL_TRACE_PRINTF( "Relay RX service add fwd ul task %d\n", smtc_modem_hal_get_time_in_ms( ) ); + smodem_task task_relay = { + .id = relay_rx_obj.task_id, + .stack_id = stack_id, + .priority = TASK_HIGH_PRIORITY, + .time_to_execute_s = smtc_modem_hal_get_time_in_s( ), + }; + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( modem_supervisor_add_task( &task_relay ) == TASK_VALID ); + + memcpy( relay_rx_obj.buffer, data, data_len ); + relay_rx_obj.buffer_len = data_len; + relay_rx_obj.time_to_tx = time_tx; + relay_rx_obj.service_state = ( is_join == true ) ? SERVICE_FWD_FWD_JOIN : SERVICE_FWD_FWD_UL; + relay_stop( true ); +} + +/* + * ----------------------------------------------------------------------------- + * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- + */ + +static void lorawan_relay_rx_service_on_launch( void* context ) +{ + // SMTC_MODEM_HAL_TRACE_PRINTF( "Relay RX service Launch %d\n", smtc_modem_hal_get_time_in_ms( ) ); + IS_SERVICE_INITIALIZED( ); + + if( ( relay_rx_obj.service_state == SERVICE_FWD_FWD_JOIN ) || ( relay_rx_obj.service_state == SERVICE_FWD_FWD_UL ) ) + { + lorawan_api_payload_send( FPORT_RELAY, true, relay_rx_obj.buffer, relay_rx_obj.buffer_len, UNCONF_DATA_UP, + relay_rx_obj.time_to_tx, RELAY_STACK_ID ); + // lorawan_api_payload_send_at_time( FPORT_RELAY, true, buffer, buffer_len, UNCONF_DATA_UP, time_to_tx, + // RELAY_STACK_ID ); + } + else if( relay_rx_obj.service_state == SERVICE_FWD_EMPTY_UL ) + { + lorawan_api_payload_send( 0, false, relay_rx_obj.buffer, 0, UNCONF_DATA_UP, + smtc_modem_hal_get_time_in_ms( ) + 300, RELAY_STACK_ID ); + } + else + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Relay RX Launch No action\n" ); + } +} + +static void lorawan_relay_rx_service_on_update( void* context ) +{ + IS_SERVICE_INITIALIZED( ); + // SMTC_MODEM_HAL_TRACE_PRINTF( "Relay RX service Update %d\n", smtc_modem_hal_get_time_in_ms( ) ); + + if( ( relay_rx_obj.service_state == SERVICE_FWD_FWD_JOIN ) || ( relay_rx_obj.service_state == SERVICE_FWD_FWD_UL ) ) + { + // No DL has been received, so no RXR windows, restart Relay CAD + // If a DL has been received relay_rx_obj.service_state is SERVICE_FWD_DONE and relay CAD will restarted after + // DL on RXR + relay_rx_obj.service_state = SERVICE_FWD_DONE; + relay_start( ); + } +} + +static uint8_t lorawan_relay_rx_service_downlink_handler( lr1_stack_mac_down_data_t* rx_down_data ) +{ + bool relay_running_flag = relay_rx_get_flag_started( ); + if( relay_rx_obj.relay_running_flag_prev != relay_running_flag ) + { + relay_rx_obj.relay_running_flag_prev = relay_running_flag; + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_RELAY_RX_RUNNING, relay_running_flag, + rx_down_data->stack_id ); + } + + // SMTC_MODEM_HAL_TRACE_PRINTF( "Relay RX service DL handler\n" ); + if( ( ( relay_rx_obj.service_state == SERVICE_FWD_FWD_JOIN ) || + ( relay_rx_obj.service_state == SERVICE_FWD_FWD_UL ) ) && + ( rx_down_data->rx_metadata.rx_fport_present == true ) && + ( rx_down_data->rx_metadata.rx_fport == FPORT_RELAY ) ) + { + relay_fwd_dl( rx_down_data->stack_id, rx_down_data->rx_payload, rx_down_data->rx_payload_size ); + + if( relay_rx_obj.service_state == SERVICE_FWD_FWD_JOIN ) + { + SMTC_MODEM_HAL_TRACE_PRINTF( "Join forwarded -> send empty uplink\n" ); + smodem_task task_relay = { + .id = relay_rx_obj.task_id, + .stack_id = rx_down_data->stack_id, + .priority = TASK_MEDIUM_HIGH_PRIORITY, + // The EmptyUplink must be send after the RxR window, + // relay_rx_obj.time_to_tx is timestamped on the rx_uplink+50ms, + // this downlink service is called after the timestamp + .time_to_execute_s = ( relay_rx_obj.time_to_tx + ( RXR_WINDOWS_DELAY_S + 1 ) * 1000UL ) / 1000UL, + }; + + if( modem_supervisor_add_task( &task_relay ) == TASK_VALID ) + { + relay_rx_obj.service_state = SERVICE_FWD_EMPTY_UL; + } + else + { + relay_rx_obj.service_state = SERVICE_FWD_DONE; + } + } + else + { + relay_rx_obj.service_state = SERVICE_FWD_DONE; + } + + return MODEM_DOWNLINK_CONSUMED; + } + + return MODEM_DOWNLINK_UNCONSUMED; +} + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_rx_service.h b/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_rx_service.h new file mode 100755 index 0000000..1bfcc4d --- /dev/null +++ b/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_rx_service.h @@ -0,0 +1,103 @@ +/** + * @file lorawan_relay_rx_service.h + * + * @brief lorawan_relay_rx_service + * + * The Clear BSD License + * Copyright Semtech Corporation 2023. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LORAWAN_RELAY_RX_SERVICE_H +#define LORAWAN_RELAY_RX_SERVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ----------------------------------------------------------------------------- + * --- DEPENDENCIES ------------------------------------------------------------ + */ + +#include // C99 types +#include // bool type +#include "lr1_stack_mac_layer.h" +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC MACROS ----------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC CONSTANTS -------------------------------------------------------- + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC TYPES ------------------------------------------------------------ + */ + +/* + * ----------------------------------------------------------------------------- + * --- PUBLIC FUNCTIONS PROTOTYPES --------------------------------------------- + */ + +/** + * @brief Init a the relay RX service + * + * @param[in] service_id Service ID (provided by supervisor) + * @param[in] task_id Task ID (provided by supervisor) + * @param[out] downlink_callback Callbak called after RX2 + * @param[out] on_lunch_callback Callback called to launched the service + * @param[out] on_update_callback Callback called when service has finished + * @param[out] context_callback Context for every callback + */ +void lorawan_relay_rx_services_init( uint8_t* service_id, uint8_t task_id, + uint8_t ( **downlink_callback )( lr1_stack_mac_down_data_t* ), + void ( **on_lunch_callback )( void* ), void ( **on_update_callback )( void* ), + void** context_callback ); + +/** + * @brief Relay has to forward a LoRaWAN Uplink + * + * @param[in] stack_id Stack ID to use + * @param[in] data Data to send + * @param[in] data_len Lenght of data + * @param[in] time_tx Timestamp to send the data + * @param[in] is_join True if the forwarded message is a Join Request + */ +void lorawan_relay_rx_fwd_uplink( uint8_t stack_id, const uint8_t* data, uint8_t data_len, uint32_t time_tx, + bool is_join ); + +#ifdef __cplusplus +} +#endif + +#endif // LORAWAN_RELAY_RX_SERVICE_H + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_tx_service.c b/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_tx_service.c index 69cf703..5e806a3 100755 --- a/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_tx_service.c +++ b/lbm_lib/smtc_modem_core/modem_services/relay_service/lorawan_relay_tx_service.c @@ -114,6 +114,7 @@ typedef struct lorawan_relay_tx_ctx_s uint8_t stack_id; uint8_t task_id; bool enabled; + uint8_t spare[62]; } lorawan_relay_tx_ctx_t; @@ -211,7 +212,7 @@ static uint8_t lorawan_relay_tx_service_downlink_handler( lr1_stack_mac_down_dat if( stack_id >= NUMBER_OF_RELAY_TX_PACKAGE_OBJ ) { - SMTC_MODEM_HAL_TRACE_ERROR( "stack id not valid %u \n", stack_id ); + SMTC_MODEM_HAL_TRACE_WARNING( "%s: stack id not valid %u \n", __func__, stack_id ); return MODEM_DOWNLINK_UNCONSUMED; } diff --git a/lbm_lib/smtc_modem_core/modem_services/service_template/service_template.c b/lbm_lib/smtc_modem_core/modem_services/service_template/service_template.c index 6a80976..c706cca 100644 --- a/lbm_lib/smtc_modem_core/modem_services/service_template/service_template.c +++ b/lbm_lib/smtc_modem_core/modem_services/service_template/service_template.c @@ -1,5 +1,5 @@ /** - * @file lorawan_template.c + * @file service_template.c * * @brief LoRaWAN Application Layer Clock Synchronization V1.0.0 Implementation * @@ -39,7 +39,7 @@ #include // C99 types #include // bool type -#include "lorawan_template.h" +#include "service_template.h" #include "modem_core.h" #include "modem_supervisor_light.h" #include "smtc_modem_api.h" diff --git a/lbm_lib/smtc_modem_core/modem_services/service_template/service_template.h b/lbm_lib/smtc_modem_core/modem_services/service_template/service_template.h index 247673b..8db8855 100644 --- a/lbm_lib/smtc_modem_core/modem_services/service_template/service_template.h +++ b/lbm_lib/smtc_modem_core/modem_services/service_template/service_template.h @@ -1,5 +1,5 @@ /** - * @file lorawan_template.h + * @file service_template.h * * @brief LoRaWAN template * The Clear BSD License diff --git a/lbm_lib/smtc_modem_core/modem_services/store_and_forward/store_and_forward_flash.c b/lbm_lib/smtc_modem_core/modem_services/store_and_forward/store_and_forward_flash.c index f921114..cd548a2 100644 --- a/lbm_lib/smtc_modem_core/modem_services/store_and_forward/store_and_forward_flash.c +++ b/lbm_lib/smtc_modem_core/modem_services/store_and_forward/store_and_forward_flash.c @@ -498,7 +498,7 @@ static void store_and_forward_flash_service_on_launch( void* service_id ) bool is_crc_ok = false; int32_t fetch_status = -1; - uint32_t rtc_ms = smtc_modem_hal_get_time_in_ms( ) ; + uint32_t rtc_ms = smtc_modem_hal_get_time_in_ms( ); // TODO check payload len and adjust the datarate with custom profile // uint8_t max_payload = lorawan_api_next_max_payload_length_get( stack_id ); @@ -573,8 +573,8 @@ static void store_and_forward_flash_service_on_launch( void* service_id ) } #endif - status_lorawan_t send_status = tx_protocol_manager_request (TX_PROTOCOL_TRANSMIT_LORA, - entry.fport, true, entry.data, entry.data_len, + status_lorawan_t send_status = tx_protocol_manager_request( + TX_PROTOCOL_TRANSMIT_LORA, entry.fport, true, entry.data, entry.data_len, ( store_and_forward_flash_obj[idx].sending_with_ack == true ) ? CONF_DATA_UP : UNCONF_DATA_UP, rtc_ms, stack_id ); @@ -726,12 +726,17 @@ static void store_and_forward_flash_add_task( store_and_forward_flash_t* ctx, ui static uint32_t store_and_forward_flash_compute_next_delay_s( store_and_forward_flash_t* ctx ) { // TODO implement the right algorithm to compute the delay between each retry to send the same packet not acked - uint32_t delay_s = ctx->sending_try_cpt * smtc_modem_hal_get_random_nb_in_range( 1, 5 ); + if( ctx->sending_try_cpt == 0 ) + { + return 0; + } + // Exponential backoff (2^sending_try_cpt * 60s) + uint32_t delay_s = ( 1 << ctx->sending_try_cpt ) * 60; if( delay_s > STORE_AND_FORWARD_DELAY_MAX_S ) { - delay_s = STORE_AND_FORWARD_DELAY_MAX_S + smtc_modem_hal_get_random_nb_in_range( 0, 60 ); + delay_s = STORE_AND_FORWARD_DELAY_MAX_S; } - return delay_s; + return delay_s + smtc_modem_hal_get_random_nb_in_range( 0, 60 ); } static int32_t op_sector_erase( struct circularfs_flash_partition* flash, uint32_t address ) diff --git a/lbm_lib/smtc_modem_core/modem_supervisor/modem_supervisor_light.c b/lbm_lib/smtc_modem_core/modem_supervisor/modem_supervisor_light.c index 4da16a3..8b24b78 100644 --- a/lbm_lib/smtc_modem_core/modem_supervisor/modem_supervisor_light.c +++ b/lbm_lib/smtc_modem_core/modem_supervisor/modem_supervisor_light.c @@ -109,18 +109,22 @@ struct stask_manager task_manager; void* supervisor_context_callback[NUMBER_OF_TASKS]; - void ( *supervisor_on_launch_func[NUMBER_OF_TASKS] )( void* ); - void ( *supervisor_on_update_func[NUMBER_OF_TASKS] )( void* ); + void ( *supervisor_on_launch_func[NUMBER_OF_TASKS] )( void* ); + void ( *supervisor_on_update_func[NUMBER_OF_TASKS] )( void* ); + + bool is_duty_cycle_constraint_enabled[NUMBER_OF_STACKS]; } modem_supervisor_context; -// clang-format off +/* clang-format off */ #define task_manager modem_supervisor_context.task_manager #define supervisor_context_callback modem_supervisor_context.supervisor_context_callback #define supervisor_on_launch_func modem_supervisor_context.supervisor_on_launch_func #define supervisor_on_update_func modem_supervisor_context.supervisor_on_update_func -// clang-format on +#define is_duty_cycle_constraint_enabled modem_supervisor_context.is_duty_cycle_constraint_enabled + +/* clang-format on */ /* * ----------------------------------------------------------------------------- @@ -162,6 +166,7 @@ void modem_supervisor_init( void ) for( uint8_t i = 0; i < NUMBER_OF_STACKS; i++ ) { task_manager.modem_mute_with_priority[i] = TASK_LOW_PRIORITY; + is_duty_cycle_constraint_enabled[i] = false; } modem_supervisor_init_callback( IDLE_TASK, supervisor_idle_task_on_launch, supervisor_idle_task_on_update, @@ -256,15 +261,14 @@ uint32_t modem_supervisor_engine( void ) { uint32_t sleep_time = 0; uint32_t sleep_time_alarm = 0; - sleep_time = tx_protocol_manager_is_busy (); - sleep_time_alarm = supervisor_check_user_alarm( ); + sleep_time = tx_protocol_manager_is_busy( ); + sleep_time_alarm = supervisor_check_user_alarm( ); if( sleep_time > 0 ) { sleep_time = MIN( sleep_time, sleep_time_alarm * 1000 ); return ( sleep_time ); - } - sleep_time = supervisor_run_lorawan_engine( STACK_ID_CURRENT_TASK ); - + } + sleep_time = supervisor_run_lorawan_engine( STACK_ID_CURRENT_TASK ); if( sleep_time > 0 ) { @@ -299,7 +303,7 @@ uint32_t modem_supervisor_engine( void ) task_manager.modem_task[task_manager.next_task_id].priority = TASK_FINISH; } uint32_t alarm = modem_get_user_alarm( ); - int32_t user_alarm_in_seconds = MODEM_MAX_ALARM_S / 1000; + int32_t user_alarm_in_seconds = MODEM_MAX_ALARM_S / 1000; if( alarm != 0 ) { user_alarm_in_seconds = ( int32_t ) ( alarm - smtc_modem_hal_get_time_in_s( ) ); @@ -368,7 +372,7 @@ static uint32_t supervisor_run_lorawan_engine( uint8_t stack_id ) if( lorawan_state == LWPSTATE_TX_WAIT ) { - tx_protocol_manager_lr1mac_stand_alone_tx (); + tx_protocol_manager_lr1mac_stand_alone_tx( ); sleep_time = ( LR1MAC_PERIOD_RETRANS_MS ); } else if( ( lorawan_state != LWPSTATE_IDLE ) && ( lorawan_state != LWPSTATE_ERROR ) ) @@ -396,6 +400,25 @@ static uint32_t supervisor_find_next_task( void ) { dtc_ms = dtc_ms_tmp; } + + // Generate event for duty-cycle busy + if( available_stack[i] == 0 ) + { + if( is_duty_cycle_constraint_enabled[i] == false ) + { + is_duty_cycle_constraint_enabled[i] = true; + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE, 1, i ); + } + } + // Generate event for duty-cycle free + else + { + if( is_duty_cycle_constraint_enabled[i] == true ) + { + is_duty_cycle_constraint_enabled[i] = false; + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE, 0, i ); + } + } } task_priority_t next_task_priority = TASK_FINISH; diff --git a/lbm_lib/smtc_modem_core/modem_supervisor/modem_tx_protocol_manager.c b/lbm_lib/smtc_modem_core/modem_supervisor/modem_tx_protocol_manager.c index a0d1851..a4cc2bd 100755 --- a/lbm_lib/smtc_modem_core/modem_supervisor/modem_tx_protocol_manager.c +++ b/lbm_lib/smtc_modem_core/modem_supervisor/modem_tx_protocol_manager.c @@ -54,8 +54,9 @@ #include "lr1mac_defs.h" #include "smtc_real.h" #include "smtc_lbt.h" +#include "smtc_modem_test.h" #include "smtc_lora_cad_bt.h" -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) #include "relay_tx_api.h" #include "relay_tx_mac_parser.h" #include "relay_def.h" @@ -67,7 +68,7 @@ */ typedef enum tx_protocol_manager_state { -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) TPM_STATE_PREPARE_WOR, //!< TPM_STATE_LBT_BEFORE_WOR, //!< #if defined( ADD_CSMA ) @@ -81,7 +82,8 @@ typedef enum tx_protocol_manager_state #endif TPM_STATE_TX_LORA, //!< TPM_STATE_NWK_TX_LORA, //!< - TPM_STATE_IDLE, //!< + TPM_STATE_TEST_MODE, + TPM_STATE_IDLE, //!< TPM_NUMBER_OF_STATE, } tx_protocol_manager_state_t; #define ENABLE_DEBUG_TPM 0 @@ -99,10 +101,11 @@ typedef enum tx_protocol_manager_state * --- PRIVATE MACROS ---------------------------------------------------------------- */ #define STACK_ID_CURRENT_TASK task_manager.modem_task[task_manager.next_task_id].stack_id -#define CURRENT_TASK_ID task_manager.next_task_id - ( NUMBER_OF_TASKS * STACK_ID_CURRENT_TASK ) +#define VIRTUAL_TASK_ID task_manager.next_task_id - ( NUMBER_OF_TASKS * STACK_ID_CURRENT_TASK ) #ifndef MODEM_MIN_RANDOM_DELAY_MS -#if defined( RELAY_TX ) -#define MODEM_MIN_RANDOM_DELAY_MS 3000 + +#if defined( ADD_RELAY_TX ) +#define MODEM_MIN_RANDOM_DELAY_MS ( smtc_relay_tx_is_enable( current_tpm_stack_id ) == false ) ? 500 : 3000 #else #define MODEM_MIN_RANDOM_DELAY_MS 500 #endif @@ -110,13 +113,30 @@ typedef enum tx_protocol_manager_state #ifndef MODEM_MAX_RANDOM_DELAY_MS #define MODEM_MAX_RANDOM_DELAY_MS 6000 #endif -#define MODEM_TASK_DELAY_MS \ - ( smtc_modem_hal_get_random_nb_in_range( MODEM_MIN_RANDOM_DELAY_MS, MODEM_MAX_RANDOM_DELAY_MS ) ) + +#if defined( ADD_RELAY_TX ) +#define MODEM_TASK_DELAY_MS \ + ( ( ( request_type == TX_PROTOCOL_TRANSMIT_TEST_MODE ) || \ + ( ( request_type == TX_PROTOCOL_TRANSMIT_LORA_CERTIFICATION ) && \ + ( smtc_relay_tx_is_enable( current_tpm_stack_id ) == false ) ) ) \ + ? 0 \ + : ( ( request_type == TX_PROTOCOL_TRANSMIT_LORA_CERTIFICATION ) && \ + ( smtc_relay_tx_is_enable( current_tpm_stack_id ) == true ) ) \ + ? 2000 \ + : ( smtc_modem_hal_get_random_nb_in_range( MODEM_MIN_RANDOM_DELAY_MS, MODEM_MAX_RANDOM_DELAY_MS ) ) ) +#else + +#define MODEM_TASK_DELAY_MS \ + ( ( ( request_type == TX_PROTOCOL_TRANSMIT_TEST_MODE ) || \ + ( request_type == TX_PROTOCOL_TRANSMIT_LORA_CERTIFICATION ) ) \ + ? 0 \ + : ( smtc_modem_hal_get_random_nb_in_range( MODEM_MIN_RANDOM_DELAY_MS, MODEM_MAX_RANDOM_DELAY_MS ) ) ) +#endif /* * ----------------------------------------------------------------------------- * --- PRIVATE VARIABLES ------------------------------------------------------- */ - +#define NB_REQUEST_ACCEPTED 5 static struct { tx_protocol_manager_tx_type_t current_tpm_request_type; @@ -135,13 +155,25 @@ static struct bool current_tpm_transmit_at_time; uint32_t current_tpm_target_transmit_at_time; uint8_t current_tpm_stack_id; - uint8_t current_tpm_cpt_lbt_max_trial; + uint32_t current_tpm_cpt_lbt_max_trial; uint8_t current_tpm_cpt_relay_max_trial; uint32_t current_tpm_target_time_csma_before_wor_ms; uint32_t current_tpm_target_time_lbt_before_wor_ms; bool current_tpm_transmit_is_aborted; uint32_t current_tpm_failsafe_time_init; + tx_protocol_manager_tx_type_t next_tpm_request_type[NB_REQUEST_ACCEPTED]; + tx_protocol_manager_state_t next_tpm_state[NB_REQUEST_ACCEPTED]; + uint8_t next_tpm_fport[NB_REQUEST_ACCEPTED]; + bool next_tpm_fport_enabled[NB_REQUEST_ACCEPTED]; + uint8_t* next_tpm_data[NB_REQUEST_ACCEPTED]; + uint8_t next_tpm_data_len[NB_REQUEST_ACCEPTED]; + lr1mac_layer_param_t next_tpm_packet_type[NB_REQUEST_ACCEPTED]; + uint32_t next_tpm_target_time_ms[NB_REQUEST_ACCEPTED]; + uint8_t next_tpm_stack_id[NB_REQUEST_ACCEPTED]; + bool next_tpm_stand_alone_stack_request[NB_REQUEST_ACCEPTED]; + uint8_t next_tpm_pending_request; + } modem_tpm_context; #define current_tpm_request_type modem_tpm_context.current_tpm_request_type @@ -165,6 +197,17 @@ static struct #define current_tpm_failsafe_time_init modem_tpm_context.current_tpm_failsafe_time_init #define current_tpm_add_delay_ms modem_tpm_context.current_tpm_add_delay_ms #define current_tpm_target_transmit_at_time modem_tpm_context.current_tpm_target_transmit_at_time +#define next_tpm_request_type modem_tpm_context.next_tpm_request_type +#define next_tpm_state modem_tpm_context.next_tpm_state +#define next_tpm_fport modem_tpm_context.next_tpm_fport +#define next_tpm_fport_enabled modem_tpm_context.next_tpm_fport_enabled +#define next_tpm_data modem_tpm_context.next_tpm_data +#define next_tpm_data_len modem_tpm_context.next_tpm_data_len +#define next_tpm_packet_type modem_tpm_context.next_tpm_packet_type +#define next_tpm_target_time_ms modem_tpm_context.next_tpm_target_time_ms +#define next_tpm_stack_id modem_tpm_context.next_tpm_stack_id +#define next_tpm_stand_alone_stack_request modem_tpm_context.next_tpm_stand_alone_stack_request +#define next_tpm_pending_request modem_tpm_context.next_tpm_pending_request /* * ----------------------------------------------------------------------------- @@ -178,6 +221,7 @@ static void compute_tpm_list( void ); static status_lorawan_t manage_tx_lora_state( void ); static status_lorawan_t manage_tx_nwk_lora_state( void ); static status_lorawan_t manage_idle_state( void ); +static status_lorawan_t manage_test_mode( void ); static status_lorawan_t manage_lbt_state( void ); static void modem_tpm_radio_busy_lbt( void* context ); static void modem_tpm_radio_free_lbt( void* context ); @@ -189,7 +233,7 @@ static void modem_tpm_radio_free_csma( void* context ); static void modem_tpm_radio_abort_csma( void* context ); static void modem_tpm_radio_free_cad_keep_channel( void* context ); #endif -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) static status_lorawan_t manage_relay_tx_state( void ); static status_lorawan_t manage_lbt_before_wor_state( void ); #if defined( ADD_CSMA ) @@ -210,10 +254,11 @@ static status_lorawan_t ( *launch_tpm_func[TPM_NUMBER_OF_STATE] )( void ) = { [TPM_STATE_NWK_TX_LORA] = &manage_tx_nwk_lora_state, [TPM_STATE_LBT] = &manage_lbt_state, [TPM_STATE_IDLE] = &manage_idle_state, + [TPM_STATE_TEST_MODE] = &manage_test_mode, #if defined( ADD_CSMA ) [TPM_STATE_CSMA] = &manage_csma_state, #endif -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) [TPM_STATE_RELAY_TX] = &manage_relay_tx_state, [TPM_STATE_LBT_BEFORE_WOR] = &manage_lbt_before_wor_state, #if defined( ADD_CSMA ) @@ -232,7 +277,7 @@ static status_lorawan_t ( *launch_tpm_func[TPM_NUMBER_OF_STATE] )( void ) = { * * @param rp pointer to the radioplanner object */ -void modem_tx_protcol_manager_init( radio_planner_t* rp ) +void modem_tx_protocol_manager_init( radio_planner_t* rp ) { memset( &modem_tpm_context, 0, sizeof( modem_tpm_context ) ); current_tpm_rp_target = rp; @@ -240,7 +285,7 @@ void modem_tx_protcol_manager_init( radio_planner_t* rp ) current_tpm_transmit_at_time = false; for( int i = 0; i < NUMBER_OF_STACKS; i++ ) { - smtc_lbt_init( smtc_lbt_get_obj( i ), current_tpm_rp_target, RP_HOOK_ID_LBT, + smtc_lbt_init( smtc_lbt_get_obj( i ), current_tpm_rp_target, RP_HOOK_ID_LBT + i, ( void ( * )( void* ) ) modem_tpm_radio_free_lbt, NULL, ( void ( * )( void* ) ) modem_tpm_radio_busy_lbt, NULL, ( void ( * )( void* ) ) modem_tpm_radio_abort_lbt, NULL ); @@ -254,7 +299,7 @@ void modem_tx_protcol_manager_init( radio_planner_t* rp ) } #if defined( ADD_CSMA ) - smtc_lora_cad_bt_init( smtc_cad_get_obj( i ), current_tpm_rp_target, RP_HOOK_ID_CAD, + smtc_lora_cad_bt_init( smtc_cad_get_obj( i ), current_tpm_rp_target, RP_HOOK_ID_CAD + i, ( void ( * )( void* ) ) modem_tpm_radio_free_csma, NULL, ( void ( * )( void* ) ) modem_tpm_radio_busy_csma, NULL, ( void ( * )( void* ) ) modem_tpm_radio_free_cad_keep_channel, NULL, @@ -263,7 +308,7 @@ void modem_tx_protcol_manager_init( radio_planner_t* rp ) smtc_lora_cad_bt_set_state( smtc_cad_get_obj( i ), true ); #endif #endif -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) smtc_relay_tx_init( i, current_tpm_rp_target, lorawan_api_stack_mac_get( i )->real, ( void ( * )( void* ) ) modem_tpm_radio_free_relay_tx, NULL, NULL, NULL, ( void ( * )( void* ) ) modem_tpm_radio_abort_relay_tx, NULL ); @@ -285,11 +330,12 @@ void modem_tx_protcol_manager_init( radio_planner_t* rp ) uint32_t tx_protocol_manager_is_busy( void ) { uint32_t time_to_sleep = READY_FOR_LR1MAC_TX; - if( ( tpm_list_of_state_to_execute[0] == TPM_STATE_LBT ) + if( ( tpm_list_of_state_to_execute[0] == TPM_STATE_LBT ) || + ( tpm_list_of_state_to_execute[0] == TPM_STATE_TEST_MODE ) #if defined( ADD_CSMA ) || ( tpm_list_of_state_to_execute[0] == TPM_STATE_CSMA ) #endif -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) || ( tpm_list_of_state_to_execute[0] == TPM_STATE_LBT_BEFORE_WOR ) || #if defined( ADD_CSMA ) ( tpm_list_of_state_to_execute[0] == TPM_STATE_CSMA_BEFORE_WOR ) || @@ -300,7 +346,31 @@ uint32_t tx_protocol_manager_is_busy( void ) ) { time_to_sleep = SLEEP_UNTIL_RADIO_INTERRUPT_MS; + if( ( ( int32_t ) ( smtc_modem_hal_get_time_in_s( ) - current_tpm_failsafe_time_init - FAILSAFE_TPM_S ) > 0 ) ) + { + tpm_abort( ); + time_to_sleep = 0; + } } + if( ( tpm_list_of_state_to_execute[0] == TPM_STATE_IDLE ) && ( next_tpm_pending_request > 0 ) && + ( next_tpm_pending_request <= NB_REQUEST_ACCEPTED ) ) + { + next_tpm_pending_request--; + if( next_tpm_stand_alone_stack_request[next_tpm_pending_request] == false ) + { + tx_protocol_manager_request( + next_tpm_request_type[next_tpm_pending_request], next_tpm_fport[next_tpm_pending_request], + next_tpm_fport_enabled[next_tpm_pending_request], next_tpm_data[next_tpm_pending_request], + next_tpm_data_len[next_tpm_pending_request], next_tpm_packet_type[next_tpm_pending_request], + next_tpm_target_time_ms[next_tpm_pending_request], next_tpm_stack_id[next_tpm_pending_request] ); + } + else + { + tx_protocol_manager_lr1mac_stand_alone_tx( ); + } + time_to_sleep = 0; + } + return time_to_sleep; } @@ -321,7 +391,26 @@ status_lorawan_t tx_protocol_manager_request( tx_protocol_manager_tx_type_t requ lr1mac_layer_param_t packet_type, uint32_t target_time_ms, uint8_t stack_id ) { - status_lorawan_t status = ERRORLORAWAN; + status_lorawan_t status = ERRORLORAWAN; + if( next_tpm_pending_request >= NB_REQUEST_ACCEPTED ) + { + return ERRORLORAWAN; + } + if( tpm_list_of_state_to_execute[0] != TPM_STATE_IDLE ) + { + next_tpm_request_type[next_tpm_pending_request] = request_type; + next_tpm_fport[next_tpm_pending_request] = fport; + next_tpm_target_time_ms[next_tpm_pending_request] = target_time_ms; + next_tpm_fport_enabled[next_tpm_pending_request] = fport_enabled; + next_tpm_data[next_tpm_pending_request] = ( uint8_t* ) data; + next_tpm_data_len[next_tpm_pending_request] = data_len; + next_tpm_packet_type[next_tpm_pending_request] = packet_type; + next_tpm_stack_id[next_tpm_pending_request] = stack_id; + next_tpm_stand_alone_stack_request[next_tpm_pending_request] = false; + next_tpm_pending_request++; + return OKLORAWAN; + } + current_tpm_failsafe_time_init = smtc_modem_hal_get_time_in_s( ); current_tpm_transaction_is_a_retransmit = false; current_tpm_transmit_is_aborted = false; @@ -374,7 +463,15 @@ status_lorawan_t tx_protocol_manager_request( tx_protocol_manager_tx_type_t requ */ void tx_protocol_manager_lr1mac_stand_alone_tx( void ) { - SMTC_MODEM_HAL_TRACE_PRINTF( "Lr1mac retransmission or Nwk Frame manage by TPM \n" ); + if( next_tpm_pending_request >= NB_REQUEST_ACCEPTED ) + { + return; + } + if( tpm_list_of_state_to_execute[0] != TPM_STATE_IDLE ) + { + next_tpm_stand_alone_stack_request[next_tpm_pending_request] = true; + return; + } current_tpm_transaction_is_a_retransmit = true; current_tpm_cpt_relay_max_trial = 0; current_tpm_cpt_lbt_max_trial = 0; @@ -507,11 +604,11 @@ static status_lorawan_t manage_tx_lora_state( void ) switch( current_tpm_request_type ) { case TX_PROTOCOL_JOIN_LORA: - status = lorawan_api_join( current_tpm_target_time_ms, current_tpm_stack_id ); break; case TX_PROTOCOL_TRANSMIT_LORA: + case TX_PROTOCOL_TRANSMIT_LORA_CERTIFICATION: status = lorawan_api_payload_send( current_tpm_fport, current_tpm_fport_enabled, current_tpm_data, current_tpm_data_len, current_tpm_packet_type, current_tpm_target_time_ms, @@ -519,7 +616,7 @@ static status_lorawan_t manage_tx_lora_state( void ) break; case TX_PROTOCOL_TRANSMIT_LORA_AT_TIME: - + if( ( ( int32_t ) ( current_tpm_target_transmit_at_time + MODEM_MIN_RANDOM_DELAY_MS - ( current_tpm_target_time_ms + update_add_delay_ms( ) ) ) < 0 ) ) { @@ -549,9 +646,9 @@ static status_lorawan_t manage_tx_lora_state( void ) { lorawan_api_set_next_tx_at_time( current_tpm_stack_id, true ); } - if (status == ERRORLORAWAN) + if( status == ERRORLORAWAN ) { - tpm_abort( ); + tpm_abort( ); } return status; } @@ -571,7 +668,7 @@ static status_lorawan_t manage_tx_lora_state( void ) // In the case where the channel is always busy, TPM tries MAX_TRIAL_LBT times to relaunch the LBT service before // aborting the current Tx transaction. -#define MAX_TRIAL_LBT 10 +#define MAX_TRIAL_LBT ( ( current_tpm_request_type == TX_PROTOCOL_TRANSMIT_TEST_MODE ) ? 10000UL : 10UL ) /** * @brief this function is called by the service LBT when the channel is "busy" meaning interferer block the next @@ -594,7 +691,7 @@ static status_lorawan_t manage_tx_lora_state( void ) static void modem_tpm_radio_busy_lbt( void* context ) { -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) // manage WOR LBT if( smtc_relay_tx_is_enable( current_tpm_stack_id ) == true ) { @@ -627,7 +724,7 @@ static void modem_tpm_radio_busy_lbt( void* context ) { modem_tpm_radio_abort_lbt( context ); } -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) } #endif @@ -679,8 +776,16 @@ static void modem_tpm_radio_abort_lbt( void* context ) */ static status_lorawan_t manage_lbt_state( void ) { - lr1_stack_mac_t* lr1mac_obj = lorawan_api_stack_mac_get( current_tpm_stack_id ); - uint32_t target_time_lbt = current_tpm_target_time_ms; + uint32_t target_time_lbt = current_tpm_target_time_ms; + + if( current_tpm_request_type == TX_PROTOCOL_TRANSMIT_TEST_MODE ) + { + smtc_lbt_listen_channel( smtc_lbt_get_obj( current_tpm_stack_id ), + ( smtc_modem_test_get_context ) ( )->tx_frequency, false, target_time_lbt, 0 ); + return OKLORAWAN; + } + lr1_stack_mac_t* lr1mac_obj = lorawan_api_stack_mac_get( current_tpm_stack_id ); + if( current_tpm_transmit_at_time == true ) { // this case covers the case where relay is on and to perform the lbt between wor_ack and lr1mac transmission @@ -732,7 +837,7 @@ static status_lorawan_t manage_lbt_state( void ) #if defined( ADD_CSMA ) static void modem_tpm_radio_busy_csma( void* context ) { -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) // manage WOR CSMA if( smtc_relay_tx_is_enable( current_tpm_stack_id ) == true ) { @@ -764,7 +869,7 @@ static void modem_tpm_radio_busy_csma( void* context ) { modem_tpm_radio_abort_csma( context ); } -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) } #endif @@ -791,7 +896,6 @@ static void modem_tpm_radio_free_csma( void* context ) shift_left_tpm_list( ); update_tpm_target_time( ); modem_tx_protocol_manager_engine( ); - SMTC_MODEM_HAL_TRACE_PRINTF( "modem_tpm_radio_free_csma\n" ); } /** * @brief this function is to abort the current tpm transmission @@ -823,7 +927,7 @@ static void modem_tpm_radio_abort_csma( void* context ) */ static void modem_tpm_radio_free_cad_keep_channel( void* context ) { -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) // manage WOR CSMA if( smtc_relay_tx_is_enable( current_tpm_stack_id ) == true ) { @@ -836,7 +940,7 @@ static void modem_tpm_radio_free_cad_keep_channel( void* context ) // => so do not call compute_tpm_list( ); update_tpm_target_time( ); modem_tx_protocol_manager_engine( ); -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) } #endif } @@ -851,8 +955,19 @@ static void modem_tpm_radio_free_cad_keep_channel( void* context ) */ static status_lorawan_t manage_csma_state( void ) { - lr1_stack_mac_t* lr1mac_obj = lorawan_api_stack_mac_get( current_tpm_stack_id ); - uint32_t target_time_csma = current_tpm_target_time_ms; + uint32_t target_time_csma = current_tpm_target_time_ms; + + if( current_tpm_request_type == TX_PROTOCOL_TRANSMIT_TEST_MODE ) + { + modem_test_context_t* test_mode_context = smtc_modem_test_get_context( ); + smtc_lora_cad_bt_listen_channel( + smtc_cad_get_obj( current_tpm_stack_id ), test_mode_context->tx_frequency, test_mode_context->sf, + test_mode_context->bw, false, target_time_csma, 0, + 16, // 16 because the max trial of csma have to be manage only by cad user setting + test_mode_context->invert_iq ); + return OKLORAWAN; + } + lr1_stack_mac_t* lr1mac_obj = lorawan_api_stack_mac_get( current_tpm_stack_id ); if( smtc_real_get_modulation_type_from_datarate( lr1mac_obj->real, lr1mac_obj->tx_data_rate ) == LORA ) { uint8_t tx_sf; @@ -860,9 +975,8 @@ static status_lorawan_t manage_csma_state( void ) smtc_real_lora_dr_to_sf_bw( lr1mac_obj->real, lr1mac_obj->tx_data_rate, &tx_sf, &tx_bw ); smtc_lora_cad_bt_listen_channel( smtc_cad_get_obj( current_tpm_stack_id ), lr1mac_obj->tx_frequency, tx_sf, - ( ral_lora_bw_t ) tx_bw, false, target_time_csma, - smtc_real_get_symbol_duration_us( lr1mac_obj->real, lr1mac_obj->tx_data_rate ), - 0, lr1mac_obj->nb_available_tx_channel, false ); + ( ral_lora_bw_t ) tx_bw, false, target_time_csma, 0, + lr1mac_obj->nb_available_tx_channel, false ); } else { @@ -884,7 +998,7 @@ static status_lorawan_t manage_csma_state( void ) *Depending on the callback, TPM updates its state machine to launch the next task. ********************************************************************************************************************/ -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) // the wor_tx variable is updated by smtc_relay_tx_prepare_wor to provide every parameters required to start the wor // transmission at the right time this variable will be reuse by smtc_relay_tx_send_wor, manage_lbt_before_wor_state or // manage_csma_before_wor_state functions @@ -956,10 +1070,8 @@ static status_lorawan_t manage_lbt_before_wor_state( void ) #if defined( ADD_CSMA ) static status_lorawan_t manage_csma_before_wor_state( void ) { - lr1_stack_mac_t* lr1mac_obj = lorawan_api_stack_mac_get( current_tpm_stack_id ); smtc_lora_cad_bt_listen_channel( smtc_cad_get_obj( current_tpm_stack_id ), wor_tx.freq_hz, wor_tx.sf, wor_tx.bw, - false, current_tpm_target_time_ms, - smtc_real_get_symbol_duration_us( lr1mac_obj->real, wor_tx.dr ), 0, MAX_TRIAL_RELAY, true ); + false, current_tpm_target_time_ms, 0, MAX_TRIAL_RELAY, true ); return OKLORAWAN; } @@ -1022,7 +1134,7 @@ static void modem_tpm_radio_abort_relay_tx( void* context ) /****************************************************************/ static status_lorawan_t tpm_get_next_channel( void ) { -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) if( ( tpm_list_of_state_to_execute[0] == TPM_STATE_LBT_BEFORE_WOR ) #if defined( ADD_CSMA ) || ( tpm_list_of_state_to_execute[0] == TPM_STATE_CSMA_BEFORE_WOR ) @@ -1032,6 +1144,10 @@ static status_lorawan_t tpm_get_next_channel( void ) return ( OKLORAWAN ); } #endif + if( current_tpm_request_type == TX_PROTOCOL_TRANSMIT_TEST_MODE ) + { + return ( OKLORAWAN ); + } if( current_tpm_request_type == TX_PROTOCOL_JOIN_LORA ) { @@ -1076,12 +1192,54 @@ static uint32_t update_add_delay_ms( void ) return ( current_tpm_add_delay_ms ); } +/** + * @brief This function compute and fix the order of the different state + **/ +/** + * @brief Computes the list of states to execute for the transmission protocol manager (TPM). + * + * This function determines the sequence of states that the TPM should execute based on the current + * request type and various conditions such as LBT (Listen Before Talk) and CSMA (Carrier Sense Multiple Access). + * The sequence of states is stored in the global array `tpm_list_of_state_to_execute`. + * + * The function handles different scenarios: + * - Transmit Test Mode: Adds TPM_STATE_LBT and TPM_STATE_TEST_MODE to the list. + * - Relay TX Mode: Adds a sequence of states including TPM_STATE_PREPARE_WOR, TPM_STATE_CSMA_BEFORE_WOR, + * TPM_STATE_LBT_BEFORE_WOR, TPM_STATE_RELAY_TX, TPM_STATE_LBT, TPM_STATE_TX_LORA, or TPM_STATE_NWK_TX_LORA. + * - Default Mode: Adds a sequence of states including TPM_STATE_CSMA, TPM_STATE_LBT, TPM_STATE_TX_LORA, or + * TPM_STATE_NWK_TX_LORA. + * + * The function ensures that the index does not exceed the maximum list length and terminates the list with + * TPM_STATE_IDLE. + * + * @note This function uses conditional compilation to include or exclude CSMA and Relay TX functionality. + */ static void compute_tpm_list( void ) { +#if defined( ADD_CSMA ) + lr1_stack_mac_t* lr1mac_obj = lorawan_api_stack_mac_get( current_tpm_stack_id ); +#endif uint8_t index = 0; reset_tpm_list( ); - -#if defined( RELAY_TX ) + if( current_tpm_request_type == TX_PROTOCOL_TRANSMIT_TEST_MODE ) + { +#if defined( ADD_CSMA ) + modem_test_context_t* test_mode_context = smtc_modem_test_get_context( ); + if( ( smtc_lora_cad_bt_get_state( smtc_cad_get_obj( current_tpm_stack_id ) ) == true ) && + ( test_mode_context->modulation_type == LORA ) ) + { + tpm_list_of_state_to_execute[index++] = TPM_STATE_CSMA; + } +#endif + if( smtc_lbt_get_state( smtc_lbt_get_obj( current_tpm_stack_id ) ) == true ) + { + tpm_list_of_state_to_execute[index++] = TPM_STATE_LBT; + } + tpm_list_of_state_to_execute[index++] = TPM_STATE_TEST_MODE; + tpm_list_of_state_to_execute[index] = TPM_STATE_IDLE; + return; + } +#if defined( ADD_RELAY_TX ) /////////////////////////////////////////////////////////////// // SEQUENCE IS PREPARE_WOR,CSMA_WOR,LBT_WOR,WOR,LBT,TX_LORA // /////////////////////////////////////////////////////////////// @@ -1090,7 +1248,9 @@ static void compute_tpm_list( void ) tpm_list_of_state_to_execute[index++] = TPM_STATE_PREPARE_WOR; #if defined( ADD_CSMA ) - if( smtc_lora_cad_bt_get_state( smtc_cad_get_obj( current_tpm_stack_id ) ) == true ) + + if( ( smtc_lora_cad_bt_get_state( smtc_cad_get_obj( current_tpm_stack_id ) ) == true ) && + ( smtc_real_get_modulation_type_from_datarate( lr1mac_obj->real, lr1mac_obj->tx_data_rate ) == LORA ) ) { tpm_list_of_state_to_execute[index++] = TPM_STATE_CSMA_BEFORE_WOR; } @@ -1121,7 +1281,8 @@ static void compute_tpm_list( void ) #endif #if defined( ADD_CSMA ) - if( smtc_lora_cad_bt_get_state( smtc_cad_get_obj( current_tpm_stack_id ) ) == true ) + if( ( smtc_lora_cad_bt_get_state( smtc_cad_get_obj( current_tpm_stack_id ) ) == true ) && + ( smtc_real_get_modulation_type_from_datarate( lr1mac_obj->real, lr1mac_obj->tx_data_rate ) == LORA ) ) { tpm_list_of_state_to_execute[index++] = TPM_STATE_CSMA; } @@ -1138,7 +1299,7 @@ static void compute_tpm_list( void ) { tpm_list_of_state_to_execute[index++] = TPM_STATE_NWK_TX_LORA; } -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) } #endif if( index >= MAX_LIST_LENGTH ) @@ -1197,6 +1358,11 @@ static void tpm_abort( void ) { reset_tpm_list( ); current_tpm_transmit_is_aborted = true; + if( current_tpm_request_type == TX_PROTOCOL_TRANSMIT_TEST_MODE ) + { + test_mode_cb_tpm( current_tpm_data, current_tpm_data_len, true ); + } + lorawan_api_core_abort( current_tpm_stack_id ); } @@ -1209,6 +1375,11 @@ static status_lorawan_t manage_idle_state( void ) { return OKLORAWAN; } +static status_lorawan_t manage_test_mode( void ) +{ + shift_left_tpm_list( ); + return ( test_mode_cb_tpm( current_tpm_data, current_tpm_data_len, false ) ); +} static void update_tpm_target_time( void ) { if( current_tpm_transmit_at_time == false ) @@ -1225,7 +1396,7 @@ static void tpm_debug_print( void ) { switch( tpm_list_of_state_to_execute[0] ) { -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) case TPM_STATE_PREPARE_WOR: SMTC_MODEM_HAL_TRACE_PRINTF( "TPM Launch PREPARE_WOR Service at %d \n", smtc_modem_hal_get_time_in_ms( ) ); break; @@ -1256,6 +1427,9 @@ static void tpm_debug_print( void ) case TPM_STATE_NWK_TX_LORA: SMTC_MODEM_HAL_TRACE_PRINTF( "TPM Launch NWK TX Lr1mac at %d \n", smtc_modem_hal_get_time_in_ms( ) ); break; + case TPM_STATE_TEST_MODE: + SMTC_MODEM_HAL_TRACE_PRINTF( "TPM Launch TEST MODE at %d \n", smtc_modem_hal_get_time_in_ms( ) ); + break; case TPM_STATE_IDLE: SMTC_MODEM_HAL_TRACE_PRINTF( "TPM Launch idle task at %d \n", smtc_modem_hal_get_time_in_ms( ) ); break; @@ -1263,4 +1437,4 @@ static void tpm_debug_print( void ) SMTC_MODEM_HAL_TRACE_ERROR( "TPM state error 0x%x\n", tpm_list_of_state_to_execute[0] ); break; } -} \ No newline at end of file +} diff --git a/lbm_lib/smtc_modem_core/modem_supervisor/modem_tx_protocol_manager.h b/lbm_lib/smtc_modem_core/modem_supervisor/modem_tx_protocol_manager.h index 9fc22b7..011d443 100644 --- a/lbm_lib/smtc_modem_core/modem_supervisor/modem_tx_protocol_manager.h +++ b/lbm_lib/smtc_modem_core/modem_supervisor/modem_tx_protocol_manager.h @@ -45,7 +45,6 @@ extern "C" { */ #include "radio_planner.h" #include "lr1_stack_mac_layer.h" -#include "modem_services_config.h" /* * ----------------------------------------------------------------------------- @@ -59,11 +58,13 @@ extern "C" { */ typedef enum tx_protocol_manager_tx_type { - TX_PROTOCOL_NONE = 0x00, - TX_PROTOCOL_JOIN_LORA = 0x01, //!< - TX_PROTOCOL_TRANSMIT_LORA = 0x02, //!< - TX_PROTOCOL_TRANSMIT_CID = 0x3, - TX_PROTOCOL_TRANSMIT_LORA_AT_TIME = 0x4, + TX_PROTOCOL_NONE = 0x00, + TX_PROTOCOL_JOIN_LORA = 0x01, //!< + TX_PROTOCOL_TRANSMIT_LORA = 0x02, //!< + TX_PROTOCOL_TRANSMIT_CID = 0x03, + TX_PROTOCOL_TRANSMIT_LORA_AT_TIME = 0x04, + TX_PROTOCOL_TRANSMIT_TEST_MODE = 0x05, + TX_PROTOCOL_TRANSMIT_LORA_CERTIFICATION = 0x06, } tx_protocol_manager_tx_type_t; /* * ----------------------------------------------------------------------------- @@ -75,7 +76,7 @@ typedef enum tx_protocol_manager_tx_type * \remark This function is called by the modem's upper layer itself, it shouldn't be useful at the application layer * \retval None */ -void modem_tx_protcol_manager_init( radio_planner_t* rp ); +void modem_tx_protocol_manager_init( radio_planner_t* rp ); /*! * @brief tx_protocol_manager_request function is called each time a LoRaWAN transmission will be processed @@ -122,7 +123,7 @@ bool tx_protocol_manager_tx_is_aborted( void ); * @param NONE * @return void */ - void tx_protocol_manager_abort( void ); +void tx_protocol_manager_abort( void ); #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/modem_utilities/circularfs.c b/lbm_lib/smtc_modem_core/modem_utilities/circularfs.c index 3395ec1..0320c6c 100644 --- a/lbm_lib/smtc_modem_core/modem_utilities/circularfs.c +++ b/lbm_lib/smtc_modem_core/modem_utilities/circularfs.c @@ -43,6 +43,10 @@ #include "smtc_modem_hal_dbg_trace.h" #include "circularfs.h" +#ifndef MIN +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + /** * @} * @defgroup sector status @@ -711,6 +715,7 @@ void circularfs_dump( struct circularfs* fs ) { #if( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) const char* description; + char slots_description[170]; SMTC_MODEM_HAL_TRACE_PRINTF( "CIRCULARFS read: {%d,%d} cursor: {%d,%d} write: {%d,%d}\n", fs->read.sector, fs->read.slot, fs->cursor.sector, fs->cursor.slot, fs->write.sector, fs->write.slot ); @@ -750,37 +755,43 @@ void circularfs_dump( struct circularfs* fs ) break; } - SMTC_MODEM_HAL_TRACE_PRINTF( "[%04d] [v=0x%08" PRIx32 "] [%-10s] ", sector, header_version, description ); - for( int32_t slot = 0; slot < fs->slots_per_sector; slot++ ) { - struct circularfs_loc loc = { sector, slot }; - uint32_t status = 0; - _slot_get_status( fs, &loc, &status ); + if( slot < ( int32_t ) ( sizeof( slots_description ) - 1 ) ) + { + struct circularfs_loc loc = { sector, slot }; + uint32_t status = 0; + _slot_get_status( fs, &loc, &status ); - switch( status ) + switch( status ) + { + case SLOT_ERASED: + slots_description[slot] = 'E'; + break; + case SLOT_RESERVED: + slots_description[slot] = 'R'; + break; + case SLOT_VALID: + slots_description[slot] = 'V'; + break; + case SLOT_GARBAGE: + slots_description[slot] = 'G'; + break; + default: + slots_description[slot] = '?'; + break; + } + } + else { - case SLOT_ERASED: - description = "E"; - break; - case SLOT_RESERVED: - description = "R"; - break; - case SLOT_VALID: - description = "V"; - break; - case SLOT_GARBAGE: - description = "G"; - break; - default: - description = "?"; + SMTC_MODEM_HAL_TRACE_WARNING( "%s: buffer trace too short\n", __func__ ); break; } - - SMTC_MODEM_HAL_TRACE_PRINTF( "%s", description ); } + slots_description[MIN( fs->slots_per_sector, ( int32_t ) ( sizeof( slots_description ) - 1 ) )] = '\0'; - SMTC_MODEM_HAL_TRACE_PRINTF( "\n" ); + SMTC_MODEM_HAL_TRACE_PRINTF( "[%04d] [v=0x%08" PRIx32 "] [%-10s] %s\n", sector, header_version, description, + slots_description ); } #endif // MODEM_HAL_DBG_TRACE } diff --git a/lbm_lib/smtc_modem_core/modem_utilities/modem_core.c b/lbm_lib/smtc_modem_core/modem_utilities/modem_core.c index 7fbb32a..a97a36d 100644 --- a/lbm_lib/smtc_modem_core/modem_utilities/modem_core.c +++ b/lbm_lib/smtc_modem_core/modem_utilities/modem_core.c @@ -59,6 +59,9 @@ #include "lorawan_class_b_management.h" #include "lorawan_send_management.h" +#if defined( ADD_RELAY_TX ) +#include "relay_tx_api.h" +#endif /* * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- @@ -114,7 +117,7 @@ struct uint32_t user_alarm; fifo_ctrl_t fifo_ctrl_obj; uint8_t fifo_buffer[FIFO_LORAWAN_SIZE]; - uint8_t ( *downlink_services_callback[NUMBER_OF_SERVICES + NUMBER_OF_LORAWAN_MANAGEMENT_TASKS] )( + uint8_t ( *downlink_services_callback[NUMBER_OF_SERVICES + NUMBER_OF_LORAWAN_MANAGEMENT_TASKS] )( lr1_stack_mac_down_data_t* rx_down_data ); uint32_t modem_reset_counter; } modem_ctx_light; @@ -143,8 +146,8 @@ static void modem_downlink_callback( lr1_stack_mac_down_data_t* rx_down_data ); void modem_context_init_light( void ( *callback )( void ), radio_planner_t* rp ) { - void ( *callback_on_launch_temp )( void* ); - void ( *callback_on_update_temp )( void* ); + void ( *callback_on_launch_temp )( void* ); + void ( *callback_on_update_temp )( void* ); void* context_callback_tmp; modem_rp = rp; @@ -272,7 +275,7 @@ bool modem_suspend_radio_access( void ) .launch_task_callbacks = modem_empty_callback, .schedule_task_low_priority = false, .start_time_ms = smtc_modem_hal_get_time_in_ms( ) + 4, - .duration_time_ms = 20000, + .duration_time_ms = 20, .state = RP_TASK_STATE_SCHEDULE, }; @@ -335,6 +338,14 @@ int32_t modem_duty_cycle_get_status( uint8_t stack_id ) &number_of_freq, freq_list, sizeof( freq_list ) / sizeof( freq_list[0] ), stack_id ) == true ) { region_dtc = smtc_duty_cycle_get_next_free_time_ms( number_of_freq, freq_list ); +#if defined( ADD_RELAY_TX ) + int32_t relay_region_dtc = smtc_relay_tx_free_duty_cycle_ms_get( stack_id ); + + if( relay_region_dtc != 0 ) + { + region_dtc = MAX( region_dtc, relay_region_dtc ); + } +#endif } if( nwk_dtc == 0 ) @@ -414,17 +425,23 @@ void modem_load_modem_context( void ) modem_ctx_t ctx = { 0 }; smtc_modem_hal_context_restore( CONTEXT_MODEM, 0, ( uint8_t* ) &ctx, sizeof( ctx ) ); - if( crc( ( uint8_t* ) &ctx, sizeof( ctx ) - sizeof( ctx.crc ) ) == ctx.crc ) - { - modem_reset_counter = ctx.reset_counter; - } - else + if( crc( ( uint8_t* ) &ctx, sizeof( ctx ) - sizeof( ctx.crc ) ) != ctx.crc ) { - ctx.reset_counter = 0; + memset( &ctx, 0, sizeof( ctx ) ); + ctx.crc = crc( ( uint8_t* ) &ctx, sizeof( ctx ) - sizeof( ctx.crc ) ); + smtc_modem_hal_context_store( CONTEXT_MODEM, 0, ( uint8_t* ) &ctx, sizeof( ctx ) ); // dummy context reading to ensure context store is done before exiting the function smtc_modem_hal_context_restore( CONTEXT_MODEM, 0, ( uint8_t* ) &ctx, sizeof( ctx ) ); } + + modem_reset_counter = ctx.reset_counter; +} + +void modem_reset_modem_context( void ) +{ + modem_ctx_t ctx = { 0 }; + smtc_modem_hal_context_store( CONTEXT_MODEM, 0, ( uint8_t* ) &ctx, sizeof( ctx ) ); } uint32_t modem_get_reset_counter( void ) diff --git a/lbm_lib/smtc_modem_core/modem_utilities/modem_core.h b/lbm_lib/smtc_modem_core/modem_utilities/modem_core.h index 21ce40b..3b5d419 100644 --- a/lbm_lib/smtc_modem_core/modem_utilities/modem_core.h +++ b/lbm_lib/smtc_modem_core/modem_utilities/modem_core.h @@ -231,6 +231,11 @@ void modem_load_modem_context( void ); */ void modem_store_modem_context( void ); +/** + * @brief Reset modem context + */ +void modem_reset_modem_context( void ); + /** * @brief Get current reset counter value */ diff --git a/lbm_lib/smtc_modem_core/modem_utilities/modem_services_config.h b/lbm_lib/smtc_modem_core/modem_utilities/modem_services_config.h index d9ad729..d1dc14c 100644 --- a/lbm_lib/smtc_modem_core/modem_utilities/modem_services_config.h +++ b/lbm_lib/smtc_modem_core/modem_utilities/modem_services_config.h @@ -47,15 +47,15 @@ extern "C" { #include "lorawan_alcsync.h" #endif -#ifdef MODEM_BEACON_APP +#if defined( MODEM_BEACON_APP ) #include "lorawan_beacon_tx_service_example.h" #endif -#ifdef RELAY_RX +#if defined( ADD_RELAY_RX ) #include "lorawan_relay_rx_service.h" #endif -#ifdef RELAY_TX +#if defined( ADD_RELAY_TX ) #include "lorawan_relay_tx_service.h" #endif @@ -104,7 +104,7 @@ typedef struct modem_service_config_s uint8_t service_id; // Start to 0 for new type of services, increment this number for multiple instantiation of the // same type of service uint8_t stack_id; // The linked LoRaWAN stack to this service - void ( *callbacks_init_service )( uint8_t* service_id, uint8_t task_id, + void ( *callbacks_init_service )( uint8_t* service_id, uint8_t task_id, uint8_t ( **callback )( lr1_stack_mac_down_data_t* ), void ( **callback_on_launch )( void* ), void ( **callback_on_update )( void* ), void** callback_context ); @@ -113,10 +113,10 @@ typedef struct modem_service_config_s static modem_service_config_t modem_service_config[] = { { .service_id = 0, .stack_id = 0, .callbacks_init_service = lorawan_certification_services_init }, -#ifdef RELAY_RX +#ifdef ADD_RELAY_RX { .service_id = 0, .stack_id = 0, .callbacks_init_service = lorawan_relay_rx_services_init }, #endif -#ifdef RELAY_TX +#if defined( ADD_RELAY_TX ) { .service_id = 0, .stack_id = 0, .callbacks_init_service = lorawan_relay_tx_services_init }, #endif #ifdef ADD_SMTC_ALC_SYNC diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/CHANGELOG.md b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/CHANGELOG.md index b63e790..4ab8184 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/CHANGELOG.md +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/CHANGELOG.md @@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v2.5.2] - v2.5.2 + +### Fixed + +- Fix Wi-Fi math computation warnings + +## [v2.5.1] 2024-10-31 + +### Fixed + +- In-code driver version +- Fix RTToF and GNSS math computation warnings + +## [v2.5.0] 2024-07-24 + +### Added + +- [radio] `lr11xx_radio_set_lna_mode` function to configure usage of antenna for LNA and corresponding helper functions `lr11xx_radio_set_rx_and_lna_mode` and `lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode` + ## [v2.4.1] 2023-11-16 ### Changed @@ -70,56 +89,56 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added -* [radio] `lr11xx_radio_set_lora_sync_timeout_with_mantissa_exponent()` function -* [radio] `LR11XX_RADIO_PKT_TYPE_BPSK` packet type, with `lr11xx_radio_set_bpsk_pkt_params` and `lr11xx_radio_set_bpsk_mod_params` functions -* [GNSS] `lr11xx_gnss_apply_mixer_cfg_workaround()` function -* [GNSS] Add function `lr11xx_gnss_read_gnss_rssi_test` to read RSSI on GNSS path -* [GNSS] Add function `lr11xx_gnss_read_freq_search_space` -* [GNSS] Add function `lr11xx_gnss_set_freq_search_space` -* [GNSS] Add function `lr11xx_gnss_get_nb_visible_satellites` -* [GNSS] Add function `lr11xx_gnss_get_visible_satellites` -* [GNSS] add structure `lr11xx_gnss_visible_satellite_t` to support `lr11xx_gnss_get_visible_satellites` function -* [lr-fhss] Add function `lr11xx_lr_fhss_get_bit_delay_in_us` to compute the delay between the last LR-FHSS bit sent and the TX done interrupt -* [radio] Add function `lr11xx_radio_set_lr_fhss_sync_word` to configure the LR-FHSS syncword -* [radio] Add function `lr11xx_radio_set_lr_fhss_mod_params` to configure the LR-FHSS modulation parameters -* [radio] Add helper function `lr11xx_radio_convert_nb_symb_to_mant_exp` to convert a number of symbols into mantissa/exponent representation -* [crypto] Add functions `lr11xx_crypto_check_encrypted_firmware_image` and `lr11xx_crypto_get_check_encrypted_firmware_image_result`; and helper function `lr11xx_crypto_check_encrypted_firmware_image_full` to check suitability of encrypted firmware image prior to actual flashing -* [ranging] Add `lr11xx_ranging_*` functions as part of new ranging component `lr11xx_ranging` +- [radio] `lr11xx_radio_set_lora_sync_timeout_with_mantissa_exponent()` function +- [radio] `LR11XX_RADIO_PKT_TYPE_BPSK` packet type, with `lr11xx_radio_set_bpsk_pkt_params` and `lr11xx_radio_set_bpsk_mod_params` functions +- [GNSS] `lr11xx_gnss_apply_mixer_cfg_workaround()` function +- [GNSS] Add function `lr11xx_gnss_read_gnss_rssi_test` to read RSSI on GNSS path +- [GNSS] Add function `lr11xx_gnss_read_freq_search_space` +- [GNSS] Add function `lr11xx_gnss_set_freq_search_space` +- [GNSS] Add function `lr11xx_gnss_get_nb_visible_satellites` +- [GNSS] Add function `lr11xx_gnss_get_visible_satellites` +- [GNSS] add structure `lr11xx_gnss_visible_satellite_t` to support `lr11xx_gnss_get_visible_satellites` function +- [lr-fhss] Add function `lr11xx_lr_fhss_get_bit_delay_in_us` to compute the delay between the last LR-FHSS bit sent and the TX done interrupt +- [radio] Add function `lr11xx_radio_set_lr_fhss_sync_word` to configure the LR-FHSS syncword +- [radio] Add function `lr11xx_radio_set_lr_fhss_mod_params` to configure the LR-FHSS modulation parameters +- [radio] Add helper function `lr11xx_radio_convert_nb_symb_to_mant_exp` to convert a number of symbols into mantissa/exponent representation +- [crypto] Add functions `lr11xx_crypto_check_encrypted_firmware_image` and `lr11xx_crypto_get_check_encrypted_firmware_image_result`; and helper function `lr11xx_crypto_check_encrypted_firmware_image_full` to check suitability of encrypted firmware image prior to actual flashing +- [ranging] Add `lr11xx_ranging_*` functions as part of new ranging component `lr11xx_ranging` ### Changed -* [GNSS] Call to `lr11xx_gnss_apply_mixer_cfg_workaround()` in `lr11xx_gnss_scan_autonomous()` and `lr11xx_gnss_scan_assisted()` (can be removed by defining `LR11XX_DISABLE_MIXER_CFG_WORKAROUND`) -* [system] Field `type` of `lr11xx_system_version_t` is now an enumerated type named `lr11xx_system_version_type_t` -* [system] Add IRQ raised on LoRa symbol received over-the-air -* [radio] `lr11xx_radio_set_lora_sync_timeout` takes argument `nb_symbol` as `uint16_t` -* [regmem] `lr11xx_regmem_write_regmem32` and `lr11xx_regmem_read_regmem32` test the number of words to write/read before actually requesting the chip, and raise an error status if it is higher than 64 +- [GNSS] Call to `lr11xx_gnss_apply_mixer_cfg_workaround()` in `lr11xx_gnss_scan_autonomous()` and `lr11xx_gnss_scan_assisted()` (can be removed by defining `LR11XX_DISABLE_MIXER_CFG_WORKAROUND`) +- [system] Field `type` of `lr11xx_system_version_t` is now an enumerated type named `lr11xx_system_version_type_t` +- [system] Add IRQ raised on LoRa symbol received over-the-air +- [radio] `lr11xx_radio_set_lora_sync_timeout` takes argument `nb_symbol` as `uint16_t` +- [regmem] `lr11xx_regmem_write_regmem32` and `lr11xx_regmem_read_regmem32` test the number of words to write/read before actually requesting the chip, and raise an error status if it is higher than 64 ## [v2.1.1] 2022-04-06 ### Fixed -* [radio] Order of the parameters in `lr11xx_radio_set_rssi_calibration()` function +- [radio] Order of the parameters in `lr11xx_radio_set_rssi_calibration()` function ## [v2.1.0] 2022-03-28 ### Added -* [radio] `lr11xx_radio_apply_high_acp_workaround()` function -* [radio] `lr11xx_radio_set_rssi_calibration()` function -* [radio] `LR11XX_RADIO_LORA_BW_200`, `LR11XX_RADIO_LORA_BW_400` and `LR11XX_RADIO_LORA_BW_800` entries to `lr11xx_radio_lora_bw_t` -* [radio] `LR11XX_RADIO_GFSK_PKT_VAR_LEN_SX128X_COMP` entry in `lr11xx_radio_gfsk_pkt_len_modes_t` to support compatibility with SX128x -* [radio] `LR11XX_RADIO_GFSK_DC_FREE_WHITENING_SX128X_COMP` entry in `lr11xx_radio_gfsk_dc_free_t` to support compatibility with SX128x -* [GNSS] `lr11xx_gnss_get_consumption` function -* [Wi-Fi] `lr11xx_wifi_get_consumption` function -* [Wi-Fi] `lr11xx_wifi_are_scan_mode_result_format_compatible` function +- [radio] `lr11xx_radio_apply_high_acp_workaround()` function +- [radio] `lr11xx_radio_set_rssi_calibration()` function +- [radio] `LR11XX_RADIO_LORA_BW_200`, `LR11XX_RADIO_LORA_BW_400` and `LR11XX_RADIO_LORA_BW_800` entries to `lr11xx_radio_lora_bw_t` +- [radio] `LR11XX_RADIO_GFSK_PKT_VAR_LEN_SX128X_COMP` entry in `lr11xx_radio_gfsk_pkt_len_modes_t` to support compatibility with SX128x +- [radio] `LR11XX_RADIO_GFSK_DC_FREE_WHITENING_SX128X_COMP` entry in `lr11xx_radio_gfsk_dc_free_t` to support compatibility with SX128x +- [GNSS] `lr11xx_gnss_get_consumption` function +- [Wi-Fi] `lr11xx_wifi_get_consumption` function +- [Wi-Fi] `lr11xx_wifi_are_scan_mode_result_format_compatible` function ### Changed -* [radio] Call to `lr11xx_radio_apply_high_acp_workaround()` in `lr11xx_radio_set_tx_with_timeout_in_rtc_step()`, `lr11xx_radio_set_rx_with_timeout_in_rtc_step()`, `lr11xx_radio_set_cad()` and `lr11xx_radio_set_tx_infinite_preamble()` (can be removed by defining `LR11XX_DISABLE_HIGH_ACP_WORKAROUND`) -* [Wi-Fi] Define type `lr11xx_wifi_country_code_str_t` for Wi-Fi country code data and update `lr11xx_wifi_extended_full_result_t` and `lr11xx_wifi_country_code_t` to use it. +- [radio] Call to `lr11xx_radio_apply_high_acp_workaround()` in `lr11xx_radio_set_tx_with_timeout_in_rtc_step()`, `lr11xx_radio_set_rx_with_timeout_in_rtc_step()`, `lr11xx_radio_set_cad()` and `lr11xx_radio_set_tx_infinite_preamble()` (can be removed by defining `LR11XX_DISABLE_HIGH_ACP_WORKAROUND`) +- [Wi-Fi] Define type `lr11xx_wifi_country_code_str_t` for Wi-Fi country code data and update `lr11xx_wifi_extended_full_result_t` and `lr11xx_wifi_country_code_t` to use it. ## [v1.0.0] Unreleased ### Added -* [all] Initial version - based on LR1110 driver v7.0.0 +- [all] Initial version - based on LR1110 driver v7.0.0 diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.c b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.c index 42355bf..d84ff14 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.c +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.c @@ -44,12 +44,6 @@ * --- PRIVATE MACROS----------------------------------------------------------- */ -#define STR_HELPER( x ) #x -#define STR( x ) STR_HELPER( x ) - -#define LR11XX_DRIVER_VERSION_FULL \ - "v" STR( LR11XX_DRIVER_VERSION_MAJOR ) "." STR( LR11XX_DRIVER_VERSION_MINOR ) "." STR( LR11XX_DRIVER_VERSION_PATCH ) - /* * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- @@ -77,7 +71,7 @@ const char* lr11xx_driver_version_get_version_string( void ) { - return ( const char* ) LR11XX_DRIVER_VERSION_FULL; + return ( const char* ) LR11XX_DRIVER_VERSION; } /* diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.h b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.h index 0411fa1..c6ca146 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.h +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_driver_version.h @@ -54,9 +54,7 @@ extern "C" { * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -#define LR11XX_DRIVER_VERSION_MAJOR 2 -#define LR11XX_DRIVER_VERSION_MINOR 4 -#define LR11XX_DRIVER_VERSION_PATCH 1 +#define LR11XX_DRIVER_VERSION "v2.5.2" /* * ----------------------------------------------------------------------------- @@ -68,17 +66,11 @@ extern "C" { * --- PUBLIC FUNCTIONS PROTOTYPES --------------------------------------------- */ -/*! - * @brief Compare version information with current ones +/** + * @brief Get version of driver as string * - * This macro expands to true boolean value if the version information provided in argument is compatible or - * retro-compatible with the version of this code base + * @return String describing driver version */ -#define LR11XX_DRIVER_VERSION_CHECK( x, y, z ) \ - ( x == LR11XX_DRIVER_VERSION_MAJOR && \ - ( y < LR11XX_DRIVER_VERSION_MINOR || \ - ( y == LR11XX_DRIVER_VERSION_MINOR && z <= LR11XX_DRIVER_VERSION_PATCH ) ) ) - const char* lr11xx_driver_version_get_version_string( void ); #ifdef __cplusplus diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss.c b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss.c index c3d6dc5..fd5524f 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss.c +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_gnss.c @@ -970,37 +970,37 @@ void lr11xx_gnss_compute_power_consumption( uint32_t* power_consumption_nah, uint32_t* power_consumption_nwh ) { float e_init = - ( ( float ) instantaneous_power_consumption_ua->init_ua / 1000.0 * ( float ) cumulative_timing->init ) / - 32768.0; + ( ( float ) instantaneous_power_consumption_ua->init_ua / 1000.0f * ( float ) cumulative_timing->init ) / + 32768.0f; - float e_gps_capture = ( ( ( float ) instantaneous_power_consumption_ua->phase1_gps_capture_ua / 1000.0 * + float e_gps_capture = ( ( ( float ) instantaneous_power_consumption_ua->phase1_gps_capture_ua / 1000.0f * ( float ) cumulative_timing->phase1_gps_capture ) + - ( ( float ) instantaneous_power_consumption_ua->multiscan_gps_capture_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->multiscan_gps_capture_ua / 1000.0f * ( float ) cumulative_timing->multiscan_gps_capture ) ) / - 32768.0; + 32768.0f; - float e_gps_process = ( ( ( float ) instantaneous_power_consumption_ua->phase1_gps_process_ua / 1000.0 * + float e_gps_process = ( ( ( float ) instantaneous_power_consumption_ua->phase1_gps_process_ua / 1000.0f * ( float ) cumulative_timing->phase1_gps_process ) + - ( ( float ) instantaneous_power_consumption_ua->multiscan_gps_process_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->multiscan_gps_process_ua / 1000.0f * ( float ) cumulative_timing->multiscan_gps_process ) ) / - 32768.0; + 32768.0f; - float e_gps_sleep_32k = ( ( float ) instantaneous_power_consumption_ua->sleep_32k_ua / 1000.0 * + float e_gps_sleep_32k = ( ( float ) instantaneous_power_consumption_ua->sleep_32k_ua / 1000.0f * ( float ) cumulative_timing->multiscan_gps_sleep_32k ) / - 32768.0; + 32768.0f; float e_tot_gps = e_gps_capture + e_gps_process + e_gps_sleep_32k; - float e_beidou_capture = ( ( ( float ) instantaneous_power_consumption_ua->phase1_beidou_capture_ua / 1000.0 * + float e_beidou_capture = ( ( ( float ) instantaneous_power_consumption_ua->phase1_beidou_capture_ua / 1000.0f * ( float ) cumulative_timing->phase1_beidou_capture ) + - ( ( float ) instantaneous_power_consumption_ua->multiscan_beidou_capture_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->multiscan_beidou_capture_ua / 1000.0f * ( float ) cumulative_timing->multiscan_beidou_capture ) ) / - 32768.0; - float e_beidou_process = ( ( ( float ) instantaneous_power_consumption_ua->phase1_beidou_process_ua / 1000.0 * + 32768.0f; + float e_beidou_process = ( ( ( float ) instantaneous_power_consumption_ua->phase1_beidou_process_ua / 1000.0f * ( float ) cumulative_timing->phase1_beidou_process ) + - ( ( float ) instantaneous_power_consumption_ua->multiscan_beidou_process_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->multiscan_beidou_process_ua / 1000.0f * ( float ) cumulative_timing->multiscan_beidou_process ) ) / - 32768.0; + 32768.0f; float e_beidou_sleep_32k = ( instantaneous_power_consumption_ua->sleep_32k_ua / 1000.0 * cumulative_timing->multiscan_beidou_sleep_32k ) / 32768.0; @@ -1010,31 +1010,31 @@ void lr11xx_gnss_compute_power_consumption( float e_demod = 0; if( cumulative_timing->constellation_demod == 0 ) // Demodulation has been done on GPS constellation { - e_demod = ( ( ( float ) instantaneous_power_consumption_ua->multiscan_gps_capture_ua / 1000.0 * + e_demod = ( ( ( float ) instantaneous_power_consumption_ua->multiscan_gps_capture_ua / 1000.0f * ( float ) cumulative_timing->demod_capture ) + - ( ( float ) instantaneous_power_consumption_ua->multiscan_gps_process_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->multiscan_gps_process_ua / 1000.0f * ( float ) cumulative_timing->demod_process ) + - ( ( float ) instantaneous_power_consumption_ua->sleep_32k_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->sleep_32k_ua / 1000.0f * ( float ) cumulative_timing->demod_sleep_32k ) + - ( ( float ) instantaneous_power_consumption_ua->demod_sleep_32m_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->demod_sleep_32m_ua / 1000.0f * ( float ) cumulative_timing->demod_sleep_32m ) ) / - 32768.0; + 32768.0f; } else // Domulation has been done on Beidou constellation { - e_demod = ( ( ( float ) instantaneous_power_consumption_ua->multiscan_beidou_capture_ua / 1000.0 * + e_demod = ( ( ( float ) instantaneous_power_consumption_ua->multiscan_beidou_capture_ua / 1000.0f * ( float ) cumulative_timing->demod_capture ) + - ( ( float ) instantaneous_power_consumption_ua->multiscan_beidou_process_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->multiscan_beidou_process_ua / 1000.0f * ( float ) cumulative_timing->demod_process ) + - ( ( float ) instantaneous_power_consumption_ua->sleep_32k_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->sleep_32k_ua / 1000.0f * ( float ) cumulative_timing->demod_sleep_32k ) + - ( ( float ) instantaneous_power_consumption_ua->demod_sleep_32m_ua / 1000.0 * + ( ( float ) instantaneous_power_consumption_ua->demod_sleep_32m_ua / 1000.0f * ( float ) cumulative_timing->demod_sleep_32m ) ) / - 32768.0; + 32768.0f; } float power_consumption_uah_tmp = ( ( e_init + e_tot_gps + e_tot_beidou + e_demod ) * 1000 ) / - ( 3600.0 - ( ( float ) cumulative_timing->total / 32768.0 ) ); + ( 3600.0f - ( ( float ) cumulative_timing->total / 32768.0f ) ); *power_consumption_nah = ( uint32_t )( power_consumption_uah_tmp * 1000 ); *power_consumption_nwh = diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.c b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.c index ded213d..092801f 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.c +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.c @@ -409,7 +409,22 @@ lr11xx_status_t lr11xx_radio_set_rx( const void* context, const uint32_t timeout return lr11xx_radio_set_rx_with_timeout_in_rtc_step( context, timeout_in_rtc_step ); } -lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step( const void* context, const uint32_t timeout ) +lr11xx_status_t lr11xx_radio_set_rx_and_lna_mode( const void* context, const uint32_t timeout_in_ms, + lr11xx_radio_lna_mode_t lna_mode ) +{ + const uint32_t timeout_in_rtc_step = lr11xx_radio_convert_time_in_ms_to_rtc_step( timeout_in_ms ); + + return lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode( context, timeout_in_rtc_step, lna_mode ); +} + +lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step( const void* context, const uint32_t timeout_in_ms ) +{ + return lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode( context, timeout_in_ms, + LR11XX_RADIO_LNA_MODE_DIFFERENTIAL_LF0 ); +} + +lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode( const void* context, const uint32_t timeout, + lr11xx_radio_lna_mode_t lna_mode ) { lr11xx_status_t status = LR11XX_STATUS_ERROR; const uint8_t cbuffer[LR11XX_RADIO_SET_RX_CMD_LENGTH] = { @@ -433,6 +448,17 @@ lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step( const void* contex { break; } + + if( ( lna_mode == LR11XX_RADIO_LNA_MODE_SINGLE_RFI_P_LF0 ) || + ( lna_mode == LR11XX_RADIO_LNA_MODE_SINGLE_RFI_N_LF0 ) ) + { + status = lr11xx_radio_set_lna_mode( context, lna_mode ); + if( status != LR11XX_STATUS_OK ) + { + break; + } + } + } while( 0 ); return status; @@ -1292,6 +1318,10 @@ uint16_t lr11xx_radio_convert_nb_symb_to_mant_exp( const uint16_t nb_symbol, uin return mant_loc << ( 2 * exp_loc + 1 ); } +lr11xx_status_t lr11xx_radio_set_lna_mode( const void* context, lr11xx_radio_lna_mode_t lna_config ) +{ + return lr11xx_regmem_write_regmem32_mask( context, 0x00F3008C, 0xF0, lna_config << 4 ); +} /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.h b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.h index 0745c41..0392713 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.h +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio.h @@ -285,6 +285,33 @@ lr11xx_status_t lr11xx_radio_set_lora_public_network( const void* */ lr11xx_status_t lr11xx_radio_set_rx( const void* context, const uint32_t timeout_in_ms ); +/*! + * @brief Start RX operations with a timeout in millisecond and configure the LNA LF0 mode + * + * This command sets the LR11XX to RX mode and configures the LNA LF0 mode. The radio must have been configured before + * using this command with @ref lr11xx_radio_set_pkt_type + * + * This command must be issued only for sub-GHz RX operations as it configures the LNA LF0, which is only used for + * sub-GHz Rx operations. + * + * By default, the timeout parameter allows to return automatically to standby RC mode if no packets have been received + * after a certain amount of time. This behavior can be altered by @ref lr11xx_radio_set_rx_tx_fallback_mode and @ref + * lr11xx_radio_auto_tx_rx. + * + * @remark To set the radio in Rx continuous mode, the function @ref lr11xx_radio_set_rx_with_timeout_in_rtc_step has to + * be called with \p timeout_in_rtc_step set to 0xFFFFFF + * + * @param [in] context Chip implementation context + * @param [in] timeout_in_ms The timeout configuration for RX operation + * @param [in] lna_mode Path to use for reception + * + * @returns Operation status + * + * @see lr11xx_radio_set_pkt_type, lr11xx_radio_set_rx_tx_fallback_mode, lr11xx_radio_set_lna_mode + */ +lr11xx_status_t lr11xx_radio_set_rx_and_lna_mode( const void* context, const uint32_t timeout_in_ms, + lr11xx_radio_lna_mode_t lna_mode ); + /*! * @brief Start RX operations with a timeout in RTC step * @@ -318,6 +345,44 @@ lr11xx_status_t lr11xx_radio_set_rx( const void* context, const uint32_t timeout */ lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step( const void* context, const uint32_t timeout_in_rtc_step ); +/*! + * @brief Start RX operations with a timeout in RTC step and configure the LNA LF0 mode + * + * This command sets the LR11XX to RX mode and configures the LNA LF0 mode. The radio must have been configured before + * using this command with @ref lr11xx_radio_set_pkt_type It internally calls lr11xx_radio_set_lna_mode. This command + * must be issued only for sub-GHz RX operations as it configures the LNA LF0, which is only used for sub-GHz Rx + * operations. + * + * By default, the timeout parameter allows to return automatically to standby RC mode if no packets have been received + * after a certain amount of time. This behavior can be altered by @ref lr11xx_radio_set_rx_tx_fallback_mode and @ref + * lr11xx_radio_auto_tx_rx. + * + * The timeout duration is obtained by: + * \f$ timeout\_duration\_ms = timeout \times \frac{1}{32.768} \f$ + * + * Maximal timeout value is 0xFFFFFF, which gives a maximal timeout of 511 seconds. + * + * The timeout argument can also have the following special values: + * + * + *
Special values Meaning
0x000000 RX single: LR11XX stays in RX mode until a + * packet is received, then switch to standby RC mode
0xFFFFFF + * RX continuous: LR11XX stays in RX mode even after reception of a + * packet + *
+ * + * @param [in] context Chip implementation context + * @param [in] timeout_in_rtc_step The timeout configuration for RX operation + * @param [in] lna_mode Path to use for reception + * + * @returns Operation status + * + * @see lr11xx_radio_set_pkt_type, lr11xx_radio_set_rx_tx_fallback_mode + */ +lr11xx_status_t lr11xx_radio_set_rx_with_timeout_in_rtc_step_and_lna_mode( const void* context, + const uint32_t timeout_in_rtc_step, + lr11xx_radio_lna_mode_t lna_mode ); + /*! * @brief Start TX operations * @@ -954,6 +1019,22 @@ lr11xx_status_t lr11xx_radio_apply_high_acp_workaround( const void* context ); */ uint16_t lr11xx_radio_convert_nb_symb_to_mant_exp( const uint16_t nb_symbol, uint8_t* mant, uint8_t* exp ); +/** + * @brief Configure LNA LF0 mode + * + * @remark This function shall be called after each call to lr11xx_radio_set_rx or + * lr11xx_radio_set_rx_with_timeout_in_rtc_step to be taken into account. Helper functions + * lr11xx_radio_set_rx_on_lna_path or lr11xx_radio_set_rx_with_timeout_in_rtc_step_on_lna_path can be used instead. + * + * @param [in] context Chip implementation context + * @param [in] lna_mode Value to put in the register, enum type + * + * @returns Operation status + * + * @see lr11xx_radio_set_rx_on_lna_path, lr11xx_radio_set_rx_with_timeout_in_rtc_step_on_lna_path + */ +lr11xx_status_t lr11xx_radio_set_lna_mode( const void* context, lr11xx_radio_lna_mode_t lna_mode ); + #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio_types.h b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio_types.h index e3cc32e..4794f41 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio_types.h +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_radio_types.h @@ -628,6 +628,18 @@ typedef struct lr11xx_radio_rssi_calibration_table_s int16_t gain_offset; //!< Used to set gain offset value for RSSI calibration } lr11xx_radio_rssi_calibration_table_t; +/*! + * @brief Values to use to setup LNA LF0 configuration + * + * LNA can be configured in either of the 3 modes: Single N, Single P or differential (which is default) + * + */ +typedef enum +{ + LR11XX_RADIO_LNA_MODE_SINGLE_RFI_N_LF0 = 1, //!< Use only RFI_N_LF0 antenna + LR11XX_RADIO_LNA_MODE_SINGLE_RFI_P_LF0 = 2, //!< Use only RFI_P_LF0 antenna + LR11XX_RADIO_LNA_MODE_DIFFERENTIAL_LF0 = 3 //!< Configure LNA LF0 in differential mode (default) +} lr11xx_radio_lna_mode_t; /* * ----------------------------------------------------------------------------- * --- PUBLIC FUNCTIONS PROTOTYPES --------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_rttof.c b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_rttof.c index 4d06b48..166ffab 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_rttof.c +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_rttof.c @@ -178,7 +178,7 @@ int32_t lr11xx_rttof_distance_raw_to_meter( lr11xx_radio_lora_bw_t rttof_bw, } int32_t retval = raw_distance; - if( raw_distance >= ( 1 << ( bitcnt - 1 ) ) ) + if( raw_distance >= (uint32_t)( 1 << ( bitcnt - 1 ) ) ) { retval -= ( 1 << bitcnt ); } diff --git a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_wifi.c b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_wifi.c index 9c1312a..bd6de6e 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_wifi.c +++ b/lbm_lib/smtc_modem_core/radio_drivers/lr11xx_driver/src/lr11xx_wifi.c @@ -567,13 +567,13 @@ uint32_t lr11xx_wifi_get_consumption_nah( lr11xx_system_reg_mode_t regulator, lr ( ( float ) timing.demodulation_us * LR11XX_WIFI_DEMODULATION_NA ) + ( ( float ) timing.rx_correlation_us * LR11XX_WIFI_CORRELATION_NA ); - wifi_scan_consumption_nah = wifi_scan_consumption_nah / - ( 3600000000.0 - ( ( float ) timing.rx_capture_us + ( float ) timing.demodulation_us + + wifi_scan_consumption_nah = (float) wifi_scan_consumption_nah / + ( (float) 3600000000.0 - ( ( float ) timing.rx_capture_us + ( float ) timing.demodulation_us + ( float ) timing.rx_correlation_us ) ); if( regulator == LR11XX_SYSTEM_REG_MODE_LDO ) { - wifi_scan_consumption_nah *= 2.0; + wifi_scan_consumption_nah *= (float) 2.0; } return ( uint32_t ) wifi_scan_consumption_nah; diff --git a/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/CHANGELOG.md b/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/CHANGELOG.md index d9ae520..07928fc 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/CHANGELOG.md +++ b/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.3.2] - 2023-12-15 + +### Changed +- `sx126x_set_gfsk_sync_word()` function - Remove memcpy usage + ## [2.3.1] - 2023-11-8 ### Fixed diff --git a/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x.c b/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x.c index b01d5a1..390ad2a 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x.c +++ b/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x.c @@ -36,8 +36,7 @@ * ----------------------------------------------------------------------------- * --- DEPENDENCIES ------------------------------------------------------------ */ - -#include // memcpy +#include #include "sx126x.h" #include "sx126x_hal.h" #include "sx126x_regs.h" @@ -1293,11 +1292,15 @@ sx126x_status_t sx126x_cfg_rx_boosted( const void* context, const bool state ) sx126x_status_t sx126x_set_gfsk_sync_word( const void* context, const uint8_t* sync_word, const uint8_t sync_word_len ) { sx126x_status_t status = SX126X_STATUS_ERROR; - uint8_t buf[8] = { 0 }; if( sync_word_len <= 8 ) { - memcpy( buf, sync_word, sync_word_len ); + uint8_t buf[8] = { 0 }; + + for( int i = 0; i < sync_word_len; i++ ) + { + buf[i] = sync_word[i]; + } status = sx126x_write_register( context, SX126X_REG_SYNCWORDBASEADDRESS, buf, 8 ); } diff --git a/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x_driver_version.h b/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x_driver_version.h index 6d97261..24d28f7 100644 --- a/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x_driver_version.h +++ b/lbm_lib/smtc_modem_core/radio_drivers/sx126x_driver/src/sx126x_driver_version.h @@ -56,7 +56,7 @@ extern "C" { #define SX126X_DRIVER_VERSION_MAJOR 2 #define SX126X_DRIVER_VERSION_MINOR 3 -#define SX126X_DRIVER_VERSION_PATCH 1 +#define SX126X_DRIVER_VERSION_PATCH 2 /* * ----------------------------------------------------------------------------- diff --git a/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner.c b/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner.c index 82a2498..5f8be34 100644 --- a/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner.c +++ b/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner.c @@ -164,7 +164,7 @@ static void rp_set_alarm( radio_planner_t* rp, const uint32_t alarm_in_ms ); static void rp_timer_irq( radio_planner_t* rp ); /** - * @brief rp_task_call_aborted excute the callback of the aborted tasks + * @brief rp_task_call_aborted execute the callback of the aborted tasks * * @param rp pointer to the radioplanner object itself */ @@ -315,8 +315,9 @@ rp_hook_status_t rp_task_enqueue( radio_planner_t* rp, const rp_task_t* task, ui if( ( task->state == RP_TASK_STATE_SCHEDULE ) && ( ( ( int32_t ) ( task->start_time_ms - now ) <= 0 ) ) ) { - SMTC_MODEM_HAL_TRACE_PRINTF( " RP: Task enqueue impossible. Task is in past start_time_ms:%d - now:%d = %d\n", - task->start_time_ms, now, task->start_time_ms - now ); + SMTC_MODEM_HAL_TRACE_PRINTF( + " RP: Task #%u enqueue impossible. Task is in past start_time_ms:%d - now:%d = %d\n", hook_id, + task->start_time_ms, now, task->start_time_ms - now ); return RP_TASK_STATUS_SCHEDULE_TASK_IN_PAST; } @@ -387,8 +388,8 @@ rp_hook_status_t rp_task_abort( radio_planner_t* rp, const uint8_t hook_id ) } #endif - rp->radio_irq_flag = true; // Fake soft IRQ to call user callback - rp->irq_timestamp_ms[rp->radio_task_id] = smtc_modem_hal_get_time_in_ms( ); + rp->radio_irq_flag = true; // Fake soft IRQ to call user callback + rp->irq_timestamp_ms[rp->radio_task_id] = smtc_modem_hal_get_time_in_ms( ); smtc_modem_hal_user_lbm_irq( ); } else @@ -432,7 +433,6 @@ rp_stats_t rp_get_stats( const radio_planner_t* rp ) void rp_callback( radio_planner_t* rp ) { - smtc_modem_hal_disable_modem_irq( ); if( ( rp->tasks[rp->radio_task_id].state == RP_TASK_STATE_RUNNING ) && ( rp->disable_failsafe != RP_DISABLE_FAILSAFE_KEY ) && ( ( int32_t ) ( rp->tasks[rp->radio_task_id].start_time_ms + 128000 - smtc_modem_hal_get_time_in_ms( ) ) < 0 ) ) @@ -441,14 +441,12 @@ void rp_callback( radio_planner_t* rp ) } if( ( rp->radio_irq_flag == false ) && ( rp->timer_irq_flag == false ) ) { - smtc_modem_hal_enable_modem_irq( ); return; } if( ( rp->radio_irq_flag == false ) && ( rp->timer_irq_flag == true ) ) { rp->timer_irq_flag = false; rp_timer_irq( rp ); - smtc_modem_hal_enable_modem_irq( ); return; } if( rp->radio_irq_flag == true ) @@ -460,21 +458,20 @@ void rp_callback( radio_planner_t* rp ) rp_irq_get_status( rp, rp->radio_task_id ); - rp_consumption_statistics_updated( rp, rp->radio_task_id, rp->irq_timestamp_ms[rp->radio_task_id] ); - if( rp->status[rp->radio_task_id] == RP_STATUS_LR_FHSS_HOP ) { - smtc_modem_hal_enable_modem_irq( ); return; } + // Compute statistics after LR-FHSS hopping interrupts to have the correct TOA and not only by hop + rp_consumption_statistics_updated( rp, rp->radio_task_id, rp->irq_timestamp_ms[rp->radio_task_id] ); + // Tx can be performed only if no activity detected on channel if( ( rp->status[rp->radio_task_id] == RP_STATUS_CAD_NEGATIVE ) && ( rp->tasks[rp->radio_task_id].type == RP_TASK_TYPE_CAD_TO_TX ) ) { rp->radio = TARGET_RADIO; rp_hook_callback( rp, rp->radio_task_id ); - smtc_modem_hal_enable_modem_irq( ); return; } @@ -484,7 +481,6 @@ void rp_callback( radio_planner_t* rp ) { rp->radio = TARGET_RADIO; rp_hook_callback( rp, rp->radio_task_id ); - smtc_modem_hal_enable_modem_irq( ); return; } @@ -495,7 +491,6 @@ void rp_callback( radio_planner_t* rp ) { rp->radio = TARGET_RADIO; rp_hook_callback( rp, rp->radio_task_id ); - smtc_modem_hal_enable_modem_irq( ); return; } } @@ -527,7 +522,6 @@ void rp_callback( radio_planner_t* rp ) // Shut Down the TCXO smtc_modem_hal_stop_radio_tcxo( ); } - smtc_modem_hal_enable_modem_irq( ); } bool rp_get_irq_flag( void* obj ) @@ -625,8 +619,10 @@ static void rp_task_arbiter( radio_planner_t* rp, const char* caller_func_name ) { // Next task exists int32_t delay = ( int32_t ) ( rp->priority_task.start_time_ms - now ); SMTC_MODEM_HAL_RP_TRACE_PRINTF( - " RP: Arbiter has been called by %s and priority-task #%d, timer hook #%d, delay %d, now %d\n ", - caller_func_name, rp->priority_task.hook_id, rp->timer_hook_id, delay, now ); + " RP: Arbiter has been called by %s and priority-task #%d, timer hook #%d, delay %d, now %d, start_time_ms " + "%u\n ", + caller_func_name, rp->priority_task.hook_id, rp->timer_hook_id, delay, now, + rp->priority_task.start_time_ms ); // Case where the high priority task is in the past, error case if( delay < 0 ) @@ -669,8 +665,6 @@ static void rp_task_arbiter( radio_planner_t* rp, const char* caller_func_name ) RAL_STATUS_OK ); SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_clear_irq_status( TARGET_RAL, RAL_IRQ_ALL ) == RAL_STATUS_OK ); - smtc_modem_hal_radio_irq_clear_pending( ); - SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_sleep( TARGET_RAL, true ) == RAL_STATUS_OK ); rp->radio_irq_flag = false; @@ -1146,16 +1140,23 @@ static void rp_consumption_statistics_updated( radio_planner_t* rp, const uint8_ uint32_t radio_t = 0, process_t = 0; uint32_t tx_freq_hz = 0; - if( rp->tasks[hook_id].type == RP_TASK_TYPE_RX_LORA ) + // TODO RP_TASK_TYPE_CAD_TO_TX, RP_TASK_TYPE_USER, RP_TASK_TYPE_NONE, + + if( ( rp->tasks[hook_id].type == RP_TASK_TYPE_RX_LORA ) || ( rp->tasks[hook_id].type == RP_TASK_TYPE_CAD ) || + ( rp->tasks[hook_id].type == RP_TASK_TYPE_CAD_TO_RX ) ) { + bool enable_boost_mode = false; + ral_cfg_rx_boosted( TARGET_RAL_FOR_HOOK_ID, enable_boost_mode ); ral_get_lora_rx_consumption_in_ua( TARGET_RAL_FOR_HOOK_ID, rp->radio_params[hook_id].rx.lora.mod_params.bw, - false, µ_ampere_radio ); + enable_boost_mode, µ_ampere_radio ); } - else if( rp->tasks[hook_id].type == RP_TASK_TYPE_RX_FSK ) + else if( ( rp->tasks[hook_id].type == RP_TASK_TYPE_RX_FSK ) || ( rp->tasks[hook_id].type == RP_TASK_TYPE_LBT ) ) { + bool enable_boost_mode = false; + ral_cfg_rx_boosted( TARGET_RAL_FOR_HOOK_ID, enable_boost_mode ); ral_get_gfsk_rx_consumption_in_ua( TARGET_RAL_FOR_HOOK_ID, rp->radio_params[hook_id].rx.gfsk.mod_params.br_in_bps, - rp->radio_params[hook_id].rx.gfsk.mod_params.bw_dsb_in_hz, false, µ_ampere_radio ); + rp->radio_params[hook_id].rx.gfsk.mod_params.bw_dsb_in_hz, enable_boost_mode, µ_ampere_radio ); } else if( rp->tasks[hook_id].type == RP_TASK_TYPE_TX_LORA ) { @@ -1169,13 +1170,15 @@ static void rp_consumption_statistics_updated( radio_planner_t* rp, const uint8_ rp->radio_params[hook_id].tx.gfsk.rf_freq_in_hz, µ_ampere_radio ); tx_freq_hz = rp->radio_params[hook_id].tx.gfsk.rf_freq_in_hz; } - // else if( rp->tasks[hook_id].type == RP_TASK_TYPE_TX_LR_FHSS ) // TODO uncomment when LR-FHSS consumption will be - // developed - // { - // ral_get_tx_consumption_in_ua( TARGET_RAL_FOR_HOOK_ID, rp->radio_params[hook_id].tx.lr_fhss.output_pwr_in_dbm, - // rp->radio_params[hook_id].tx.lr_fhss.ral_lr_fhss_params.rf_freq_in_hz, - // µ_ampere_radio ); - // } + else if( rp->tasks[hook_id].type == RP_TASK_TYPE_TX_LR_FHSS ) + { + // The power and duty-cycle are computed only on the center_frequency_in_hz and not on all hopping + ral_get_tx_consumption_in_ua( TARGET_RAL_FOR_HOOK_ID, rp->radio_params[hook_id].tx.lr_fhss.output_pwr_in_dbm, + rp->radio_params[hook_id].tx.lr_fhss.ral_lr_fhss_params.center_frequency_in_hz, + µ_ampere_radio ); + + tx_freq_hz = rp->radio_params[hook_id].tx.lr_fhss.ral_lr_fhss_params.center_frequency_in_hz; + } if( ( rp->tasks[hook_id].type == RP_TASK_TYPE_GNSS_SNIFF ) || ( rp->tasks[hook_id].type == RP_TASK_TYPE_GNSS_RSSI ) || @@ -1208,9 +1211,9 @@ static void rp_consumption_statistics_updated( radio_planner_t* rp, const uint8_ void rp_radio_irq_callback( void* obj ) { - radio_planner_t* rp = ( ( radio_planner_t* ) obj ); - rp->radio_irq_flag = true; - rp->irq_timestamp_ms[rp->radio_task_id] = smtc_modem_hal_get_time_in_ms( ); + radio_planner_t* rp = ( ( radio_planner_t* ) obj ); + rp->radio_irq_flag = true; + rp->irq_timestamp_ms[rp->radio_task_id] = smtc_modem_hal_get_time_in_ms( ); smtc_modem_hal_user_lbm_irq( ); } diff --git a/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner_hook_id_defs.h b/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner_hook_id_defs.h index 8847e32..e23f194 100644 --- a/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner_hook_id_defs.h +++ b/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner_hook_id_defs.h @@ -66,6 +66,10 @@ enum RP_HOOK_ID_DEF RP_HOOK_ID_DIRECT_RP_ACCESS_WIFI, #endif +#if defined( ADD_RELAY_RX ) + RP_HOOK_ID_RELAY_FORWARD_RXR, +#endif + #if defined( ADD_CLASS_B ) RP_HOOK_ID_CLASS_B_BEACON, RP_HOOK_ID_LR1MAC_STACK = RP_HOOK_ID_CLASS_B_BEACON + NUMBER_OF_STACKS, @@ -76,14 +80,22 @@ enum RP_HOOK_ID_DEF RP_HOOK_ID_LBT = RP_HOOK_ID_LR1MAC_STACK + NUMBER_OF_STACKS, #if defined( ADD_CSMA ) - RP_HOOK_ID_CAD, + RP_HOOK_ID_CAD = RP_HOOK_ID_LBT + NUMBER_OF_STACKS, #endif #if defined( ADD_CLASS_B ) - RP_HOOK_ID_CLASS_B_PING_SLOT, +#if defined( ADD_CSMA ) + RP_HOOK_ID_CLASS_B_PING_SLOT = RP_HOOK_ID_CAD + NUMBER_OF_STACKS, +#else + RP_HOOK_ID_CLASS_B_PING_SLOT = RP_HOOK_ID_LBT + NUMBER_OF_STACKS, +#endif RP_HOOK_ID_TEST_MODE = RP_HOOK_ID_CLASS_B_PING_SLOT + NUMBER_OF_STACKS, #else - RP_HOOK_ID_TEST_MODE, +#if defined( ADD_CSMA ) + RP_HOOK_ID_TEST_MODE = RP_HOOK_ID_CAD + NUMBER_OF_STACKS, +#else + RP_HOOK_ID_TEST_MODE = RP_HOOK_ID_LBT + NUMBER_OF_STACKS, +#endif #endif #if defined( ADD_ALMANAC ) @@ -98,7 +110,11 @@ enum RP_HOOK_ID_DEF RP_HOOK_ID_BLE_TX_BEACON, #endif -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_RX ) + RP_HOOK_ID_RELAY_RX_CAD, +#endif // ADD_RELAY_RX + +#if defined( ADD_RELAY_TX ) RP_HOOK_ID_RELAY_TX, #if defined( ADD_CLASS_C ) RP_HOOK_ID_CLASS_C = RP_HOOK_ID_RELAY_TX + NUMBER_OF_STACKS, @@ -106,7 +122,6 @@ enum RP_HOOK_ID_DEF #else RP_HOOK_ID_MAX = RP_HOOK_ID_RELAY_TX + NUMBER_OF_STACKS, #endif - #else #if defined( ADD_CLASS_C ) RP_HOOK_ID_CLASS_C, @@ -114,7 +129,7 @@ enum RP_HOOK_ID_DEF #else RP_HOOK_ID_MAX, #endif -#endif // RELAY_TX +#endif // ADD_RELAY_TX }; #endif diff --git a/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner_types.h b/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner_types.h index a03e32f..3b6812f 100644 --- a/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner_types.h +++ b/lbm_lib/smtc_modem_core/radio_planner/src/radio_planner_types.h @@ -61,7 +61,7 @@ extern "C" { * --- PUBLIC CONSTANTS -------------------------------------------------------- */ -// clang-format off +/* clang-format off */ /* * Maximum number of objects that can be attached to the scheduler @@ -104,14 +104,16 @@ extern "C" { /*! * */ +#ifndef RP_MCU_FAIRNESS_DELAY_MS #define RP_MCU_FAIRNESS_DELAY_MS 10 +#endif /*! * */ #define RP_DISABLE_FAILSAFE_KEY 0xF00D4BEE -// clang-format on +/* clang-format on */ /* * ----------------------------------------------------------------------------- @@ -141,7 +143,7 @@ typedef struct rp_radio_params_s ralf_params_lora_t lora; ralf_params_lora_cad_t lora_cad; }; - uint32_t timeout_in_ms; + uint32_t timeout_in_ms; ral_lora_cad_params_t cad; union { @@ -221,9 +223,9 @@ typedef enum rp_next_state_status_e */ typedef struct rp_task_s { - uint8_t hook_id; - rp_task_types_t type; - void ( *launch_task_callbacks )( void* ); + uint8_t hook_id; + rp_task_types_t type; + void ( *launch_task_callbacks )( void* ); uint8_t priority; bool schedule_task_low_priority; rp_task_states_t state; diff --git a/lbm_lib/smtc_modem_core/smtc_modem.c b/lbm_lib/smtc_modem_core/smtc_modem.c index 960d420..370ab51 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem.c +++ b/lbm_lib/smtc_modem_core/smtc_modem.c @@ -98,20 +98,30 @@ #include "smtc_modem_geolocation_api.h" #endif -#if defined( RELAY_TX ) +#if defined( ADD_RELAY_TX ) #include "smtc_modem_relay_api.h" #include "relay_tx_api.h" #endif +#if defined( ADD_RELAY_RX ) +#include "relay_rx_api.h" +#endif + #if defined( ADD_SMTC_STORE_AND_FORWARD ) #include "store_and_forward_flash.h" #endif +#if defined( USE_LR11XX_CE ) && ( ADD_FUOTA == 2 ) +#include "aes.h" +#endif // USE_LR11XX_CE && ( ADD_FUOTA == 2 ) + /* * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- */ - +#if defined( BYPASS_CHECK_TEST_MODE ) +#define RETURN_BUSY_IF_TEST_MODE( ) +#else #define RETURN_BUSY_IF_TEST_MODE( ) \ do \ { \ @@ -120,6 +130,7 @@ return SMTC_MODEM_RC_BUSY; \ } \ } while( 0 ) +#endif // BYPASS_CHECK_TEST_MODE #define RETURN_INVALID_IF_NULL( x ) \ do \ @@ -163,6 +174,7 @@ typedef struct modem_key_ctx_s uint32_t appkey_crc; uint8_t gen_appkey_crc_status; uint32_t gen_appkey_crc; + uint8_t data_block_int_key[16]; uint8_t rfu[6]; uint32_t crc; // !! crc MUST be the last field of the structure !! } modem_key_ctx_t; @@ -194,12 +206,14 @@ struct uint32_t modem_appkey_crc; uint8_t modem_gen_appkey_status; uint32_t modem_gen_appkey_crc; + uint8_t modem_data_block_int_key[16]; } smtc_modem_key_ctx; #define modem_appkey_status smtc_modem_key_ctx.modem_appkey_status #define modem_appkey_crc smtc_modem_key_ctx.modem_appkey_crc #define modem_gen_appkey_status smtc_modem_key_ctx.modem_gen_appkey_status #define modem_gen_appkey_crc smtc_modem_key_ctx.modem_gen_appkey_crc +#define modem_data_block_int_key smtc_modem_key_ctx.modem_data_block_int_key /* * ----------------------------------------------------------------------------- @@ -249,7 +263,7 @@ void smtc_modem_init( void ( *callback_event )( void ) ) smtc_secure_element_init( ); modem_supervisor_init( ); modem_context_init_light( callback_event, &modem_radio_planner ); - modem_tx_protcol_manager_init( &modem_radio_planner ); + modem_tx_protocol_manager_init( &modem_radio_planner ); // If lr11xx crypto engine is used for crypto #if defined( USE_LR11XX_CE ) modem_load_appkey_context( ); @@ -369,6 +383,41 @@ smtc_modem_return_code_t smtc_modem_set_deveui( uint8_t stack_id, const uint8_t return return_code; } +#if defined( USE_LR11XX_CE ) && ( ADD_FUOTA == 2 ) +smtc_modem_return_code_t smtc_modem_get_data_block_int_key( uint8_t stack_id, + uint8_t data_block_int_key[SMTC_MODEM_KEY_LENGTH] ) +{ + RETURN_BUSY_IF_TEST_MODE( ); + RETURN_INVALID_IF_NULL( data_block_int_key ); + + smtc_modem_return_code_t return_code = SMTC_MODEM_RC_OK; + + memcpy( data_block_int_key, modem_data_block_int_key, SMTC_MODEM_KEY_LENGTH ); + + return return_code; +} + +smtc_modem_return_code_t smtc_modem_derive_and_set_data_block_int_key( uint8_t stack_id, + const uint8_t gen_appkey[SMTC_MODEM_KEY_LENGTH] ) +{ + RETURN_BUSY_IF_TEST_MODE( ); + RETURN_INVALID_IF_NULL( gen_appkey ); + + smtc_modem_return_code_t return_code = SMTC_MODEM_RC_OK; + + memset( modem_data_block_int_key, 0, SMTC_MODEM_KEY_LENGTH ); + + uint8_t b0[16] = { 0 }; + // Derive key + b0[0] = 0x30; + aes_context aes_ctx = { 0 }; + smtc_aes_set_key( gen_appkey, 16, &aes_ctx ); + smtc_aes_encrypt( b0, modem_data_block_int_key, &aes_ctx ); + + return return_code; +} +#endif // USE_LR11XX_CE + smtc_modem_return_code_t smtc_modem_set_appkey( uint8_t stack_id, const uint8_t appkey[SMTC_MODEM_KEY_LENGTH] ) { RETURN_BUSY_IF_TEST_MODE( ); @@ -387,7 +436,7 @@ smtc_modem_return_code_t smtc_modem_set_appkey( uint8_t stack_id, const uint8_t // To prevent too much flash access first check crc on key in case of Hardware Secure element #if defined( USE_LR11XX_CE ) - uint32_t new_crc = crc( appkey, 16 ); + uint32_t new_crc = crc( appkey, SMTC_MODEM_KEY_LENGTH ); if( ( modem_gen_appkey_status == MODEM_KEY_CRC_STATUS_INVALID ) || ( modem_gen_appkey_crc != new_crc ) ) { @@ -401,6 +450,13 @@ smtc_modem_return_code_t smtc_modem_set_appkey( uint8_t stack_id, const uint8_t #if defined( USE_LR11XX_CE ) else { +#if defined( ADD_FUOTA ) && ( ADD_FUOTA == 2 ) + if( smtc_modem_derive_and_set_data_block_int_key( stack_id, appkey ) != SMTC_MODEM_RC_OK ) + { + return_code = SMTC_MODEM_RC_FAIL; + } +#endif + // Store appkey crc and status modem_store_key_context( ); } @@ -427,7 +483,7 @@ smtc_modem_return_code_t smtc_modem_set_nwkkey( uint8_t stack_id, const uint8_t // To prevent too much flash access first check crc on key in case of Hardware Secure element #if defined( USE_LR11XX_CE ) - uint32_t new_crc = crc( nwkkey, 16 ); + uint32_t new_crc = crc( nwkkey, SMTC_MODEM_KEY_LENGTH ); if( ( modem_appkey_status == MODEM_KEY_CRC_STATUS_INVALID ) || ( modem_appkey_crc != new_crc ) ) { @@ -590,7 +646,8 @@ smtc_modem_return_code_t smtc_modem_adr_set_profile( // update profile in lorawan stack status = lorawan_api_dr_strategy_set( MOBILE_LOWPER_DR_DISTRIBUTION, stack_id ); break; - case SMTC_MODEM_ADR_PROFILE_CUSTOM: { + case SMTC_MODEM_ADR_PROFILE_CUSTOM: + { uint16_t mask_dr_allowed = lorawan_api_mask_tx_dr_channel_up_dwell_time_check( stack_id ); uint8_t adr_distribution_tab[SMTC_MODEM_CUSTOM_ADR_DATA_LENGTH] = { 0 }; @@ -607,7 +664,8 @@ smtc_modem_return_code_t smtc_modem_adr_set_profile( status = lorawan_api_dr_strategy_set( USER_DR_DISTRIBUTION, stack_id ); break; } - default: { + default: + { SMTC_MODEM_HAL_TRACE_ERROR( "Unknown adr profile %d\n ", adr_profile ); return SMTC_MODEM_RC_INVALID; } @@ -720,7 +778,6 @@ smtc_modem_return_code_t smtc_modem_request_uplink( uint8_t stack_id, uint8_t f_ smtc_modem_return_code_t smtc_modem_get_event( smtc_modem_event_t* event, uint8_t* event_pending_count ) { - RETURN_BUSY_IF_TEST_MODE( ); RETURN_INVALID_IF_NULL( event ); RETURN_INVALID_IF_NULL( event_pending_count ); @@ -804,7 +861,7 @@ smtc_modem_return_code_t smtc_modem_get_event( smtc_modem_event_t* event, uint8_ break; #endif // ADD_SMTC_LFU -#ifdef RELAY_TX +#if defined( ADD_RELAY_TX ) case SMTC_MODEM_EVENT_RELAY_TX_DYNAMIC: case SMTC_MODEM_EVENT_RELAY_TX_MODE: case SMTC_MODEM_EVENT_RELAY_TX_SYNC: @@ -812,6 +869,18 @@ smtc_modem_return_code_t smtc_modem_get_event( smtc_modem_event_t* event, uint8_ break; #endif +#if defined( ADD_RELAY_RX ) + case SMTC_MODEM_EVENT_RELAY_RX_RUNNING: + event->event_data.relay_rx.status = get_modem_event_status( event->event_type ); + break; +#endif + + case SMTC_MODEM_EVENT_TEST_MODE: + event->event_data.test_mode_status.status = get_modem_event_status( event->event_type ); + break; + case SMTC_MODEM_EVENT_REGIONAL_DUTY_CYCLE: + event->event_data.regional_duty_cycle.status = get_modem_event_status( event->event_type ); + break; case SMTC_MODEM_EVENT_DOWNDATA: case SMTC_MODEM_EVENT_ALARM: case SMTC_MODEM_EVENT_JOINED: @@ -1005,7 +1074,7 @@ smtc_modem_return_code_t smtc_modem_leave_network( uint8_t stack_id ) smtc_modem_return_code_t return_code = SMTC_MODEM_RC_OK; RETURN_BUSY_IF_TEST_MODE( ); smtc_modem_set_class( stack_id, SMTC_MODEM_CLASS_A ); - tx_protocol_manager_abort (); + tx_protocol_manager_abort( ); modem_supervisor_abort_tasks_in_range( stack_id * NUMBER_OF_TASKS, ( ( stack_id + 1 ) * NUMBER_OF_TASKS ) - 1 ); lorawan_api_join_status_clear( stack_id ); @@ -1357,11 +1426,11 @@ smtc_modem_return_code_t smtc_modem_csma_get_state( uint8_t stack_id, bool* enab return SMTC_MODEM_RC_OK; } -smtc_modem_return_code_t smtc_modem_csma_set_parameters( uint8_t stack_id, uint8_t nb_bo_max, bool bo_enabled, - uint8_t max_ch_change ) +smtc_modem_return_code_t smtc_modem_csma_set_parameters( uint8_t stack_id, uint8_t max_ch_change, bool bo_enabled, + uint8_t nb_bo_max ) { RETURN_BUSY_IF_TEST_MODE( ); - if( smtc_lora_cad_bt_set_parameters( smtc_cad_get_obj( stack_id ), nb_bo_max, bo_enabled, max_ch_change ) != + if( smtc_lora_cad_bt_set_parameters( smtc_cad_get_obj( stack_id ), max_ch_change, bo_enabled, nb_bo_max ) != SMTC_LORA_CAD_OK ) { @@ -1384,7 +1453,6 @@ smtc_modem_return_code_t smtc_modem_csma_get_parameters( uint8_t stack_id, uint8 smtc_modem_return_code_t smtc_modem_get_charge( uint32_t* charge_mah ) { - RETURN_BUSY_IF_TEST_MODE( ); RETURN_INVALID_IF_NULL( charge_mah ); *charge_mah = rp_stats_get_charge_mah( &modem_radio_planner.stats ); @@ -1392,9 +1460,8 @@ smtc_modem_return_code_t smtc_modem_get_charge( uint32_t* charge_mah ) return SMTC_MODEM_RC_OK; } -smtc_modem_return_code_t smtc_modem_get_rp_stats_to_array( uint8_t* stats_array, uint8_t* stats_array_length ) +smtc_modem_return_code_t smtc_modem_get_rp_stats_to_array( uint8_t* stats_array, uint16_t* stats_array_length ) { - RETURN_BUSY_IF_TEST_MODE( ); RETURN_INVALID_IF_NULL( stats_array ); RETURN_INVALID_IF_NULL( stats_array_length ); @@ -1442,7 +1509,7 @@ smtc_modem_return_code_t smtc_modem_get_rp_stats_to_array( uint8_t* stats_array, stats_array[*stats_array_length + 30] = ( modem_radio_planner.stats.none_consumption_ma[i] >> 8 ) & 0xFF; stats_array[*stats_array_length + 31] = ( modem_radio_planner.stats.none_consumption_ma[i] & 0xFF ); - *stats_array_length = 32 * i; + *stats_array_length += 32; } return SMTC_MODEM_RC_OK; @@ -1450,8 +1517,6 @@ smtc_modem_return_code_t smtc_modem_get_rp_stats_to_array( uint8_t* stats_array, smtc_modem_return_code_t smtc_modem_reset_charge( void ) { - RETURN_BUSY_IF_TEST_MODE( ); - rp_stats_init( &modem_radio_planner.stats ); return SMTC_MODEM_RC_OK; } @@ -1613,7 +1678,8 @@ smtc_modem_return_code_t smtc_modem_set_class( uint8_t stack_id, smtc_modem_clas switch( lorawan_class ) { - case SMTC_MODEM_CLASS_A: { + case SMTC_MODEM_CLASS_A: + { #ifdef ADD_CLASS_B lorawan_class_b_management_enable( stack_id, false, 0 ); #endif @@ -1623,7 +1689,8 @@ smtc_modem_return_code_t smtc_modem_set_class( uint8_t stack_id, smtc_modem_clas break; } #ifdef ADD_CLASS_B - case SMTC_MODEM_CLASS_B: { + case SMTC_MODEM_CLASS_B: + { #ifdef ADD_CLASS_C lorawan_api_class_c_enabled( false, stack_id ); #endif // ADD_CLASS_C @@ -1632,7 +1699,8 @@ smtc_modem_return_code_t smtc_modem_set_class( uint8_t stack_id, smtc_modem_clas } #endif // ADD_CLASS_B #ifdef ADD_CLASS_C - case SMTC_MODEM_CLASS_C: { + case SMTC_MODEM_CLASS_C: + { #ifdef ADD_CLASS_B lorawan_class_b_management_enable( stack_id, false, 0 ); #endif // ADD_CLASS_B @@ -1704,9 +1772,9 @@ smtc_modem_return_code_t smtc_modem_multicast_set_grp_config( uint8_t stack_id, modem_rc = SMTC_MODEM_RC_INVALID; break; case LORAWAN_MC_RC_ERROR_BUSY: - // intentional fallthrought + // intentional fallthrough case LORAWAN_MC_RC_ERROR_CRYPTO: - // intentional fallthrought + // intentional fallthrough default: modem_rc = SMTC_MODEM_RC_FAIL; break; @@ -1760,16 +1828,16 @@ smtc_modem_return_code_t smtc_modem_multicast_class_c_start_session( uint8_t sta modem_rc = SMTC_MODEM_RC_OK; break; case LORAWAN_MC_RC_ERROR_PARAM: - // intentional fallthrought + // intentional fallthrough case LORAWAN_MC_RC_ERROR_INCOMPATIBLE_SESSION: - // intentional fallthrought + // intentional fallthrough case LORAWAN_MC_RC_ERROR_BAD_ID: modem_rc = SMTC_MODEM_RC_INVALID; break; case LORAWAN_MC_RC_ERROR_BUSY: - // intentional fallthrought + // intentional fallthrough case LORAWAN_MC_RC_ERROR_CLASS_NOT_ENABLED: - // intentional fallthrought + // intentional fallthrough default: modem_rc = SMTC_MODEM_RC_FAIL; break; @@ -1879,16 +1947,16 @@ smtc_modem_return_code_t smtc_modem_multicast_class_b_start_session( modem_rc = SMTC_MODEM_RC_OK; break; case LORAWAN_MC_RC_ERROR_PARAM: - // intentional fallthrought + // intentional fallthrough case LORAWAN_MC_RC_ERROR_INCOMPATIBLE_SESSION: - // intentional fallthrought + // intentional fallthrough case LORAWAN_MC_RC_ERROR_BAD_ID: modem_rc = SMTC_MODEM_RC_INVALID; break; case LORAWAN_MC_RC_ERROR_BUSY: - // intentional fallthrought + // intentional fallthrough case LORAWAN_MC_RC_ERROR_CLASS_NOT_ENABLED: - // intentional fallthrought + // intentional fallthrough default: modem_rc = SMTC_MODEM_RC_FAIL; break; @@ -2676,7 +2744,6 @@ static smtc_modem_return_code_t smtc_modem_send_tx( uint8_t stack_id, uint8_t f_ const uint8_t* payload, uint8_t payload_length, bool emergency ) { smtc_modem_return_code_t return_code = SMTC_MODEM_RC_OK; - SMTC_MODEM_HAL_TRACE_INFO( "add task user \n" ); smtc_modem_status_mask_t status_mask = modem_get_status( stack_id ); if( ( ( status_mask & SMTC_MODEM_STATUS_JOINED ) != SMTC_MODEM_STATUS_JOINED ) || ( ( status_mask & SMTC_MODEM_STATUS_MUTE ) == SMTC_MODEM_STATUS_MUTE ) || @@ -2702,6 +2769,7 @@ static smtc_modem_return_code_t smtc_modem_send_tx( uint8_t stack_id, uint8_t f_ } else { + SMTC_MODEM_HAL_TRACE_INFO( "add send task\n" ); lorawan_send_add_task( stack_id, f_port, true, confirmed, payload, payload_length, emergency, 0 ); } @@ -2754,7 +2822,8 @@ static void modem_store_key_context( void ) ctx.appkey_crc_status = modem_appkey_status; ctx.gen_appkey_crc = modem_gen_appkey_crc; ctx.gen_appkey_crc_status = modem_gen_appkey_status; - ctx.crc = crc( ( uint8_t* ) &ctx, sizeof( ctx ) - sizeof( ctx.crc ) ); + memcpy( ctx.data_block_int_key, modem_data_block_int_key, SMTC_MODEM_KEY_LENGTH ); + ctx.crc = crc( ( uint8_t* ) &ctx, sizeof( ctx ) - sizeof( ctx.crc ) ); smtc_modem_hal_context_store( CONTEXT_KEY_MODEM, 0, ( uint8_t* ) &ctx, sizeof( ctx ) ); // dummy context reading to ensure context store is done before exiting the function @@ -2773,10 +2842,11 @@ static void modem_load_appkey_context( void ) modem_appkey_crc = ctx.appkey_crc; modem_gen_appkey_status = ctx.gen_appkey_crc_status; modem_gen_appkey_crc = ctx.gen_appkey_crc; + memcpy( modem_data_block_int_key, ctx.data_block_int_key, SMTC_MODEM_KEY_LENGTH ); } else { - // crc of the context is not good anymore => restore key stasus to default + // crc of the context is not good anymore => restore key status to default ctx.appkey_crc = 0; ctx.appkey_crc_status = MODEM_KEY_CRC_STATUS_INVALID; ctx.gen_appkey_crc = 0; @@ -2790,7 +2860,7 @@ static void modem_load_appkey_context( void ) } #endif -#ifdef RELAY_TX +#if defined( ADD_RELAY_TX ) smtc_modem_return_code_t smtc_modem_relay_tx_get_activation_mode( uint8_t stack_id, smtc_modem_relay_tx_activation_mode_t* mode ) { @@ -2828,6 +2898,13 @@ smtc_modem_return_code_t smtc_modem_relay_tx_enable( uint8_t RETURN_BUSY_IF_TEST_MODE( ); RETURN_INVALID_IF_NULL( relay_config ); +#if defined( ADD_RELAY_RX ) + if( relay_rx_get_flag_started( ) == true ) + { + return SMTC_MODEM_RC_FAIL; + } +#endif // ADD_RELAY_RX + if( smtc_relay_tx_update_config( stack_id, ( relay_tx_config_t* ) relay_config ) != true ) { return SMTC_MODEM_RC_FAIL; diff --git a/lbm_lib/smtc_modem_core/smtc_modem_crypto/lr11xx_crypto_engine/lr11xx_ce.c b/lbm_lib/smtc_modem_core/smtc_modem_crypto/lr11xx_crypto_engine/lr11xx_ce.c index 166add5..06eda35 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_crypto/lr11xx_crypto_engine/lr11xx_ce.c +++ b/lbm_lib/smtc_modem_core/smtc_modem_crypto/lr11xx_crypto_engine/lr11xx_ce.c @@ -184,13 +184,11 @@ smtc_se_return_code_t smtc_secure_element_set_key( smtc_se_key_identifier_t key_ smtc_se_return_code_t status = SMTC_SE_RC_ERROR; - // convert key into lr11xx value first to check if returned key is not LR11XX_CRYPTO_KEYS_IDX_GP1 - lr11xx_crypto_keys_idx_t lr11xx_key_id = convert_key_id_from_se_to_lr11xx( key_id ); - - if( lr11xx_key_id == LR11XX_CRYPTO_KEYS_IDX_GP1 ) + if( key_id == SMTC_SE_DATA_BLOCK_INT_KEY ) { return SMTC_SE_RC_ERROR_INVALID_KEY_ID; } + lr11xx_crypto_keys_idx_t lr11xx_key_id = convert_key_id_from_se_to_lr11xx( key_id ); // lr11xx crypto operation needed: suspend modem radio access to secure this direct access SMTC_MODEM_HAL_PANIC_ON_FAILURE( modem_suspend_radio_access( ) == true ); @@ -356,6 +354,95 @@ smtc_se_return_code_t smtc_secure_element_derive_and_store_key( uint8_t* input, return status; } +smtc_se_return_code_t smtc_secure_element_derive_relay_session_keys( uint32_t dev_addr, uint8_t stack_id ) +{ + smtc_se_return_code_t status = SMTC_SE_RC_ERROR; + uint8_t key[16] = { 0 }; + uint8_t block[16]; + + memset( block, 0, sizeof( block ) ); + block[0] = 0x01; + + // lr11xx crypto operation needed: suspend modem radio access to secure this direct access + SMTC_MODEM_HAL_PANIC_ON_FAILURE( modem_suspend_radio_access( ) == true ); + + // key = RELAY_ROOT_WOR_S_KEY + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_aes_encrypt_01( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status, + convert_key_id_from_se_to_lr11xx( SMTC_SE_NWK_S_ENC_KEY ), block, 16, + key ) == LR11XX_STATUS_OK ); + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_set_key( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status, + convert_key_id_from_se_to_lr11xx( SMTC_SE_RELAY_ROOT_WOR_S_KEY ), + key ) == LR11XX_STATUS_OK ); + + if( status == SMTC_SE_RC_SUCCESS ) + { + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_store_to_flash( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status ) == LR11XX_STATUS_OK ); + } + + memset( block, 0, sizeof( block ) ); + block[0] = 0x01; + block[1] = ( uint8_t ) ( dev_addr ); + block[2] = ( uint8_t ) ( dev_addr >> 8 ); + block[3] = ( uint8_t ) ( dev_addr >> 16 ); + block[4] = ( uint8_t ) ( dev_addr >> 24 ); + + // key = SMTC_SE_RELAY_WOR_S_INT_KEY + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_aes_encrypt( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status, + convert_key_id_from_se_to_lr11xx( SMTC_SE_RELAY_ROOT_WOR_S_KEY ), block, 16, + key ) == LR11XX_STATUS_OK ); + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_set_key( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status, + convert_key_id_from_se_to_lr11xx( SMTC_SE_RELAY_WOR_S_INT_KEY ), + key ) == LR11XX_STATUS_OK ); + + if( status == SMTC_SE_RC_SUCCESS ) + { + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_store_to_flash( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status ) == LR11XX_STATUS_OK ); + } + + memset( block, 0, sizeof( block ) ); + block[0] = 0x02; + block[1] = ( uint8_t ) ( dev_addr ); + block[2] = ( uint8_t ) ( dev_addr >> 8 ); + block[3] = ( uint8_t ) ( dev_addr >> 16 ); + block[4] = ( uint8_t ) ( dev_addr >> 24 ); + + // key = SMTC_SE_RELAY_WOR_S_ENC_KEY + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_aes_encrypt( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status, + convert_key_id_from_se_to_lr11xx( SMTC_SE_RELAY_ROOT_WOR_S_KEY ), block, 16, + key ) == LR11XX_STATUS_OK ); + + if( status == SMTC_SE_RC_SUCCESS ) + { + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_store_to_flash( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status ) == LR11XX_STATUS_OK ); + } + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_set_key( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status, + convert_key_id_from_se_to_lr11xx( SMTC_SE_RELAY_WOR_S_ENC_KEY ), + key ) == LR11XX_STATUS_OK ); + + if( status == SMTC_SE_RC_SUCCESS ) + { + SMTC_MODEM_HAL_PANIC_ON_FAILURE( + lr11xx_crypto_store_to_flash( lr11xx_ctx, ( lr11xx_crypto_status_t* ) &status ) == LR11XX_STATUS_OK ); + } + + // lr11xx crypto operation done: resume modem radio access + SMTC_MODEM_HAL_PANIC_ON_FAILURE( modem_resume_radio_access( ) == true ); + + return status; +} + smtc_se_return_code_t smtc_secure_element_process_join_accept( smtc_se_join_req_identifier_t join_req_type, uint8_t* joineui, uint16_t dev_nonce, const uint8_t* enc_join_accept, @@ -594,6 +681,15 @@ static lr11xx_crypto_keys_idx_t convert_key_id_from_se_to_lr11xx( smtc_se_key_id case SMTC_SE_MC_NWK_S_KEY_3: id = LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_3; break; + case SMTC_SE_RELAY_ROOT_WOR_S_KEY: + id = LR11XX_CRYPTO_KEYS_IDX_GP1; + break; + case SMTC_SE_RELAY_WOR_S_INT_KEY: + id = LR11XX_CRYPTO_KEYS_IDX_RFU_0; + break; + case SMTC_SE_RELAY_WOR_S_ENC_KEY: + id = LR11XX_CRYPTO_KEYS_IDX_RFU_1; + break; case SMTC_SE_SLOT_RAND_ZERO_KEY: id = LR11XX_CRYPTO_KEYS_IDX_GP0; break; diff --git a/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.c b/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.c index a10f2a4..faa1651 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.c +++ b/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.c @@ -430,6 +430,15 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_derive_multicast_session_keys( return SMTC_MODEM_CRYPTO_RC_SUCCESS; } +smtc_modem_crypto_return_code_t smtc_modem_crypto_derive_relay_session_keys( uint32_t dev_addr, uint8_t stack_id ) +{ + if( smtc_secure_element_derive_relay_session_keys( dev_addr, stack_id ) != SMTC_SE_RC_SUCCESS ) + { + return SMTC_MODEM_CRYPTO_RC_ERROR_SECURE_ELEMENT; + } + return SMTC_MODEM_CRYPTO_RC_SUCCESS; +} + smtc_modem_crypto_return_code_t smtc_modem_crypto_get_class_b_rand( uint32_t beacon_epoch_time, uint32_t dev_addr, uint8_t rand[16], uint8_t stack_id ) { @@ -442,11 +451,11 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_get_class_b_rand( uint32_t bea } // a block filling - a_block[0] = ( beacon_epoch_time ) &0xFF; + a_block[0] = ( beacon_epoch_time ) & 0xFF; a_block[1] = ( beacon_epoch_time >> 8 ) & 0xFF; a_block[2] = ( beacon_epoch_time >> 16 ) & 0xFF; a_block[3] = ( beacon_epoch_time >> 24 ) & 0xFF; - a_block[4] = ( dev_addr ) &0xFF; + a_block[4] = ( dev_addr ) & 0xFF; a_block[5] = ( dev_addr >> 8 ) & 0xFF; a_block[6] = ( dev_addr >> 16 ) & 0xFF; a_block[7] = ( dev_addr >> 24 ) & 0xFF; @@ -595,8 +604,8 @@ static smtc_modem_crypto_return_code_t derive_session_key_1_0_x( smtc_se_key_ide comp_base[5] = net_id[1]; comp_base[6] = net_id[2]; - comp_base[7] = ( uint8_t )( ( dev_nonce >> 0 ) & 0xFF ); - comp_base[8] = ( uint8_t )( ( dev_nonce >> 8 ) & 0xFF ); + comp_base[7] = ( uint8_t ) ( ( dev_nonce >> 0 ) & 0xFF ); + comp_base[8] = ( uint8_t ) ( ( dev_nonce >> 8 ) & 0xFF ); if( smtc_secure_element_derive_and_store_key( comp_base, SMTC_SE_NWK_KEY, key_id, stack_id ) != SMTC_SE_RC_SUCCESS ) { diff --git a/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.h b/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.h index ba0c7c5..2881dff 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.h +++ b/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_modem_crypto.h @@ -136,7 +136,7 @@ typedef enum smtc_modem_crypto_addr_id_e smtc_modem_crypto_return_code_t smtc_modem_crypto_payload_encrypt( const uint8_t* buffer, uint16_t size, smtc_se_key_identifier_t key_id, uint32_t address, uint8_t dir, uint32_t frame_counter, - uint8_t* enc_buffer,uint8_t stack_id ); + uint8_t* enc_buffer, uint8_t stack_id ); /** * @brief Computes the payload decryption @@ -153,7 +153,7 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_payload_encrypt( const uint8_t smtc_modem_crypto_return_code_t smtc_modem_crypto_payload_decrypt( const uint8_t* enc_buffer, uint16_t size, smtc_se_key_identifier_t key_id, uint32_t address, uint8_t dir, uint32_t frame_counter, - uint8_t* dec_buffer,uint8_t stack_id ); + uint8_t* dec_buffer, uint8_t stack_id ); /** * @brief Computes the LoRaWAN Join Request frame MIC field @@ -163,8 +163,8 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_payload_decrypt( const uint8_t * @param [in] mic Computed MIC field * @return smtc_modem_crypto_return_code_t */ -smtc_modem_crypto_return_code_t smtc_modem_crypto_compute_join_mic( const uint8_t* buffer, uint16_t size, - uint32_t* mic, uint8_t stack_id ); +smtc_modem_crypto_return_code_t smtc_modem_crypto_compute_join_mic( const uint8_t* buffer, uint16_t size, uint32_t* mic, + uint8_t stack_id ); /** * @brief Process join-accept message. It decrypts the message and verifies the MIC @@ -187,7 +187,7 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_process_join_accept( const uin */ smtc_modem_crypto_return_code_t smtc_modem_crypto_derive_skeys( const uint8_t join_nonce[LORAWAN_JOIN_NONCE_SIZE], const uint8_t net_id[LORAWAN_NET_ID_SIZE], - uint16_t dev_nonce, uint8_t stack_id ); + uint16_t dev_nonce, uint8_t stack_id ); /** * @brief Verifies mic @@ -203,7 +203,8 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_derive_skeys( const uint8_t jo */ smtc_modem_crypto_return_code_t smtc_modem_crypto_verify_mic( const uint8_t* buffer, uint16_t size, smtc_se_key_identifier_t key_id, uint32_t devaddr, - uint8_t dir, uint32_t fcnt, uint32_t expected_mic, uint8_t stack_id ); + uint8_t dir, uint32_t fcnt, uint32_t expected_mic, + uint8_t stack_id ); /** * @brief Compute and add mic to a buffer @@ -218,7 +219,8 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_verify_mic( const uint8_t* buf */ smtc_modem_crypto_return_code_t smtc_modem_crypto_compute_and_add_mic( uint8_t* buffer, uint16_t size, smtc_se_key_identifier_t key_id, - uint32_t devaddr, uint8_t dir, uint32_t fcnt, uint8_t stack_id ); + uint32_t devaddr, uint8_t dir, uint32_t fcnt, + uint8_t stack_id ); /** * @brief Sets a key @@ -227,7 +229,8 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_compute_and_add_mic( uint8_t* * @param [in] key Key value (16 bytes), if its a multicast key it must be encrypted with McKEKey * @return smtc_modem_crypto_return_code_t */ -smtc_modem_crypto_return_code_t smtc_modem_crypto_set_key( smtc_se_key_identifier_t key_id, const uint8_t* key, uint8_t stack_id ); +smtc_modem_crypto_return_code_t smtc_modem_crypto_set_key( smtc_se_key_identifier_t key_id, const uint8_t* key, + uint8_t stack_id ); /** * @brief Derives a Multicast group key pair ( McAppSKey, McNwkSKey ) from McKey @@ -237,7 +240,15 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_set_key( smtc_se_key_identifie * @return smtc_modem_crypto_return_code_t */ smtc_modem_crypto_return_code_t smtc_modem_crypto_derive_multicast_session_keys( smtc_modem_crypto_addr_id_t addr_id, - uint32_t mc_addr, uint8_t stack_id ); + uint32_t mc_addr, uint8_t stack_id ); + +/** + * @brief Derives Relay WOR session keys ( RelayRootWorSKey, RelayWorSKey and RelayWorSIntKey ) from NwkSEncKey + * + * @param [in] dev_addr Device address (4 bytes) + * @return smtc_modem_crypto_return_code_t + */ +smtc_modem_crypto_return_code_t smtc_modem_crypto_derive_relay_session_keys( uint32_t dev_addr, uint8_t stack_id ); /** * @brief Get the class B ping slot rand number that will be used to compute PingPeriod Offset @@ -260,7 +271,8 @@ smtc_modem_crypto_return_code_t smtc_modem_crypto_get_class_b_rand( uint32_t bea * @return smtc_modem_crypto_return_code_t */ smtc_modem_crypto_return_code_t smtc_modem_crypto_service_encrypt( const uint8_t* clear_buff, uint16_t len, - uint8_t nonce[14], uint8_t* enc_buff, uint8_t stack_id ); + uint8_t nonce[14], uint8_t* enc_buff, + uint8_t stack_id ); #ifdef __cplusplus } diff --git a/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_secure_element/smtc_secure_element.h b/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_secure_element/smtc_secure_element.h index a831950..10829a0 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_secure_element/smtc_secure_element.h +++ b/lbm_lib/smtc_modem_core/smtc_modem_crypto/smtc_secure_element/smtc_secure_element.h @@ -3,11 +3,12 @@ * * @brief Secure Element API * - * Revised BSD License - * Copyright Semtech Corporation 2020. All rights reserved. + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef SMTC_SECURE_ELEMENT_H @@ -139,9 +142,10 @@ typedef enum smtc_se_key_identifier_e SMTC_SE_MC_KEY_3, //!< Multicast root key index 3 SMTC_SE_MC_APP_S_KEY_3, //!< Multicast Application session key index 3 SMTC_SE_MC_NWK_S_KEY_3, //!< Multicast Network session key index 3 - SMTC_RELAY_ROOT_WOR_S_KEY, //!< Relay Root Session Key - SMTC_RELAY_WOR_S_INT_KEY, //!< Relay WOR Integrity Session Key - SMTC_RELAY_WOR_S_ENC_KEY, //!< Relay WOR Encryption Session Key + SMTC_SE_RELAY_ROOT_WOR_S_KEY, //!< Relay Root Session Key + SMTC_SE_RELAY_WOR_S_INT_KEY, //!< Relay WOR Integrity Session Key + SMTC_SE_RELAY_WOR_S_ENC_KEY, //!< Relay WOR Encryption Session Key + SMTC_SE_DATA_BLOCK_INT_KEY, //!< Fragmented data block Transport DataBlockIntKey SMTC_SE_SLOT_RAND_ZERO_KEY, //!< Zero key for slot randomization in class B SMTC_SE_NO_KEY, //!< No Key } smtc_se_key_identifier_t; @@ -224,6 +228,15 @@ smtc_se_return_code_t smtc_secure_element_derive_and_store_key( uint8_t* input, smtc_se_key_identifier_t targetkey_id, uint8_t stack_id ); +/** + * @brief Derives Relay WOR session keys and store them + * + * @param [in] dev_addr Device address (4 bytes) + * @param [in] stack_id The Stack Identifier + * @return Secure element return code as defined in @ref smtc_se_return_code_t + */ +smtc_se_return_code_t smtc_secure_element_derive_relay_session_keys( uint32_t dev_addr, uint8_t stack_id ); + /** * @brief Process join_accept message. * diff --git a/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.c b/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.c index eb0551f..ac43223 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.c +++ b/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.c @@ -33,191 +33,178 @@ /* define if you have a fast memcpy function on your system */ #if 0 -# define HAVE_MEMCPY -# include -# if defined( _MSC_VER ) -# include -# pragma intrinsic( memcpy ) -# endif +#define HAVE_MEMCPY +#include +#if defined( _MSC_VER ) +#include +#pragma intrinsic( memcpy ) +#endif #endif - #include #include /* define if you have fast 32-bit types on your system */ -#if ( __CORTEX_M != 0 ) // if Cortex is different from M0/M0+ -# define HAVE_UINT_32T +#if( __CORTEX_M != 0 ) // if Cortex is different from M0/M0+ +#define HAVE_UINT_32T #endif /* define if you don't want any tables */ #if 1 -# define USE_TABLES +#define USE_TABLES #endif /* On Intel Core 2 duo VERSION_1 is faster */ /* alternative versions (test for performance on your system) */ #if 1 -# define VERSION_1 +#define VERSION_1 #endif #include "aes.h" -//#if defined( HAVE_UINT_32T ) -// typedef unsigned long uint32_t; -//#endif +// #if defined( HAVE_UINT_32T ) +// typedef unsigned long uint32_t; +// #endif /* functions for finite field multiplication in the AES Galois field */ -#define WPOLY 0x011b -#define BPOLY 0x1b -#define DPOLY 0x008d +#define WPOLY 0x011b +#define BPOLY 0x1b +#define DPOLY 0x008d -#define f1(x) (x) -#define f2(x) ((x << 1) ^ (((x >> 7) & 1) * WPOLY)) -#define f4(x) ((x << 2) ^ (((x >> 6) & 1) * WPOLY) ^ (((x >> 6) & 2) * WPOLY)) -#define f8(x) ((x << 3) ^ (((x >> 5) & 1) * WPOLY) ^ (((x >> 5) & 2) * WPOLY) \ - ^ (((x >> 5) & 4) * WPOLY)) -#define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0)) +#define f1( x ) ( x ) +#define f2( x ) ( ( x << 1 ) ^ ( ( ( x >> 7 ) & 1 ) * WPOLY ) ) +#define f4( x ) ( ( x << 2 ) ^ ( ( ( x >> 6 ) & 1 ) * WPOLY ) ^ ( ( ( x >> 6 ) & 2 ) * WPOLY ) ) +#define f8( x ) \ + ( ( x << 3 ) ^ ( ( ( x >> 5 ) & 1 ) * WPOLY ) ^ ( ( ( x >> 5 ) & 2 ) * WPOLY ) ^ ( ( ( x >> 5 ) & 4 ) * WPOLY ) ) +#define d2( x ) ( ( ( x ) >> 1 ) ^ ( ( x ) & 1 ? DPOLY : 0 ) ) -#define f3(x) (f2(x) ^ x) -#define f9(x) (f8(x) ^ x) -#define fb(x) (f8(x) ^ f2(x) ^ x) -#define fd(x) (f8(x) ^ f4(x) ^ x) -#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) +#define f3( x ) ( f2( x ) ^ x ) +#define f9( x ) ( f8( x ) ^ x ) +#define fb( x ) ( f8( x ) ^ f2( x ) ^ x ) +#define fd( x ) ( f8( x ) ^ f4( x ) ^ x ) +#define fe( x ) ( f8( x ) ^ f4( x ) ^ f2( x ) ) #if defined( USE_TABLES ) -#define sb_data(w) { /* S Box data values */ \ - w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ - w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ - w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ - w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ - w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ - w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ - w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ - w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ - w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ - w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ - w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ - w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ - w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ - w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ - w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ - w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ - w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ - w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ - w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ - w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ - w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ - w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ - w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ - w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ - w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ - w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ - w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ - w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ - w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ - w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ - w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ - w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) } - -#define isb_data(w) { /* inverse S Box data values */ \ - w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\ - w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\ - w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\ - w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\ - w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\ - w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\ - w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\ - w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\ - w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\ - w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\ - w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\ - w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\ - w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\ - w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\ - w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\ - w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\ - w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\ - w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\ - w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\ - w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\ - w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\ - w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\ - w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\ - w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\ - w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\ - w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\ - w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\ - w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\ - w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\ - w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\ - w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\ - w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) } - -#define mm_data(w) { /* basic data for forming finite field tables */ \ - w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\ - w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\ - w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\ - w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\ - w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\ - w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\ - w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\ - w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\ - w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\ - w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\ - w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\ - w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\ - w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\ - w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\ - w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\ - w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\ - w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\ - w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\ - w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\ - w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\ - w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\ - w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\ - w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\ - w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\ - w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\ - w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\ - w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\ - w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\ - w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\ - w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\ - w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\ - w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) } - -static const uint8_t sbox[256] = sb_data(f1); +#define sb_data( w ) \ + { /* S Box data values */ \ + w( 0x63 ), w( 0x7c ), w( 0x77 ), w( 0x7b ), w( 0xf2 ), w( 0x6b ), w( 0x6f ), w( 0xc5 ), w( 0x30 ), w( 0x01 ), \ + w( 0x67 ), w( 0x2b ), w( 0xfe ), w( 0xd7 ), w( 0xab ), w( 0x76 ), w( 0xca ), w( 0x82 ), w( 0xc9 ), w( 0x7d ), \ + w( 0xfa ), w( 0x59 ), w( 0x47 ), w( 0xf0 ), w( 0xad ), w( 0xd4 ), w( 0xa2 ), w( 0xaf ), w( 0x9c ), w( 0xa4 ), \ + w( 0x72 ), w( 0xc0 ), w( 0xb7 ), w( 0xfd ), w( 0x93 ), w( 0x26 ), w( 0x36 ), w( 0x3f ), w( 0xf7 ), w( 0xcc ), \ + w( 0x34 ), w( 0xa5 ), w( 0xe5 ), w( 0xf1 ), w( 0x71 ), w( 0xd8 ), w( 0x31 ), w( 0x15 ), w( 0x04 ), w( 0xc7 ), \ + w( 0x23 ), w( 0xc3 ), w( 0x18 ), w( 0x96 ), w( 0x05 ), w( 0x9a ), w( 0x07 ), w( 0x12 ), w( 0x80 ), w( 0xe2 ), \ + w( 0xeb ), w( 0x27 ), w( 0xb2 ), w( 0x75 ), w( 0x09 ), w( 0x83 ), w( 0x2c ), w( 0x1a ), w( 0x1b ), w( 0x6e ), \ + w( 0x5a ), w( 0xa0 ), w( 0x52 ), w( 0x3b ), w( 0xd6 ), w( 0xb3 ), w( 0x29 ), w( 0xe3 ), w( 0x2f ), w( 0x84 ), \ + w( 0x53 ), w( 0xd1 ), w( 0x00 ), w( 0xed ), w( 0x20 ), w( 0xfc ), w( 0xb1 ), w( 0x5b ), w( 0x6a ), w( 0xcb ), \ + w( 0xbe ), w( 0x39 ), w( 0x4a ), w( 0x4c ), w( 0x58 ), w( 0xcf ), w( 0xd0 ), w( 0xef ), w( 0xaa ), w( 0xfb ), \ + w( 0x43 ), w( 0x4d ), w( 0x33 ), w( 0x85 ), w( 0x45 ), w( 0xf9 ), w( 0x02 ), w( 0x7f ), w( 0x50 ), w( 0x3c ), \ + w( 0x9f ), w( 0xa8 ), w( 0x51 ), w( 0xa3 ), w( 0x40 ), w( 0x8f ), w( 0x92 ), w( 0x9d ), w( 0x38 ), w( 0xf5 ), \ + w( 0xbc ), w( 0xb6 ), w( 0xda ), w( 0x21 ), w( 0x10 ), w( 0xff ), w( 0xf3 ), w( 0xd2 ), w( 0xcd ), w( 0x0c ), \ + w( 0x13 ), w( 0xec ), w( 0x5f ), w( 0x97 ), w( 0x44 ), w( 0x17 ), w( 0xc4 ), w( 0xa7 ), w( 0x7e ), w( 0x3d ), \ + w( 0x64 ), w( 0x5d ), w( 0x19 ), w( 0x73 ), w( 0x60 ), w( 0x81 ), w( 0x4f ), w( 0xdc ), w( 0x22 ), w( 0x2a ), \ + w( 0x90 ), w( 0x88 ), w( 0x46 ), w( 0xee ), w( 0xb8 ), w( 0x14 ), w( 0xde ), w( 0x5e ), w( 0x0b ), w( 0xdb ), \ + w( 0xe0 ), w( 0x32 ), w( 0x3a ), w( 0x0a ), w( 0x49 ), w( 0x06 ), w( 0x24 ), w( 0x5c ), w( 0xc2 ), w( 0xd3 ), \ + w( 0xac ), w( 0x62 ), w( 0x91 ), w( 0x95 ), w( 0xe4 ), w( 0x79 ), w( 0xe7 ), w( 0xc8 ), w( 0x37 ), w( 0x6d ), \ + w( 0x8d ), w( 0xd5 ), w( 0x4e ), w( 0xa9 ), w( 0x6c ), w( 0x56 ), w( 0xf4 ), w( 0xea ), w( 0x65 ), w( 0x7a ), \ + w( 0xae ), w( 0x08 ), w( 0xba ), w( 0x78 ), w( 0x25 ), w( 0x2e ), w( 0x1c ), w( 0xa6 ), w( 0xb4 ), w( 0xc6 ), \ + w( 0xe8 ), w( 0xdd ), w( 0x74 ), w( 0x1f ), w( 0x4b ), w( 0xbd ), w( 0x8b ), w( 0x8a ), w( 0x70 ), w( 0x3e ), \ + w( 0xb5 ), w( 0x66 ), w( 0x48 ), w( 0x03 ), w( 0xf6 ), w( 0x0e ), w( 0x61 ), w( 0x35 ), w( 0x57 ), w( 0xb9 ), \ + w( 0x86 ), w( 0xc1 ), w( 0x1d ), w( 0x9e ), w( 0xe1 ), w( 0xf8 ), w( 0x98 ), w( 0x11 ), w( 0x69 ), w( 0xd9 ), \ + w( 0x8e ), w( 0x94 ), w( 0x9b ), w( 0x1e ), w( 0x87 ), w( 0xe9 ), w( 0xce ), w( 0x55 ), w( 0x28 ), w( 0xdf ), \ + w( 0x8c ), w( 0xa1 ), w( 0x89 ), w( 0x0d ), w( 0xbf ), w( 0xe6 ), w( 0x42 ), w( 0x68 ), w( 0x41 ), w( 0x99 ), \ + w( 0x2d ), w( 0x0f ), w( 0xb0 ), w( 0x54 ), w( 0xbb ), w( 0x16 ) \ + } + +#define isb_data( w ) \ + { /* inverse S Box data values */ \ + w( 0x52 ), w( 0x09 ), w( 0x6a ), w( 0xd5 ), w( 0x30 ), w( 0x36 ), w( 0xa5 ), w( 0x38 ), w( 0xbf ), w( 0x40 ), \ + w( 0xa3 ), w( 0x9e ), w( 0x81 ), w( 0xf3 ), w( 0xd7 ), w( 0xfb ), w( 0x7c ), w( 0xe3 ), w( 0x39 ), w( 0x82 ), \ + w( 0x9b ), w( 0x2f ), w( 0xff ), w( 0x87 ), w( 0x34 ), w( 0x8e ), w( 0x43 ), w( 0x44 ), w( 0xc4 ), w( 0xde ), \ + w( 0xe9 ), w( 0xcb ), w( 0x54 ), w( 0x7b ), w( 0x94 ), w( 0x32 ), w( 0xa6 ), w( 0xc2 ), w( 0x23 ), w( 0x3d ), \ + w( 0xee ), w( 0x4c ), w( 0x95 ), w( 0x0b ), w( 0x42 ), w( 0xfa ), w( 0xc3 ), w( 0x4e ), w( 0x08 ), w( 0x2e ), \ + w( 0xa1 ), w( 0x66 ), w( 0x28 ), w( 0xd9 ), w( 0x24 ), w( 0xb2 ), w( 0x76 ), w( 0x5b ), w( 0xa2 ), w( 0x49 ), \ + w( 0x6d ), w( 0x8b ), w( 0xd1 ), w( 0x25 ), w( 0x72 ), w( 0xf8 ), w( 0xf6 ), w( 0x64 ), w( 0x86 ), w( 0x68 ), \ + w( 0x98 ), w( 0x16 ), w( 0xd4 ), w( 0xa4 ), w( 0x5c ), w( 0xcc ), w( 0x5d ), w( 0x65 ), w( 0xb6 ), w( 0x92 ), \ + w( 0x6c ), w( 0x70 ), w( 0x48 ), w( 0x50 ), w( 0xfd ), w( 0xed ), w( 0xb9 ), w( 0xda ), w( 0x5e ), w( 0x15 ), \ + w( 0x46 ), w( 0x57 ), w( 0xa7 ), w( 0x8d ), w( 0x9d ), w( 0x84 ), w( 0x90 ), w( 0xd8 ), w( 0xab ), w( 0x00 ), \ + w( 0x8c ), w( 0xbc ), w( 0xd3 ), w( 0x0a ), w( 0xf7 ), w( 0xe4 ), w( 0x58 ), w( 0x05 ), w( 0xb8 ), w( 0xb3 ), \ + w( 0x45 ), w( 0x06 ), w( 0xd0 ), w( 0x2c ), w( 0x1e ), w( 0x8f ), w( 0xca ), w( 0x3f ), w( 0x0f ), w( 0x02 ), \ + w( 0xc1 ), w( 0xaf ), w( 0xbd ), w( 0x03 ), w( 0x01 ), w( 0x13 ), w( 0x8a ), w( 0x6b ), w( 0x3a ), w( 0x91 ), \ + w( 0x11 ), w( 0x41 ), w( 0x4f ), w( 0x67 ), w( 0xdc ), w( 0xea ), w( 0x97 ), w( 0xf2 ), w( 0xcf ), w( 0xce ), \ + w( 0xf0 ), w( 0xb4 ), w( 0xe6 ), w( 0x73 ), w( 0x96 ), w( 0xac ), w( 0x74 ), w( 0x22 ), w( 0xe7 ), w( 0xad ), \ + w( 0x35 ), w( 0x85 ), w( 0xe2 ), w( 0xf9 ), w( 0x37 ), w( 0xe8 ), w( 0x1c ), w( 0x75 ), w( 0xdf ), w( 0x6e ), \ + w( 0x47 ), w( 0xf1 ), w( 0x1a ), w( 0x71 ), w( 0x1d ), w( 0x29 ), w( 0xc5 ), w( 0x89 ), w( 0x6f ), w( 0xb7 ), \ + w( 0x62 ), w( 0x0e ), w( 0xaa ), w( 0x18 ), w( 0xbe ), w( 0x1b ), w( 0xfc ), w( 0x56 ), w( 0x3e ), w( 0x4b ), \ + w( 0xc6 ), w( 0xd2 ), w( 0x79 ), w( 0x20 ), w( 0x9a ), w( 0xdb ), w( 0xc0 ), w( 0xfe ), w( 0x78 ), w( 0xcd ), \ + w( 0x5a ), w( 0xf4 ), w( 0x1f ), w( 0xdd ), w( 0xa8 ), w( 0x33 ), w( 0x88 ), w( 0x07 ), w( 0xc7 ), w( 0x31 ), \ + w( 0xb1 ), w( 0x12 ), w( 0x10 ), w( 0x59 ), w( 0x27 ), w( 0x80 ), w( 0xec ), w( 0x5f ), w( 0x60 ), w( 0x51 ), \ + w( 0x7f ), w( 0xa9 ), w( 0x19 ), w( 0xb5 ), w( 0x4a ), w( 0x0d ), w( 0x2d ), w( 0xe5 ), w( 0x7a ), w( 0x9f ), \ + w( 0x93 ), w( 0xc9 ), w( 0x9c ), w( 0xef ), w( 0xa0 ), w( 0xe0 ), w( 0x3b ), w( 0x4d ), w( 0xae ), w( 0x2a ), \ + w( 0xf5 ), w( 0xb0 ), w( 0xc8 ), w( 0xeb ), w( 0xbb ), w( 0x3c ), w( 0x83 ), w( 0x53 ), w( 0x99 ), w( 0x61 ), \ + w( 0x17 ), w( 0x2b ), w( 0x04 ), w( 0x7e ), w( 0xba ), w( 0x77 ), w( 0xd6 ), w( 0x26 ), w( 0xe1 ), w( 0x69 ), \ + w( 0x14 ), w( 0x63 ), w( 0x55 ), w( 0x21 ), w( 0x0c ), w( 0x7d ) \ + } + +#define mm_data( w ) \ + { /* basic data for forming finite field tables */ \ + w( 0x00 ), w( 0x01 ), w( 0x02 ), w( 0x03 ), w( 0x04 ), w( 0x05 ), w( 0x06 ), w( 0x07 ), w( 0x08 ), w( 0x09 ), \ + w( 0x0a ), w( 0x0b ), w( 0x0c ), w( 0x0d ), w( 0x0e ), w( 0x0f ), w( 0x10 ), w( 0x11 ), w( 0x12 ), w( 0x13 ), \ + w( 0x14 ), w( 0x15 ), w( 0x16 ), w( 0x17 ), w( 0x18 ), w( 0x19 ), w( 0x1a ), w( 0x1b ), w( 0x1c ), w( 0x1d ), \ + w( 0x1e ), w( 0x1f ), w( 0x20 ), w( 0x21 ), w( 0x22 ), w( 0x23 ), w( 0x24 ), w( 0x25 ), w( 0x26 ), w( 0x27 ), \ + w( 0x28 ), w( 0x29 ), w( 0x2a ), w( 0x2b ), w( 0x2c ), w( 0x2d ), w( 0x2e ), w( 0x2f ), w( 0x30 ), w( 0x31 ), \ + w( 0x32 ), w( 0x33 ), w( 0x34 ), w( 0x35 ), w( 0x36 ), w( 0x37 ), w( 0x38 ), w( 0x39 ), w( 0x3a ), w( 0x3b ), \ + w( 0x3c ), w( 0x3d ), w( 0x3e ), w( 0x3f ), w( 0x40 ), w( 0x41 ), w( 0x42 ), w( 0x43 ), w( 0x44 ), w( 0x45 ), \ + w( 0x46 ), w( 0x47 ), w( 0x48 ), w( 0x49 ), w( 0x4a ), w( 0x4b ), w( 0x4c ), w( 0x4d ), w( 0x4e ), w( 0x4f ), \ + w( 0x50 ), w( 0x51 ), w( 0x52 ), w( 0x53 ), w( 0x54 ), w( 0x55 ), w( 0x56 ), w( 0x57 ), w( 0x58 ), w( 0x59 ), \ + w( 0x5a ), w( 0x5b ), w( 0x5c ), w( 0x5d ), w( 0x5e ), w( 0x5f ), w( 0x60 ), w( 0x61 ), w( 0x62 ), w( 0x63 ), \ + w( 0x64 ), w( 0x65 ), w( 0x66 ), w( 0x67 ), w( 0x68 ), w( 0x69 ), w( 0x6a ), w( 0x6b ), w( 0x6c ), w( 0x6d ), \ + w( 0x6e ), w( 0x6f ), w( 0x70 ), w( 0x71 ), w( 0x72 ), w( 0x73 ), w( 0x74 ), w( 0x75 ), w( 0x76 ), w( 0x77 ), \ + w( 0x78 ), w( 0x79 ), w( 0x7a ), w( 0x7b ), w( 0x7c ), w( 0x7d ), w( 0x7e ), w( 0x7f ), w( 0x80 ), w( 0x81 ), \ + w( 0x82 ), w( 0x83 ), w( 0x84 ), w( 0x85 ), w( 0x86 ), w( 0x87 ), w( 0x88 ), w( 0x89 ), w( 0x8a ), w( 0x8b ), \ + w( 0x8c ), w( 0x8d ), w( 0x8e ), w( 0x8f ), w( 0x90 ), w( 0x91 ), w( 0x92 ), w( 0x93 ), w( 0x94 ), w( 0x95 ), \ + w( 0x96 ), w( 0x97 ), w( 0x98 ), w( 0x99 ), w( 0x9a ), w( 0x9b ), w( 0x9c ), w( 0x9d ), w( 0x9e ), w( 0x9f ), \ + w( 0xa0 ), w( 0xa1 ), w( 0xa2 ), w( 0xa3 ), w( 0xa4 ), w( 0xa5 ), w( 0xa6 ), w( 0xa7 ), w( 0xa8 ), w( 0xa9 ), \ + w( 0xaa ), w( 0xab ), w( 0xac ), w( 0xad ), w( 0xae ), w( 0xaf ), w( 0xb0 ), w( 0xb1 ), w( 0xb2 ), w( 0xb3 ), \ + w( 0xb4 ), w( 0xb5 ), w( 0xb6 ), w( 0xb7 ), w( 0xb8 ), w( 0xb9 ), w( 0xba ), w( 0xbb ), w( 0xbc ), w( 0xbd ), \ + w( 0xbe ), w( 0xbf ), w( 0xc0 ), w( 0xc1 ), w( 0xc2 ), w( 0xc3 ), w( 0xc4 ), w( 0xc5 ), w( 0xc6 ), w( 0xc7 ), \ + w( 0xc8 ), w( 0xc9 ), w( 0xca ), w( 0xcb ), w( 0xcc ), w( 0xcd ), w( 0xce ), w( 0xcf ), w( 0xd0 ), w( 0xd1 ), \ + w( 0xd2 ), w( 0xd3 ), w( 0xd4 ), w( 0xd5 ), w( 0xd6 ), w( 0xd7 ), w( 0xd8 ), w( 0xd9 ), w( 0xda ), w( 0xdb ), \ + w( 0xdc ), w( 0xdd ), w( 0xde ), w( 0xdf ), w( 0xe0 ), w( 0xe1 ), w( 0xe2 ), w( 0xe3 ), w( 0xe4 ), w( 0xe5 ), \ + w( 0xe6 ), w( 0xe7 ), w( 0xe8 ), w( 0xe9 ), w( 0xea ), w( 0xeb ), w( 0xec ), w( 0xed ), w( 0xee ), w( 0xef ), \ + w( 0xf0 ), w( 0xf1 ), w( 0xf2 ), w( 0xf3 ), w( 0xf4 ), w( 0xf5 ), w( 0xf6 ), w( 0xf7 ), w( 0xf8 ), w( 0xf9 ), \ + w( 0xfa ), w( 0xfb ), w( 0xfc ), w( 0xfd ), w( 0xfe ), w( 0xff ) \ + } + +static const uint8_t sbox[256] = sb_data( f1 ); #if defined( AES_DEC_PREKEYED ) -static const uint8_t isbox[256] = isb_data(f1); +static const uint8_t isbox[256] = isb_data( f1 ); #endif -static const uint8_t gfm2_sbox[256] = sb_data(f2); -static const uint8_t gfm3_sbox[256] = sb_data(f3); +static const uint8_t gfm2_sbox[256] = sb_data( f2 ); +static const uint8_t gfm3_sbox[256] = sb_data( f3 ); #if defined( AES_DEC_PREKEYED ) -static const uint8_t gfmul_9[256] = mm_data(f9); -static const uint8_t gfmul_b[256] = mm_data(fb); -static const uint8_t gfmul_d[256] = mm_data(fd); -static const uint8_t gfmul_e[256] = mm_data(fe); +static const uint8_t gfmul_9[256] = mm_data( f9 ); +static const uint8_t gfmul_b[256] = mm_data( fb ); +static const uint8_t gfmul_d[256] = mm_data( fd ); +static const uint8_t gfmul_e[256] = mm_data( fe ); #endif -#define s_box(x) sbox[(x)] +#define s_box( x ) sbox[( x )] #if defined( AES_DEC_PREKEYED ) -#define is_box(x) isbox[(x)] +#define is_box( x ) isbox[( x )] #endif -#define gfm2_sb(x) gfm2_sbox[(x)] -#define gfm3_sb(x) gfm3_sbox[(x)] +#define gfm2_sb( x ) gfm2_sbox[( x )] +#define gfm3_sb( x ) gfm3_sbox[( x )] #if defined( AES_DEC_PREKEYED ) -#define gfm_9(x) gfmul_9[(x)] -#define gfm_b(x) gfmul_b[(x)] -#define gfm_d(x) gfmul_d[(x)] -#define gfm_e(x) gfmul_e[(x)] +#define gfm_9( x ) gfmul_9[( x )] +#define gfm_b( x ) gfmul_b[( x )] +#define gfm_d( x ) gfmul_d[( x )] +#define gfm_e( x ) gfmul_e[( x )] #endif #else @@ -226,42 +213,44 @@ static const uint8_t gfmul_e[256] = mm_data(fe); /* 9 bits (0x11b), this right shift keeps the */ /* values of all top bits within a byte */ -static uint8_t hibit(const uint8_t x) -{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2)); +static uint8_t hibit( const uint8_t x ) +{ + uint8_t r = ( uint8_t ) ( ( x >> 1 ) | ( x >> 2 ) ); - r |= (r >> 2); - r |= (r >> 4); - return (r + 1) >> 1; + r |= ( r >> 2 ); + r |= ( r >> 4 ); + return ( r + 1 ) >> 1; } /* return the inverse of the finite field element x */ -static uint8_t gf_inv(const uint8_t x) -{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; +static uint8_t gf_inv( const uint8_t x ) +{ + uint8_t p1 = x, p2 = BPOLY, n1 = hibit( x ), n2 = 0x80, v1 = 1, v2 = 0; - if(x < 2) + if( x < 2 ) return x; - for( ; ; ) + for( ;; ) { - if(n1) - while(n2 >= n1) /* divide polynomial p2 by p1 */ + if( n1 ) + while( n2 >= n1 ) /* divide polynomial p2 by p1 */ { - n2 /= n1; /* shift smaller polynomial left */ - p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */ - v2 ^= (v1 * n2); /* shift accumulated value and */ - n2 = hibit(p2); /* add into result */ + n2 /= n1; /* shift smaller polynomial left */ + p2 ^= ( p1 * n2 ) & 0xff; /* and remove from larger one */ + v2 ^= ( v1 * n2 ); /* shift accumulated value and */ + n2 = hibit( p2 ); /* add into result */ } else return v1; - if(n2) /* repeat with values swapped */ - while(n1 >= n2) + if( n2 ) /* repeat with values swapped */ + while( n1 >= n2 ) { n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; - n1 = hibit(p1); + n1 = hibit( p1 ); } else return v2; @@ -269,240 +258,267 @@ static uint8_t gf_inv(const uint8_t x) } /* The forward and inverse affine transformations used in the S-box */ -uint8_t fwd_affine(const uint8_t x) +uint8_t fwd_affine( const uint8_t x ) { #if defined( HAVE_UINT_32T ) uint32_t w = x; - w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4); - return 0x63 ^ ((w ^ (w >> 8)) & 0xff); + w ^= ( w << 1 ) ^ ( w << 2 ) ^ ( w << 3 ) ^ ( w << 4 ); + return 0x63 ^ ( ( w ^ ( w >> 8 ) ) & 0xff ); #else - return 0x63 ^ x ^ (x << 1) ^ (x << 2) ^ (x << 3) ^ (x << 4) - ^ (x >> 7) ^ (x >> 6) ^ (x >> 5) ^ (x >> 4); + return 0x63 ^ x ^ ( x << 1 ) ^ ( x << 2 ) ^ ( x << 3 ) ^ ( x << 4 ) ^ ( x >> 7 ) ^ ( x >> 6 ) ^ ( x >> 5 ) ^ + ( x >> 4 ); #endif } -uint8_t inv_affine(const uint8_t x) +uint8_t inv_affine( const uint8_t x ) { #if defined( HAVE_UINT_32T ) uint32_t w = x; - w = (w << 1) ^ (w << 3) ^ (w << 6); - return 0x05 ^ ((w ^ (w >> 8)) & 0xff); + w = ( w << 1 ) ^ ( w << 3 ) ^ ( w << 6 ); + return 0x05 ^ ( ( w ^ ( w >> 8 ) ) & 0xff ); #else - return 0x05 ^ (x << 1) ^ (x << 3) ^ (x << 6) - ^ (x >> 7) ^ (x >> 5) ^ (x >> 2); + return 0x05 ^ ( x << 1 ) ^ ( x << 3 ) ^ ( x << 6 ) ^ ( x >> 7 ) ^ ( x >> 5 ) ^ ( x >> 2 ); #endif } -#define s_box(x) fwd_affine(gf_inv(x)) -#define is_box(x) gf_inv(inv_affine(x)) -#define gfm2_sb(x) f2(s_box(x)) -#define gfm3_sb(x) f3(s_box(x)) -#define gfm_9(x) f9(x) -#define gfm_b(x) fb(x) -#define gfm_d(x) fd(x) -#define gfm_e(x) fe(x) +#define s_box( x ) fwd_affine( gf_inv( x ) ) +#define is_box( x ) gf_inv( inv_affine( x ) ) +#define gfm2_sb( x ) f2( s_box( x ) ) +#define gfm3_sb( x ) f3( s_box( x ) ) +#define gfm_9( x ) f9( x ) +#define gfm_b( x ) fb( x ) +#define gfm_d( x ) fd( x ) +#define gfm_e( x ) fe( x ) #endif #if defined( HAVE_MEMCPY ) -# define block_copy_nn(d, s, l) memcpy(d, s, l) -# define block_copy(d, s) memcpy(d, s, N_BLOCK) +#define block_copy_nn( d, s, l ) memcpy( d, s, l ) +#define block_copy( d, s ) memcpy( d, s, N_BLOCK ) #else -# define block_copy_nn(d, s, l) copy_block_nn(d, s, l) -# define block_copy(d, s) copy_block(d, s) +#define block_copy_nn( d, s, l ) copy_block_nn( d, s, l ) +#define block_copy( d, s ) copy_block( d, s ) #endif -static void copy_block( void *d, const void *s ) +static void copy_block( void* d, const void* s ) { #if defined( HAVE_UINT_32T ) - ((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0]; - ((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1]; - ((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2]; - ((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3]; + ( ( uint32_t* ) d )[0] = ( ( uint32_t* ) s )[0]; + ( ( uint32_t* ) d )[1] = ( ( uint32_t* ) s )[1]; + ( ( uint32_t* ) d )[2] = ( ( uint32_t* ) s )[2]; + ( ( uint32_t* ) d )[3] = ( ( uint32_t* ) s )[3]; #else - ((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0]; - ((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1]; - ((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2]; - ((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3]; - ((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4]; - ((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5]; - ((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6]; - ((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7]; - ((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8]; - ((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9]; - ((uint8_t*)d)[10] = ((uint8_t*)s)[10]; - ((uint8_t*)d)[11] = ((uint8_t*)s)[11]; - ((uint8_t*)d)[12] = ((uint8_t*)s)[12]; - ((uint8_t*)d)[13] = ((uint8_t*)s)[13]; - ((uint8_t*)d)[14] = ((uint8_t*)s)[14]; - ((uint8_t*)d)[15] = ((uint8_t*)s)[15]; + ( ( uint8_t* ) d )[0] = ( ( uint8_t* ) s )[0]; + ( ( uint8_t* ) d )[1] = ( ( uint8_t* ) s )[1]; + ( ( uint8_t* ) d )[2] = ( ( uint8_t* ) s )[2]; + ( ( uint8_t* ) d )[3] = ( ( uint8_t* ) s )[3]; + ( ( uint8_t* ) d )[4] = ( ( uint8_t* ) s )[4]; + ( ( uint8_t* ) d )[5] = ( ( uint8_t* ) s )[5]; + ( ( uint8_t* ) d )[6] = ( ( uint8_t* ) s )[6]; + ( ( uint8_t* ) d )[7] = ( ( uint8_t* ) s )[7]; + ( ( uint8_t* ) d )[8] = ( ( uint8_t* ) s )[8]; + ( ( uint8_t* ) d )[9] = ( ( uint8_t* ) s )[9]; + ( ( uint8_t* ) d )[10] = ( ( uint8_t* ) s )[10]; + ( ( uint8_t* ) d )[11] = ( ( uint8_t* ) s )[11]; + ( ( uint8_t* ) d )[12] = ( ( uint8_t* ) s )[12]; + ( ( uint8_t* ) d )[13] = ( ( uint8_t* ) s )[13]; + ( ( uint8_t* ) d )[14] = ( ( uint8_t* ) s )[14]; + ( ( uint8_t* ) d )[15] = ( ( uint8_t* ) s )[15]; #endif } -static void copy_block_nn( uint8_t * d, const uint8_t *s, uint8_t nn ) +static void copy_block_nn( uint8_t* d, const uint8_t* s, uint8_t nn ) { while( nn-- ) //*((uint8_t*)d)++ = *((uint8_t*)s)++; *d++ = *s++; } -static void xor_block( void *d, const void *s ) +static void xor_block( void* d, const void* s ) { #if defined( HAVE_UINT_32T ) - ((uint32_t*)d)[ 0] ^= ((uint32_t*)s)[ 0]; - ((uint32_t*)d)[ 1] ^= ((uint32_t*)s)[ 1]; - ((uint32_t*)d)[ 2] ^= ((uint32_t*)s)[ 2]; - ((uint32_t*)d)[ 3] ^= ((uint32_t*)s)[ 3]; + ( ( uint32_t* ) d )[0] ^= ( ( uint32_t* ) s )[0]; + ( ( uint32_t* ) d )[1] ^= ( ( uint32_t* ) s )[1]; + ( ( uint32_t* ) d )[2] ^= ( ( uint32_t* ) s )[2]; + ( ( uint32_t* ) d )[3] ^= ( ( uint32_t* ) s )[3]; #else - ((uint8_t*)d)[ 0] ^= ((uint8_t*)s)[ 0]; - ((uint8_t*)d)[ 1] ^= ((uint8_t*)s)[ 1]; - ((uint8_t*)d)[ 2] ^= ((uint8_t*)s)[ 2]; - ((uint8_t*)d)[ 3] ^= ((uint8_t*)s)[ 3]; - ((uint8_t*)d)[ 4] ^= ((uint8_t*)s)[ 4]; - ((uint8_t*)d)[ 5] ^= ((uint8_t*)s)[ 5]; - ((uint8_t*)d)[ 6] ^= ((uint8_t*)s)[ 6]; - ((uint8_t*)d)[ 7] ^= ((uint8_t*)s)[ 7]; - ((uint8_t*)d)[ 8] ^= ((uint8_t*)s)[ 8]; - ((uint8_t*)d)[ 9] ^= ((uint8_t*)s)[ 9]; - ((uint8_t*)d)[10] ^= ((uint8_t*)s)[10]; - ((uint8_t*)d)[11] ^= ((uint8_t*)s)[11]; - ((uint8_t*)d)[12] ^= ((uint8_t*)s)[12]; - ((uint8_t*)d)[13] ^= ((uint8_t*)s)[13]; - ((uint8_t*)d)[14] ^= ((uint8_t*)s)[14]; - ((uint8_t*)d)[15] ^= ((uint8_t*)s)[15]; + ( ( uint8_t* ) d )[0] ^= ( ( uint8_t* ) s )[0]; + ( ( uint8_t* ) d )[1] ^= ( ( uint8_t* ) s )[1]; + ( ( uint8_t* ) d )[2] ^= ( ( uint8_t* ) s )[2]; + ( ( uint8_t* ) d )[3] ^= ( ( uint8_t* ) s )[3]; + ( ( uint8_t* ) d )[4] ^= ( ( uint8_t* ) s )[4]; + ( ( uint8_t* ) d )[5] ^= ( ( uint8_t* ) s )[5]; + ( ( uint8_t* ) d )[6] ^= ( ( uint8_t* ) s )[6]; + ( ( uint8_t* ) d )[7] ^= ( ( uint8_t* ) s )[7]; + ( ( uint8_t* ) d )[8] ^= ( ( uint8_t* ) s )[8]; + ( ( uint8_t* ) d )[9] ^= ( ( uint8_t* ) s )[9]; + ( ( uint8_t* ) d )[10] ^= ( ( uint8_t* ) s )[10]; + ( ( uint8_t* ) d )[11] ^= ( ( uint8_t* ) s )[11]; + ( ( uint8_t* ) d )[12] ^= ( ( uint8_t* ) s )[12]; + ( ( uint8_t* ) d )[13] ^= ( ( uint8_t* ) s )[13]; + ( ( uint8_t* ) d )[14] ^= ( ( uint8_t* ) s )[14]; + ( ( uint8_t* ) d )[15] ^= ( ( uint8_t* ) s )[15]; #endif } -static void copy_and_key( void *d, const void *s, const void *k ) +static void copy_and_key( void* d, const void* s, const void* k ) { #if defined( HAVE_UINT_32T ) - ((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0] ^ ((uint32_t*)k)[ 0]; - ((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1] ^ ((uint32_t*)k)[ 1]; - ((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2] ^ ((uint32_t*)k)[ 2]; - ((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3] ^ ((uint32_t*)k)[ 3]; + ( ( uint32_t* ) d )[0] = ( ( uint32_t* ) s )[0] ^ ( ( uint32_t* ) k )[0]; + ( ( uint32_t* ) d )[1] = ( ( uint32_t* ) s )[1] ^ ( ( uint32_t* ) k )[1]; + ( ( uint32_t* ) d )[2] = ( ( uint32_t* ) s )[2] ^ ( ( uint32_t* ) k )[2]; + ( ( uint32_t* ) d )[3] = ( ( uint32_t* ) s )[3] ^ ( ( uint32_t* ) k )[3]; #elif 1 - ((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0] ^ ((uint8_t*)k)[ 0]; - ((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1] ^ ((uint8_t*)k)[ 1]; - ((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2] ^ ((uint8_t*)k)[ 2]; - ((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3] ^ ((uint8_t*)k)[ 3]; - ((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4] ^ ((uint8_t*)k)[ 4]; - ((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5] ^ ((uint8_t*)k)[ 5]; - ((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6] ^ ((uint8_t*)k)[ 6]; - ((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7] ^ ((uint8_t*)k)[ 7]; - ((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8] ^ ((uint8_t*)k)[ 8]; - ((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9] ^ ((uint8_t*)k)[ 9]; - ((uint8_t*)d)[10] = ((uint8_t*)s)[10] ^ ((uint8_t*)k)[10]; - ((uint8_t*)d)[11] = ((uint8_t*)s)[11] ^ ((uint8_t*)k)[11]; - ((uint8_t*)d)[12] = ((uint8_t*)s)[12] ^ ((uint8_t*)k)[12]; - ((uint8_t*)d)[13] = ((uint8_t*)s)[13] ^ ((uint8_t*)k)[13]; - ((uint8_t*)d)[14] = ((uint8_t*)s)[14] ^ ((uint8_t*)k)[14]; - ((uint8_t*)d)[15] = ((uint8_t*)s)[15] ^ ((uint8_t*)k)[15]; + ( ( uint8_t* ) d )[0] = ( ( uint8_t* ) s )[0] ^ ( ( uint8_t* ) k )[0]; + ( ( uint8_t* ) d )[1] = ( ( uint8_t* ) s )[1] ^ ( ( uint8_t* ) k )[1]; + ( ( uint8_t* ) d )[2] = ( ( uint8_t* ) s )[2] ^ ( ( uint8_t* ) k )[2]; + ( ( uint8_t* ) d )[3] = ( ( uint8_t* ) s )[3] ^ ( ( uint8_t* ) k )[3]; + ( ( uint8_t* ) d )[4] = ( ( uint8_t* ) s )[4] ^ ( ( uint8_t* ) k )[4]; + ( ( uint8_t* ) d )[5] = ( ( uint8_t* ) s )[5] ^ ( ( uint8_t* ) k )[5]; + ( ( uint8_t* ) d )[6] = ( ( uint8_t* ) s )[6] ^ ( ( uint8_t* ) k )[6]; + ( ( uint8_t* ) d )[7] = ( ( uint8_t* ) s )[7] ^ ( ( uint8_t* ) k )[7]; + ( ( uint8_t* ) d )[8] = ( ( uint8_t* ) s )[8] ^ ( ( uint8_t* ) k )[8]; + ( ( uint8_t* ) d )[9] = ( ( uint8_t* ) s )[9] ^ ( ( uint8_t* ) k )[9]; + ( ( uint8_t* ) d )[10] = ( ( uint8_t* ) s )[10] ^ ( ( uint8_t* ) k )[10]; + ( ( uint8_t* ) d )[11] = ( ( uint8_t* ) s )[11] ^ ( ( uint8_t* ) k )[11]; + ( ( uint8_t* ) d )[12] = ( ( uint8_t* ) s )[12] ^ ( ( uint8_t* ) k )[12]; + ( ( uint8_t* ) d )[13] = ( ( uint8_t* ) s )[13] ^ ( ( uint8_t* ) k )[13]; + ( ( uint8_t* ) d )[14] = ( ( uint8_t* ) s )[14] ^ ( ( uint8_t* ) k )[14]; + ( ( uint8_t* ) d )[15] = ( ( uint8_t* ) s )[15] ^ ( ( uint8_t* ) k )[15]; #else - block_copy(d, s); - xor_block(d, k); + block_copy( d, s ); + xor_block( d, k ); #endif } static void add_round_key( uint8_t d[N_BLOCK], const uint8_t k[N_BLOCK] ) { - xor_block(d, k); + xor_block( d, k ); } static void shift_sub_rows( uint8_t st[N_BLOCK] ) -{ uint8_t tt; - - st[ 0] = s_box(st[ 0]); st[ 4] = s_box(st[ 4]); - st[ 8] = s_box(st[ 8]); st[12] = s_box(st[12]); - - tt = st[1]; st[ 1] = s_box(st[ 5]); st[ 5] = s_box(st[ 9]); - st[ 9] = s_box(st[13]); st[13] = s_box( tt ); - - tt = st[2]; st[ 2] = s_box(st[10]); st[10] = s_box( tt ); - tt = st[6]; st[ 6] = s_box(st[14]); st[14] = s_box( tt ); - - tt = st[15]; st[15] = s_box(st[11]); st[11] = s_box(st[ 7]); - st[ 7] = s_box(st[ 3]); st[ 3] = s_box( tt ); +{ + uint8_t tt; + + st[0] = s_box( st[0] ); + st[4] = s_box( st[4] ); + st[8] = s_box( st[8] ); + st[12] = s_box( st[12] ); + + tt = st[1]; + st[1] = s_box( st[5] ); + st[5] = s_box( st[9] ); + st[9] = s_box( st[13] ); + st[13] = s_box( tt ); + + tt = st[2]; + st[2] = s_box( st[10] ); + st[10] = s_box( tt ); + tt = st[6]; + st[6] = s_box( st[14] ); + st[14] = s_box( tt ); + + tt = st[15]; + st[15] = s_box( st[11] ); + st[11] = s_box( st[7] ); + st[7] = s_box( st[3] ); + st[3] = s_box( tt ); } #if defined( AES_DEC_PREKEYED ) static void inv_shift_sub_rows( uint8_t st[N_BLOCK] ) -{ uint8_t tt; - - st[ 0] = is_box(st[ 0]); st[ 4] = is_box(st[ 4]); - st[ 8] = is_box(st[ 8]); st[12] = is_box(st[12]); - - tt = st[13]; st[13] = is_box(st[9]); st[ 9] = is_box(st[5]); - st[ 5] = is_box(st[1]); st[ 1] = is_box( tt ); - - tt = st[2]; st[ 2] = is_box(st[10]); st[10] = is_box( tt ); - tt = st[6]; st[ 6] = is_box(st[14]); st[14] = is_box( tt ); - - tt = st[3]; st[ 3] = is_box(st[ 7]); st[ 7] = is_box(st[11]); - st[11] = is_box(st[15]); st[15] = is_box( tt ); +{ + uint8_t tt; + + st[0] = is_box( st[0] ); + st[4] = is_box( st[4] ); + st[8] = is_box( st[8] ); + st[12] = is_box( st[12] ); + + tt = st[13]; + st[13] = is_box( st[9] ); + st[9] = is_box( st[5] ); + st[5] = is_box( st[1] ); + st[1] = is_box( tt ); + + tt = st[2]; + st[2] = is_box( st[10] ); + st[10] = is_box( tt ); + tt = st[6]; + st[6] = is_box( st[14] ); + st[14] = is_box( tt ); + + tt = st[3]; + st[3] = is_box( st[7] ); + st[7] = is_box( st[11] ); + st[11] = is_box( st[15] ); + st[15] = is_box( tt ); } #endif #if defined( VERSION_1 ) - static void mix_sub_columns( uint8_t dt[N_BLOCK] ) - { uint8_t st[N_BLOCK]; - block_copy(st, dt); +static void mix_sub_columns( uint8_t dt[N_BLOCK] ) +{ + uint8_t st[N_BLOCK]; + block_copy( st, dt ); #else - static void mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] ) - { -#endif - dt[ 0] = gfm2_sb(st[0]) ^ gfm3_sb(st[5]) ^ s_box(st[10]) ^ s_box(st[15]); - dt[ 1] = s_box(st[0]) ^ gfm2_sb(st[5]) ^ gfm3_sb(st[10]) ^ s_box(st[15]); - dt[ 2] = s_box(st[0]) ^ s_box(st[5]) ^ gfm2_sb(st[10]) ^ gfm3_sb(st[15]); - dt[ 3] = gfm3_sb(st[0]) ^ s_box(st[5]) ^ s_box(st[10]) ^ gfm2_sb(st[15]); - - dt[ 4] = gfm2_sb(st[4]) ^ gfm3_sb(st[9]) ^ s_box(st[14]) ^ s_box(st[3]); - dt[ 5] = s_box(st[4]) ^ gfm2_sb(st[9]) ^ gfm3_sb(st[14]) ^ s_box(st[3]); - dt[ 6] = s_box(st[4]) ^ s_box(st[9]) ^ gfm2_sb(st[14]) ^ gfm3_sb(st[3]); - dt[ 7] = gfm3_sb(st[4]) ^ s_box(st[9]) ^ s_box(st[14]) ^ gfm2_sb(st[3]); - - dt[ 8] = gfm2_sb(st[8]) ^ gfm3_sb(st[13]) ^ s_box(st[2]) ^ s_box(st[7]); - dt[ 9] = s_box(st[8]) ^ gfm2_sb(st[13]) ^ gfm3_sb(st[2]) ^ s_box(st[7]); - dt[10] = s_box(st[8]) ^ s_box(st[13]) ^ gfm2_sb(st[2]) ^ gfm3_sb(st[7]); - dt[11] = gfm3_sb(st[8]) ^ s_box(st[13]) ^ s_box(st[2]) ^ gfm2_sb(st[7]); - - dt[12] = gfm2_sb(st[12]) ^ gfm3_sb(st[1]) ^ s_box(st[6]) ^ s_box(st[11]); - dt[13] = s_box(st[12]) ^ gfm2_sb(st[1]) ^ gfm3_sb(st[6]) ^ s_box(st[11]); - dt[14] = s_box(st[12]) ^ s_box(st[1]) ^ gfm2_sb(st[6]) ^ gfm3_sb(st[11]); - dt[15] = gfm3_sb(st[12]) ^ s_box(st[1]) ^ s_box(st[6]) ^ gfm2_sb(st[11]); - } +static void mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] ) +{ +#endif + dt[0] = gfm2_sb( st[0] ) ^ gfm3_sb( st[5] ) ^ s_box( st[10] ) ^ s_box( st[15] ); + dt[1] = s_box( st[0] ) ^ gfm2_sb( st[5] ) ^ gfm3_sb( st[10] ) ^ s_box( st[15] ); + dt[2] = s_box( st[0] ) ^ s_box( st[5] ) ^ gfm2_sb( st[10] ) ^ gfm3_sb( st[15] ); + dt[3] = gfm3_sb( st[0] ) ^ s_box( st[5] ) ^ s_box( st[10] ) ^ gfm2_sb( st[15] ); + + dt[4] = gfm2_sb( st[4] ) ^ gfm3_sb( st[9] ) ^ s_box( st[14] ) ^ s_box( st[3] ); + dt[5] = s_box( st[4] ) ^ gfm2_sb( st[9] ) ^ gfm3_sb( st[14] ) ^ s_box( st[3] ); + dt[6] = s_box( st[4] ) ^ s_box( st[9] ) ^ gfm2_sb( st[14] ) ^ gfm3_sb( st[3] ); + dt[7] = gfm3_sb( st[4] ) ^ s_box( st[9] ) ^ s_box( st[14] ) ^ gfm2_sb( st[3] ); + + dt[8] = gfm2_sb( st[8] ) ^ gfm3_sb( st[13] ) ^ s_box( st[2] ) ^ s_box( st[7] ); + dt[9] = s_box( st[8] ) ^ gfm2_sb( st[13] ) ^ gfm3_sb( st[2] ) ^ s_box( st[7] ); + dt[10] = s_box( st[8] ) ^ s_box( st[13] ) ^ gfm2_sb( st[2] ) ^ gfm3_sb( st[7] ); + dt[11] = gfm3_sb( st[8] ) ^ s_box( st[13] ) ^ s_box( st[2] ) ^ gfm2_sb( st[7] ); + + dt[12] = gfm2_sb( st[12] ) ^ gfm3_sb( st[1] ) ^ s_box( st[6] ) ^ s_box( st[11] ); + dt[13] = s_box( st[12] ) ^ gfm2_sb( st[1] ) ^ gfm3_sb( st[6] ) ^ s_box( st[11] ); + dt[14] = s_box( st[12] ) ^ s_box( st[1] ) ^ gfm2_sb( st[6] ) ^ gfm3_sb( st[11] ); + dt[15] = gfm3_sb( st[12] ) ^ s_box( st[1] ) ^ s_box( st[6] ) ^ gfm2_sb( st[11] ); +} #if defined( AES_DEC_PREKEYED ) #if defined( VERSION_1 ) - static void inv_mix_sub_columns( uint8_t dt[N_BLOCK] ) - { uint8_t st[N_BLOCK]; - block_copy(st, dt); +static void inv_mix_sub_columns( uint8_t dt[N_BLOCK] ) +{ + uint8_t st[N_BLOCK]; + block_copy( st, dt ); #else - static void inv_mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] ) - { +static void inv_mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] ) +{ #endif - dt[ 0] = is_box(gfm_e(st[ 0]) ^ gfm_b(st[ 1]) ^ gfm_d(st[ 2]) ^ gfm_9(st[ 3])); - dt[ 5] = is_box(gfm_9(st[ 0]) ^ gfm_e(st[ 1]) ^ gfm_b(st[ 2]) ^ gfm_d(st[ 3])); - dt[10] = is_box(gfm_d(st[ 0]) ^ gfm_9(st[ 1]) ^ gfm_e(st[ 2]) ^ gfm_b(st[ 3])); - dt[15] = is_box(gfm_b(st[ 0]) ^ gfm_d(st[ 1]) ^ gfm_9(st[ 2]) ^ gfm_e(st[ 3])); - - dt[ 4] = is_box(gfm_e(st[ 4]) ^ gfm_b(st[ 5]) ^ gfm_d(st[ 6]) ^ gfm_9(st[ 7])); - dt[ 9] = is_box(gfm_9(st[ 4]) ^ gfm_e(st[ 5]) ^ gfm_b(st[ 6]) ^ gfm_d(st[ 7])); - dt[14] = is_box(gfm_d(st[ 4]) ^ gfm_9(st[ 5]) ^ gfm_e(st[ 6]) ^ gfm_b(st[ 7])); - dt[ 3] = is_box(gfm_b(st[ 4]) ^ gfm_d(st[ 5]) ^ gfm_9(st[ 6]) ^ gfm_e(st[ 7])); - - dt[ 8] = is_box(gfm_e(st[ 8]) ^ gfm_b(st[ 9]) ^ gfm_d(st[10]) ^ gfm_9(st[11])); - dt[13] = is_box(gfm_9(st[ 8]) ^ gfm_e(st[ 9]) ^ gfm_b(st[10]) ^ gfm_d(st[11])); - dt[ 2] = is_box(gfm_d(st[ 8]) ^ gfm_9(st[ 9]) ^ gfm_e(st[10]) ^ gfm_b(st[11])); - dt[ 7] = is_box(gfm_b(st[ 8]) ^ gfm_d(st[ 9]) ^ gfm_9(st[10]) ^ gfm_e(st[11])); - - dt[12] = is_box(gfm_e(st[12]) ^ gfm_b(st[13]) ^ gfm_d(st[14]) ^ gfm_9(st[15])); - dt[ 1] = is_box(gfm_9(st[12]) ^ gfm_e(st[13]) ^ gfm_b(st[14]) ^ gfm_d(st[15])); - dt[ 6] = is_box(gfm_d(st[12]) ^ gfm_9(st[13]) ^ gfm_e(st[14]) ^ gfm_b(st[15])); - dt[11] = is_box(gfm_b(st[12]) ^ gfm_d(st[13]) ^ gfm_9(st[14]) ^ gfm_e(st[15])); - } + dt[0] = is_box( gfm_e( st[0] ) ^ gfm_b( st[1] ) ^ gfm_d( st[2] ) ^ gfm_9( st[3] ) ); + dt[5] = is_box( gfm_9( st[0] ) ^ gfm_e( st[1] ) ^ gfm_b( st[2] ) ^ gfm_d( st[3] ) ); + dt[10] = is_box( gfm_d( st[0] ) ^ gfm_9( st[1] ) ^ gfm_e( st[2] ) ^ gfm_b( st[3] ) ); + dt[15] = is_box( gfm_b( st[0] ) ^ gfm_d( st[1] ) ^ gfm_9( st[2] ) ^ gfm_e( st[3] ) ); + + dt[4] = is_box( gfm_e( st[4] ) ^ gfm_b( st[5] ) ^ gfm_d( st[6] ) ^ gfm_9( st[7] ) ); + dt[9] = is_box( gfm_9( st[4] ) ^ gfm_e( st[5] ) ^ gfm_b( st[6] ) ^ gfm_d( st[7] ) ); + dt[14] = is_box( gfm_d( st[4] ) ^ gfm_9( st[5] ) ^ gfm_e( st[6] ) ^ gfm_b( st[7] ) ); + dt[3] = is_box( gfm_b( st[4] ) ^ gfm_d( st[5] ) ^ gfm_9( st[6] ) ^ gfm_e( st[7] ) ); + + dt[8] = is_box( gfm_e( st[8] ) ^ gfm_b( st[9] ) ^ gfm_d( st[10] ) ^ gfm_9( st[11] ) ); + dt[13] = is_box( gfm_9( st[8] ) ^ gfm_e( st[9] ) ^ gfm_b( st[10] ) ^ gfm_d( st[11] ) ); + dt[2] = is_box( gfm_d( st[8] ) ^ gfm_9( st[9] ) ^ gfm_e( st[10] ) ^ gfm_b( st[11] ) ); + dt[7] = is_box( gfm_b( st[8] ) ^ gfm_d( st[9] ) ^ gfm_9( st[10] ) ^ gfm_e( st[11] ) ); + + dt[12] = is_box( gfm_e( st[12] ) ^ gfm_b( st[13] ) ^ gfm_d( st[14] ) ^ gfm_9( st[15] ) ); + dt[1] = is_box( gfm_9( st[12] ) ^ gfm_e( st[13] ) ^ gfm_b( st[14] ) ^ gfm_d( st[15] ) ); + dt[6] = is_box( gfm_d( st[12] ) ^ gfm_9( st[13] ) ^ gfm_e( st[14] ) ^ gfm_b( st[15] ) ); + dt[11] = is_box( gfm_b( st[12] ) ^ gfm_d( st[13] ) ^ gfm_9( st[14] ) ^ gfm_e( st[15] ) ); +} #endif @@ -510,7 +526,7 @@ static void inv_shift_sub_rows( uint8_t st[N_BLOCK] ) /* Set the cipher key for the pre-keyed version */ -return_type aes_set_key( const uint8_t key[], length_type keylen, aes_context ctx[1] ) +return_type smtc_aes_set_key( const uint8_t key[], length_type keylen, aes_context ctx[1] ) { uint8_t cc, rc, hi; @@ -522,13 +538,14 @@ return_type aes_set_key( const uint8_t key[], length_type keylen, aes_context ct break; default: ctx->rnd = 0; - return ( uint8_t )-1; + return ( uint8_t ) -1; } - block_copy_nn(ctx->ksch, key, keylen); - hi = (keylen + 28) << 2; - ctx->rnd = (hi >> 4) - 1; + block_copy_nn( ctx->ksch, key, keylen ); + hi = ( keylen + 28 ) << 2; + ctx->rnd = ( hi >> 4 ) - 1; for( cc = keylen, rc = 1; cc < hi; cc += 4 ) - { uint8_t tt, t0, t1, t2, t3; + { + uint8_t tt, t0, t1, t2, t3; t0 = ctx->ksch[cc - 4]; t1 = ctx->ksch[cc - 3]; @@ -537,20 +554,20 @@ return_type aes_set_key( const uint8_t key[], length_type keylen, aes_context ct if( cc % keylen == 0 ) { tt = t0; - t0 = s_box(t1) ^ rc; - t1 = s_box(t2); - t2 = s_box(t3); - t3 = s_box(tt); - rc = f2(rc); + t0 = s_box( t1 ) ^ rc; + t1 = s_box( t2 ); + t2 = s_box( t3 ); + t3 = s_box( tt ); + rc = f2( rc ); } else if( keylen > 24 && cc % keylen == 16 ) { - t0 = s_box(t0); - t1 = s_box(t1); - t2 = s_box(t2); - t3 = s_box(t3); + t0 = s_box( t0 ); + t1 = s_box( t1 ); + t2 = s_box( t2 ); + t3 = s_box( t3 ); } - tt = cc - keylen; + tt = cc - keylen; ctx->ksch[cc + 0] = ctx->ksch[tt + 0] ^ t0; ctx->ksch[cc + 1] = ctx->ksch[tt + 1] ^ t1; ctx->ksch[cc + 2] = ctx->ksch[tt + 2] ^ t2; @@ -565,46 +582,46 @@ return_type aes_set_key( const uint8_t key[], length_type keylen, aes_context ct /* Encrypt a single block of 16 bytes */ -return_type aes_encrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] ) +return_type smtc_aes_encrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] ) { if( ctx->rnd ) { uint8_t s1[N_BLOCK], r; copy_and_key( s1, in, ctx->ksch ); - for( r = 1 ; r < ctx->rnd ; ++r ) + for( r = 1; r < ctx->rnd; ++r ) #if defined( VERSION_1 ) { mix_sub_columns( s1 ); - add_round_key( s1, ctx->ksch + r * N_BLOCK); + add_round_key( s1, ctx->ksch + r * N_BLOCK ); } #else - { uint8_t s2[N_BLOCK]; + { + uint8_t s2[N_BLOCK]; mix_sub_columns( s2, s1 ); - copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK); + copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK ); } #endif shift_sub_rows( s1 ); copy_and_key( out, s1, ctx->ksch + r * N_BLOCK ); } else - return ( uint8_t )-1; + return ( uint8_t ) -1; return 0; } /* CBC encrypt a number of blocks (input and return an IV) */ -return_type aes_cbc_encrypt( const uint8_t *in, uint8_t *out, - int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] ) +return_type smtc_aes_cbc_encrypt( const uint8_t* in, uint8_t* out, int32_t n_block, uint8_t iv[N_BLOCK], + const aes_context ctx[1] ) { - - while(n_block--) + while( n_block-- ) { - xor_block(iv, in); - if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS) + xor_block( iv, in ); + if( smtc_aes_encrypt( iv, iv, ctx ) != EXIT_SUCCESS ) return EXIT_FAILURE; - //memcpy(out, iv, N_BLOCK); - block_copy(out, iv); + // memcpy(out, iv, N_BLOCK); + block_copy( out, iv ); in += N_BLOCK; out += N_BLOCK; } @@ -617,7 +634,7 @@ return_type aes_cbc_encrypt( const uint8_t *in, uint8_t *out, /* Decrypt a single block of 16 bytes */ -return_type aes_decrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] ) +return_type smtc_aes_decrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] ) { if( ctx->rnd ) { @@ -625,14 +642,15 @@ return_type aes_decrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const copy_and_key( s1, in, ctx->ksch + ctx->rnd * N_BLOCK ); inv_shift_sub_rows( s1 ); - for( r = ctx->rnd ; --r ; ) + for( r = ctx->rnd; --r; ) #if defined( VERSION_1 ) { add_round_key( s1, ctx->ksch + r * N_BLOCK ); inv_mix_sub_columns( s1 ); } #else - { uint8_t s2[N_BLOCK]; + { + uint8_t s2[N_BLOCK]; copy_and_key( s2, s1, ctx->ksch + r * N_BLOCK ); inv_mix_sub_columns( s1, s2 ); } @@ -646,19 +664,20 @@ return_type aes_decrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const /* CBC decrypt a number of blocks (input and return an IV) */ -return_type aes_cbc_decrypt( const uint8_t *in, uint8_t *out, - int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] ) +return_type smtc_aes_cbc_decrypt( const uint8_t* in, uint8_t* out, int32_t n_block, uint8_t iv[N_BLOCK], + const aes_context ctx[1] ) { - while(n_block--) - { uint8_t tmp[N_BLOCK]; + while( n_block-- ) + { + uint8_t tmp[N_BLOCK]; - //memcpy(tmp, in, N_BLOCK); - block_copy(tmp, in); - if(aes_decrypt(in, out, ctx) != EXIT_SUCCESS) + // memcpy(tmp, in, N_BLOCK); + block_copy( tmp, in ); + if( smtc_aes_decrypt( in, out, ctx ) != EXIT_SUCCESS ) return EXIT_FAILURE; - xor_block(out, iv); - //memcpy(iv, tmp, N_BLOCK); - block_copy(iv, tmp); + xor_block( out, iv ); + // memcpy(iv, tmp, N_BLOCK); + block_copy( iv, tmp ); in += N_BLOCK; out += N_BLOCK; } @@ -671,16 +690,17 @@ return_type aes_cbc_decrypt( const uint8_t *in, uint8_t *out, /* The 'on the fly' encryption key update for for 128 bit keys */ -static void update_encrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc ) -{ uint8_t cc; +static void update_encrypt_key_128( uint8_t k[N_BLOCK], uint8_t* rc ) +{ + uint8_t cc; - k[0] ^= s_box(k[13]) ^ *rc; - k[1] ^= s_box(k[14]); - k[2] ^= s_box(k[15]); - k[3] ^= s_box(k[12]); + k[0] ^= s_box( k[13] ) ^ *rc; + k[1] ^= s_box( k[14] ); + k[2] ^= s_box( k[15] ); + k[3] ^= s_box( k[12] ); *rc = f2( *rc ); - for(cc = 4; cc < 16; cc += 4 ) + for( cc = 4; cc < 16; cc += 4 ) { k[cc + 0] ^= k[cc - 4]; k[cc + 1] ^= k[cc - 3]; @@ -691,15 +711,16 @@ static void update_encrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc ) /* Encrypt a single block of 16 bytes with 'on the fly' 128 bit keying */ -void aes_encrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], - const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] ) -{ uint8_t s1[N_BLOCK], r, rc = 1; +void smtc_aes_encrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const uint8_t key[N_BLOCK], + uint8_t o_key[N_BLOCK] ) +{ + uint8_t s1[N_BLOCK], r, rc = 1; - if(o_key != key) + if( o_key != key ) block_copy( o_key, key ); copy_and_key( s1, in, o_key ); - for( r = 1 ; r < 10 ; ++r ) + for( r = 1; r < 10; ++r ) #if defined( VERSION_1 ) { mix_sub_columns( s1 ); @@ -707,7 +728,8 @@ void aes_encrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], add_round_key( s1, o_key ); } #else - { uint8_t s2[N_BLOCK]; + { + uint8_t s2[N_BLOCK]; mix_sub_columns( s2, s1 ); update_encrypt_key_128( o_key, &rc ); copy_and_key( s1, s2, o_key ); @@ -725,8 +747,9 @@ void aes_encrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], /* The 'on the fly' decryption key update for for 128 bit keys */ -static void update_decrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc ) -{ uint8_t cc; +static void update_decrypt_key_128( uint8_t k[N_BLOCK], uint8_t* rc ) +{ + uint8_t cc; for( cc = 12; cc > 0; cc -= 4 ) { @@ -735,26 +758,26 @@ static void update_decrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc ) k[cc + 2] ^= k[cc - 2]; k[cc + 3] ^= k[cc - 1]; } - *rc = d2(*rc); - k[0] ^= s_box(k[13]) ^ *rc; - k[1] ^= s_box(k[14]); - k[2] ^= s_box(k[15]); - k[3] ^= s_box(k[12]); + *rc = d2( *rc ); + k[0] ^= s_box( k[13] ) ^ *rc; + k[1] ^= s_box( k[14] ); + k[2] ^= s_box( k[15] ); + k[3] ^= s_box( k[12] ); } /* Decrypt a single block of 16 bytes with 'on the fly' 128 bit keying */ -void aes_decrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], - const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] ) +void smtc_aes_decrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const uint8_t key[N_BLOCK], + uint8_t o_key[N_BLOCK] ) { uint8_t s1[N_BLOCK], r, rc = 0x6c; - if(o_key != key) + if( o_key != key ) block_copy( o_key, key ); copy_and_key( s1, in, o_key ); inv_shift_sub_rows( s1 ); - for( r = 10 ; --r ; ) + for( r = 10; --r; ) #if defined( VERSION_1 ) { update_decrypt_key_128( o_key, &rc ); @@ -762,7 +785,8 @@ void aes_decrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], inv_mix_sub_columns( s1 ); } #else - { uint8_t s2[N_BLOCK]; + { + uint8_t s2[N_BLOCK]; update_decrypt_key_128( o_key, &rc ); copy_and_key( s2, s1, o_key ); inv_mix_sub_columns( s1, s2 ); @@ -778,16 +802,17 @@ void aes_decrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], /* The 'on the fly' encryption key update for for 256 bit keys */ -static void update_encrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc ) -{ uint8_t cc; +static void update_encrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t* rc ) +{ + uint8_t cc; - k[0] ^= s_box(k[29]) ^ *rc; - k[1] ^= s_box(k[30]); - k[2] ^= s_box(k[31]); - k[3] ^= s_box(k[28]); + k[0] ^= s_box( k[29] ) ^ *rc; + k[1] ^= s_box( k[30] ); + k[2] ^= s_box( k[31] ); + k[3] ^= s_box( k[28] ); *rc = f2( *rc ); - for(cc = 4; cc < 16; cc += 4) + for( cc = 4; cc < 16; cc += 4 ) { k[cc + 0] ^= k[cc - 4]; k[cc + 1] ^= k[cc - 3]; @@ -795,10 +820,10 @@ static void update_encrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc ) k[cc + 3] ^= k[cc - 1]; } - k[16] ^= s_box(k[12]); - k[17] ^= s_box(k[13]); - k[18] ^= s_box(k[14]); - k[19] ^= s_box(k[15]); + k[16] ^= s_box( k[12] ); + k[17] ^= s_box( k[13] ); + k[18] ^= s_box( k[14] ); + k[19] ^= s_box( k[15] ); for( cc = 20; cc < 32; cc += 4 ) { @@ -811,21 +836,21 @@ static void update_encrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc ) /* Encrypt a single block of 16 bytes with 'on the fly' 256 bit keying */ -void aes_encrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], - const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] ) +void smtc_aes_encrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const uint8_t key[2 * N_BLOCK], + uint8_t o_key[2 * N_BLOCK] ) { uint8_t s1[N_BLOCK], r, rc = 1; - if(o_key != key) + if( o_key != key ) { block_copy( o_key, key ); block_copy( o_key + 16, key + 16 ); } copy_and_key( s1, in, o_key ); - for( r = 1 ; r < 14 ; ++r ) + for( r = 1; r < 14; ++r ) #if defined( VERSION_1 ) { - mix_sub_columns(s1); + mix_sub_columns( s1 ); if( r & 1 ) add_round_key( s1, o_key + 16 ); else @@ -835,7 +860,8 @@ void aes_encrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], } } #else - { uint8_t s2[N_BLOCK]; + { + uint8_t s2[N_BLOCK]; mix_sub_columns( s2, s1 ); if( r & 1 ) copy_and_key( s1, s2, o_key + 16 ); @@ -858,10 +884,11 @@ void aes_encrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], /* The 'on the fly' encryption key update for for 256 bit keys */ -static void update_decrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc ) -{ uint8_t cc; +static void update_decrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t* rc ) +{ + uint8_t cc; - for(cc = 28; cc > 16; cc -= 4) + for( cc = 28; cc > 16; cc -= 4 ) { k[cc + 0] ^= k[cc - 4]; k[cc + 1] ^= k[cc - 3]; @@ -869,12 +896,12 @@ static void update_decrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc ) k[cc + 3] ^= k[cc - 1]; } - k[16] ^= s_box(k[12]); - k[17] ^= s_box(k[13]); - k[18] ^= s_box(k[14]); - k[19] ^= s_box(k[15]); + k[16] ^= s_box( k[12] ); + k[17] ^= s_box( k[13] ); + k[18] ^= s_box( k[14] ); + k[19] ^= s_box( k[15] ); - for(cc = 12; cc > 0; cc -= 4) + for( cc = 12; cc > 0; cc -= 4 ) { k[cc + 0] ^= k[cc - 4]; k[cc + 1] ^= k[cc - 3]; @@ -882,22 +909,22 @@ static void update_decrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc ) k[cc + 3] ^= k[cc - 1]; } - *rc = d2(*rc); - k[0] ^= s_box(k[29]) ^ *rc; - k[1] ^= s_box(k[30]); - k[2] ^= s_box(k[31]); - k[3] ^= s_box(k[28]); + *rc = d2( *rc ); + k[0] ^= s_box( k[29] ) ^ *rc; + k[1] ^= s_box( k[30] ); + k[2] ^= s_box( k[31] ); + k[3] ^= s_box( k[28] ); } /* Decrypt a single block of 16 bytes with 'on the fly' 256 bit keying */ -void aes_decrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], - const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] ) +void smtc_aes_decrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const uint8_t key[2 * N_BLOCK], + uint8_t o_key[2 * N_BLOCK] ) { uint8_t s1[N_BLOCK], r, rc = 0x80; - if(o_key != key) + if( o_key != key ) { block_copy( o_key, key ); block_copy( o_key + 16, key + 16 ); @@ -906,7 +933,7 @@ void aes_decrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], copy_and_key( s1, in, o_key ); inv_shift_sub_rows( s1 ); - for( r = 14 ; --r ; ) + for( r = 14; --r; ) #if defined( VERSION_1 ) { if( ( r & 1 ) ) @@ -919,7 +946,8 @@ void aes_decrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], inv_mix_sub_columns( s1 ); } #else - { uint8_t s2[N_BLOCK]; + { + uint8_t s2[N_BLOCK]; if( ( r & 1 ) ) { update_decrypt_key_256( o_key, &rc ); diff --git a/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.h b/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.h index b4f9f40..da14fe0 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.h +++ b/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/aes.h @@ -28,8 +28,8 @@ cipher state. */ -#ifndef AES_H -#define AES_H +#ifndef SMTC_AES_H +#define SMTC_AES_H #ifdef __cplusplus extern "C" { @@ -38,28 +38,28 @@ extern "C" { #include #if 1 -# define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */ +#define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */ #endif #if 0 -# define AES_DEC_PREKEYED /* AES decryption with a precomputed key schedule */ +#define AES_DEC_PREKEYED /* AES decryption with a precomputed key schedule */ #endif #if 0 -# define AES_ENC_128_OTFK /* AES encryption with 'on the fly' 128 bit keying */ +#define AES_ENC_128_OTFK /* AES encryption with 'on the fly' 128 bit keying */ #endif #if 0 -# define AES_DEC_128_OTFK /* AES decryption with 'on the fly' 128 bit keying */ +#define AES_DEC_128_OTFK /* AES decryption with 'on the fly' 128 bit keying */ #endif #if 0 -# define AES_ENC_256_OTFK /* AES encryption with 'on the fly' 256 bit keying */ +#define AES_ENC_256_OTFK /* AES encryption with 'on the fly' 256 bit keying */ #endif #if 0 -# define AES_DEC_256_OTFK /* AES decryption with 'on the fly' 256 bit keying */ +#define AES_DEC_256_OTFK /* AES decryption with 'on the fly' 256 bit keying */ #endif -#define N_ROW 4 -#define N_COL 4 -#define N_BLOCK (N_ROW * N_COL) -#define N_MAX_ROUNDS 14 +#define N_ROW 4 +#define N_COL 4 +#define N_BLOCK ( N_ROW * N_COL ) +#define N_MAX_ROUNDS 14 typedef uint8_t return_type; @@ -70,7 +70,8 @@ typedef uint8_t return_type; typedef uint8_t length_type; typedef struct -{ uint8_t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK]; +{ + uint8_t ksch[( N_MAX_ROUNDS + 1 ) * N_BLOCK]; uint8_t rnd; } aes_context; @@ -84,35 +85,23 @@ typedef struct #if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED ) -return_type aes_set_key( const uint8_t key[], - length_type keylen, - aes_context ctx[1] ); +return_type smtc_aes_set_key( const uint8_t key[], length_type keylen, aes_context ctx[1] ); #endif #if defined( AES_ENC_PREKEYED ) -return_type aes_encrypt( const uint8_t in[N_BLOCK], - uint8_t out[N_BLOCK], - const aes_context ctx[1] ); +return_type smtc_aes_encrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] ); -return_type aes_cbc_encrypt( const uint8_t *in, - uint8_t *out, - int32_t n_block, - uint8_t iv[N_BLOCK], - const aes_context ctx[1] ); +return_type smtc_aes_cbc_encrypt( const uint8_t* in, uint8_t* out, int32_t n_block, uint8_t iv[N_BLOCK], + const aes_context ctx[1] ); #endif #if defined( AES_DEC_PREKEYED ) -return_type aes_decrypt( const uint8_t in[N_BLOCK], - uint8_t out[N_BLOCK], - const aes_context ctx[1] ); +return_type smtc_aes_decrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] ); -return_type aes_cbc_decrypt( const uint8_t *in, - uint8_t *out, - int32_t n_block, - uint8_t iv[N_BLOCK], - const aes_context ctx[1] ); +return_type smtc_aes_cbc_decrypt( const uint8_t* in, uint8_t* out, int32_t n_block, uint8_t iv[N_BLOCK], + const aes_context ctx[1] ); #endif /* The following calls are for 'on the fly' keying. In this case the @@ -121,7 +110,7 @@ return_type aes_cbc_decrypt( const uint8_t *in, The encryption subroutines take a key in an array of bytes in key[L] where L is 16, 24 or 32 bytes for key lengths of 128, 192, and 256 bits respectively. They then encrypts the input - data, in[] with this key and put the reult in the output array + data, in[] with this key and put the result in the output array out[]. In addition, the second key array, o_key[L], is used to output the key that is needed by the decryption subroutine to reverse the encryption operation. The two key arrays can @@ -136,31 +125,23 @@ return_type aes_cbc_decrypt( const uint8_t *in, */ #if defined( AES_ENC_128_OTFK ) -void aes_encrypt_128( const uint8_t in[N_BLOCK], - uint8_t out[N_BLOCK], - const uint8_t key[N_BLOCK], - uint8_t o_key[N_BLOCK] ); +void smtc_aes_encrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const uint8_t key[N_BLOCK], + uint8_t o_key[N_BLOCK] ); #endif #if defined( AES_DEC_128_OTFK ) -void aes_decrypt_128( const uint8_t in[N_BLOCK], - uint8_t out[N_BLOCK], - const uint8_t key[N_BLOCK], - uint8_t o_key[N_BLOCK] ); +void smtc_aes_decrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const uint8_t key[N_BLOCK], + uint8_t o_key[N_BLOCK] ); #endif #if defined( AES_ENC_256_OTFK ) -void aes_encrypt_256( const uint8_t in[N_BLOCK], - uint8_t out[N_BLOCK], - const uint8_t key[2 * N_BLOCK], - uint8_t o_key[2 * N_BLOCK] ); +void smtc_aes_encrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const uint8_t key[2 * N_BLOCK], + uint8_t o_key[2 * N_BLOCK] ); #endif #if defined( AES_DEC_256_OTFK ) -void aes_decrypt_256( const uint8_t in[N_BLOCK], - uint8_t out[N_BLOCK], - const uint8_t key[2 * N_BLOCK], - uint8_t o_key[2 * N_BLOCK] ); +void smtc_aes_decrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const uint8_t key[2 * N_BLOCK], + uint8_t o_key[2 * N_BLOCK] ); #endif #ifdef __cplusplus diff --git a/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/cmac.c b/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/cmac.c index 3bc327c..a07d855 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/cmac.c +++ b/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/cmac.c @@ -73,7 +73,7 @@ void AES_CMAC_Init( AES_CMAC_CTX* ctx ) void AES_CMAC_SetKey( AES_CMAC_CTX* ctx, const uint8_t key[AES_CMAC_KEY_LENGTH] ) { - aes_set_key( key, AES_CMAC_KEY_LENGTH, &ctx->rijndael ); + smtc_aes_set_key( key, AES_CMAC_KEY_LENGTH, &ctx->rijndael ); } void AES_CMAC_Update( AES_CMAC_CTX* ctx, const uint8_t* data, uint32_t len ) @@ -91,7 +91,7 @@ void AES_CMAC_Update( AES_CMAC_CTX* ctx, const uint8_t* data, uint32_t len ) XOR( ctx->M_last, ctx->X ); memcpy( in, &ctx->X[0], 16 ); // Otherwise it does not look good - aes_encrypt( in, in, &ctx->rijndael ); + smtc_aes_encrypt( in, in, &ctx->rijndael ); memcpy( &ctx->X[0], in, 16 ); data += mlen; @@ -103,7 +103,7 @@ void AES_CMAC_Update( AES_CMAC_CTX* ctx, const uint8_t* data, uint32_t len ) XOR( data, ctx->X ); memcpy( in, &ctx->X[0], 16 ); // Otherwise it does not look good - aes_encrypt( in, in, &ctx->rijndael ); + smtc_aes_encrypt( in, in, &ctx->rijndael ); memcpy( &ctx->X[0], in, 16 ); data += 16; @@ -121,7 +121,7 @@ void AES_CMAC_Final( uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX* ctx ) /* generate subkey K1 */ memset( K, '\0', 16 ); - aes_encrypt( K, K, &ctx->rijndael ); + smtc_aes_encrypt( K, K, &ctx->rijndael ); if( K[0] & 0x80 ) { @@ -157,6 +157,6 @@ void AES_CMAC_Final( uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX* ctx ) XOR( ctx->M_last, ctx->X ); memcpy( in, &ctx->X[0], 16 ); // Otherwise it does not look good - aes_encrypt( in, digest, &ctx->rijndael ); + smtc_aes_encrypt( in, digest, &ctx->rijndael ); memset( K, 0, sizeof K ); } diff --git a/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/soft_se.c b/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/soft_se.c index de110f9..29073ad 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/soft_se.c +++ b/lbm_lib/smtc_modem_core/smtc_modem_crypto/soft_secure_element/soft_se.c @@ -63,7 +63,7 @@ /*! * Number of keys supported in soft secure element */ -#define SOFT_SE_NUMBER_OF_KEYS 26 +#define SOFT_SE_NUMBER_OF_KEYS 27 /*! * JoinAccept frame maximum size @@ -269,7 +269,7 @@ /*! \ * Relay WOR Session key (Dynamically updated) \ */ \ - .key_id = SMTC_RELAY_ROOT_WOR_S_KEY, \ + .key_id = SMTC_SE_RELAY_ROOT_WOR_S_KEY, \ .key_value = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00 }, \ }, \ @@ -277,7 +277,7 @@ /*! \ * Relay WOR Integrity session key (Dynamically updated) \ */ \ - .key_id = SMTC_RELAY_WOR_S_INT_KEY, \ + .key_id = SMTC_SE_RELAY_WOR_S_INT_KEY, \ .key_value = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00 }, \ }, \ @@ -285,7 +285,15 @@ /*! \ * Relay WOR Encryption session key (Dynamically updated) \ */ \ - .key_id = SMTC_RELAY_WOR_S_ENC_KEY, \ + .key_id = SMTC_SE_RELAY_WOR_S_ENC_KEY, \ + .key_value = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00 }, \ + }, \ + { \ + /*! \ + * Fragmentation data block integrity key (Dynamically updated) \ + */ \ + .key_id = SMTC_SE_DATA_BLOCK_INT_KEY, \ .key_value = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00 }, \ }, \ @@ -505,13 +513,13 @@ smtc_se_return_code_t smtc_secure_element_aes_encrypt( const uint8_t* buffer, ui if( rc == SMTC_SE_RC_SUCCESS ) { - aes_set_key( key_item->key_value, 16, &aes_ctx ); + smtc_aes_set_key( key_item->key_value, 16, &aes_ctx ); uint8_t block = 0; while( size != 0 ) { - aes_encrypt( &buffer[block], &enc_buffer[block], &aes_ctx ); + smtc_aes_encrypt( &buffer[block], &enc_buffer[block], &aes_ctx ); block = block + 16; size = size - 16; } @@ -557,6 +565,40 @@ smtc_se_return_code_t smtc_secure_element_derive_and_store_key( uint8_t* input, return SMTC_SE_RC_SUCCESS; } +smtc_se_return_code_t smtc_secure_element_derive_relay_session_keys( uint32_t dev_addr, uint8_t stack_id ) +{ + uint8_t block[16]; + memset( block, 0, sizeof( block ) ); + block[0] = 0x01; + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_derive_and_store_key( block, SMTC_SE_NWK_S_ENC_KEY, + SMTC_SE_RELAY_ROOT_WOR_S_KEY, + stack_id ) == SMTC_SE_RC_SUCCESS ); + + memset( block, 0, sizeof( block ) ); + block[0] = 0x01; + block[1] = ( uint8_t ) ( dev_addr ); + block[2] = ( uint8_t ) ( dev_addr >> 8 ); + block[3] = ( uint8_t ) ( dev_addr >> 16 ); + block[4] = ( uint8_t ) ( dev_addr >> 24 ); + + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_derive_and_store_key( block, SMTC_SE_RELAY_ROOT_WOR_S_KEY, + SMTC_SE_RELAY_WOR_S_INT_KEY, + stack_id ) == SMTC_SE_RC_SUCCESS ); + + memset( block, 0, sizeof( block ) ); + block[0] = 0x02; + block[1] = ( uint8_t ) ( dev_addr ); + block[2] = ( uint8_t ) ( dev_addr >> 8 ); + block[3] = ( uint8_t ) ( dev_addr >> 16 ); + block[4] = ( uint8_t ) ( dev_addr >> 24 ); + SMTC_MODEM_HAL_PANIC_ON_FAILURE( smtc_secure_element_derive_and_store_key( block, SMTC_SE_RELAY_ROOT_WOR_S_KEY, + SMTC_SE_RELAY_WOR_S_ENC_KEY, + stack_id ) == SMTC_SE_RC_SUCCESS ); + + return SMTC_SE_RC_SUCCESS; +} + smtc_se_return_code_t smtc_secure_element_process_join_accept( smtc_se_join_req_identifier_t join_req_type, uint8_t joineui[SMTC_SE_EUI_SIZE], uint16_t dev_nonce, const uint8_t* enc_join_accept, diff --git a/lbm_lib/smtc_modem_core/smtc_modem_test.c b/lbm_lib/smtc_modem_core/smtc_modem_test.c index 95ec987..4daeae6 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem_test.c +++ b/lbm_lib/smtc_modem_core/smtc_modem_test.c @@ -57,7 +57,10 @@ #include "smtc_lora_cad_bt.h" #include "ralf.h" #include "radio_planner.h" - +#include "radio_planner_hook_id_defs.h" +#include "modem_tx_protocol_manager.h" +#include "smtc_modem_test.h" +#include "modem_event_utilities.h" #if defined( SX128X ) #include "sx128x_hal.h" #elif defined( SX126X ) @@ -85,82 +88,16 @@ */ static const uint8_t sync_word_gfsk[] = { 0xC1, 0x94, 0xC1 }; -/* clang-format off */ -/*! - * \brief Conversion table for Spreading Factor - */ -static const uint8_t modem_test_sf_convert[SMTC_MODEM_TEST_LORA_SF_COUNT] = { - [SMTC_MODEM_TEST_LORA_SF5] = RAL_LORA_SF5, - [SMTC_MODEM_TEST_LORA_SF6] = RAL_LORA_SF6, - [SMTC_MODEM_TEST_LORA_SF7] = RAL_LORA_SF7, - [SMTC_MODEM_TEST_LORA_SF8] = RAL_LORA_SF8, - [SMTC_MODEM_TEST_LORA_SF9] = RAL_LORA_SF9, - [SMTC_MODEM_TEST_LORA_SF10] = RAL_LORA_SF10, - [SMTC_MODEM_TEST_LORA_SF11] = RAL_LORA_SF11, - [SMTC_MODEM_TEST_LORA_SF12] = RAL_LORA_SF12, -}; - /*! - * \brief Conversion table for BandWidth + * \brief LoRaWAN LR_FHSS sync word */ -static const uint8_t modem_test_bw_convert[SMTC_MODEM_TEST_BW_COUNT] = { - [SMTC_MODEM_TEST_BW_125_KHZ] = RAL_LORA_BW_125_KHZ, - [SMTC_MODEM_TEST_BW_250_KHZ] = RAL_LORA_BW_250_KHZ, - [SMTC_MODEM_TEST_BW_500_KHZ] = RAL_LORA_BW_500_KHZ, - [SMTC_MODEM_TEST_BW_200_KHZ] = RAL_LORA_BW_200_KHZ, - [SMTC_MODEM_TEST_BW_400_KHZ] = RAL_LORA_BW_400_KHZ, - [SMTC_MODEM_TEST_BW_800_KHZ] = RAL_LORA_BW_800_KHZ, - [SMTC_MODEM_TEST_BW_1600_KHZ] = RAL_LORA_BW_1600_KHZ, -}; - -/*! - * \brief Conversion table for Coding Rate - */ -static const uint8_t modem_test_cr_convert[SMTC_MODEM_TEST_CR_COUNT] = { - [SMTC_MODEM_TEST_CR_4_5] = RAL_LORA_CR_4_5, - [SMTC_MODEM_TEST_CR_4_6] = RAL_LORA_CR_4_6, - [SMTC_MODEM_TEST_CR_4_7] = RAL_LORA_CR_4_7, - [SMTC_MODEM_TEST_CR_4_8] = RAL_LORA_CR_4_8, - [SMTC_MODEM_TEST_CR_LI_4_5] = RAL_LORA_CR_LI_4_5, - [SMTC_MODEM_TEST_CR_LI_4_6] = RAL_LORA_CR_LI_4_6, - [SMTC_MODEM_TEST_CR_LI_4_8] = RAL_LORA_CR_LI_4_8, -}; -/*! - * \brief Helper table for gfsk Bandwidth - */ -static const uint32_t modem_test_bw_helper[SMTC_MODEM_TEST_BW_COUNT] = { - [SMTC_MODEM_TEST_BW_125_KHZ] = 125000, - [SMTC_MODEM_TEST_BW_250_KHZ] = 250000, - [SMTC_MODEM_TEST_BW_500_KHZ] = 100000, - [SMTC_MODEM_TEST_BW_200_KHZ] = 200000, - [SMTC_MODEM_TEST_BW_400_KHZ] = 400000, - [SMTC_MODEM_TEST_BW_800_KHZ] = 800000, - [SMTC_MODEM_TEST_BW_1600_KHZ] = 1600000, -}; -/* clang-format on */ +static const uint8_t sync_word_lr_fhss[] = { 0x2C, 0x0F, 0x79, 0x95 }; /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- */ -/*! - * \typedef modem_test_context_t - * \brief Test context - */ -typedef struct modem_test_context -{ - radio_planner_t* rp; //!< Radio planner instance - lr1_stack_mac_t* lr1_mac_obj; //!< Lorawan lr1mac instance - uint8_t hook_id; //!< Lorawan lr1mac hook id used for test - uint8_t tx_rx_payload[255]; //!< Transmit/Received buffer - int16_t rssi; //!< Placeholder for mean rssi - bool rssi_ready; //!< True when rssi mean test is finished - uint32_t total_rx_packets; //!< Number of received packet - bool random_payload; //!< True in case of random payload - smtc_lbt_t lbt_obj; -} modem_test_context_t; - /* * ----------------------------------------------------------------------------- * --- PRIVATE VARIABLES ------------------------------------------------------- @@ -168,14 +105,18 @@ typedef struct modem_test_context modem_test_context_t modem_test_context; +static rp_task_t rp_task; +static rp_radio_params_t rp_radio_params; /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DECLARATION ------------------------------------------- */ +static void modem_test_enqueue_task( uint8_t* payload, uint8_t payload_length ); /*! * \brief Empty callback for test * \retval [out] context* - modem_test_context_t */ + void modem_test_empty_callback( modem_test_context_t* context ); void modem_test_compute_rssi_callback( modem_test_context_t* context ); @@ -220,6 +161,8 @@ smtc_modem_return_code_t smtc_modem_test_start( void ) modem_set_test_mode_status( true ); SMTC_MODEM_HAL_TRACE_INFO( "TST MODE: START\n" ); memset( &modem_test_context, 0, sizeof( modem_test_context_t ) ); + memset( &rp_task, 0, sizeof( rp_task_t ) ); + memset( &rp_radio_params, 0, sizeof( rp_radio_params_t ) ); modem_test_context.rp = modem_get_rp( ); // modem_test_context.lr1_mac_obj = lorawan_api_stack_mac_get( TEST_STACK_ID_0 ); @@ -242,7 +185,7 @@ smtc_modem_return_code_t smtc_modem_test_stop( void ) return SMTC_MODEM_RC_INVALID; } - if( smtc_modem_test_nop( ) != SMTC_MODEM_RC_OK ) + if( smtc_modem_test_nop( true ) != SMTC_MODEM_RC_OK ) { return SMTC_MODEM_RC_FAIL; } @@ -265,171 +208,235 @@ smtc_modem_return_code_t smtc_modem_test_tx_hop( void ) return SMTC_MODEM_RC_FAIL; } -smtc_modem_return_code_t smtc_modem_test_nop( void ) +smtc_modem_return_code_t smtc_modem_test_nop( bool reset_radio ) { if( modem_get_test_mode_status( ) == false ) { SMTC_MODEM_HAL_TRACE_WARNING( "TEST FUNCTION CANNOT BE CALLED: NOT IN TEST MODE\n" ); return SMTC_MODEM_RC_INVALID; } + modem_test_context.nb_of_repetition = 1; rp_task_abort( modem_test_context.rp, modem_test_context.hook_id ); // force a call of rp_callback to re-arbitrate the radio planner before the next loop rp_callback( modem_test_context.rp ); - smtc_modem_test_radio_reset( ); + if( reset_radio ) + { + smtc_modem_test_radio_reset( ); + } // Re enable failsafe on radio planner rp_disable_failsafe( modem_test_context.rp, false ); return SMTC_MODEM_RC_OK; } -smtc_modem_return_code_t smtc_modem_test_tx( uint8_t* payload, uint8_t payload_length, uint32_t frequency_hz, - int8_t tx_power_dbm, smtc_modem_test_sf_t sf, smtc_modem_test_bw_t bw, - smtc_modem_test_cr_t cr, uint32_t preamble_size, bool continuous_tx ) +smtc_modem_return_code_t smtc_modem_test_tx_lora( uint8_t* payload, uint8_t payload_length, uint32_t frequency_hz, + int8_t tx_power_dbm, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cr_t cr, smtc_modem_test_mode_sync_word_t sync_word, + bool invert_iq, bool crc_is_on, ral_lora_pkt_len_modes_t header_type, + uint32_t preamble_size, uint32_t nb_of_tx, uint32_t delay_ms ) { if( modem_get_test_mode_status( ) == false ) { SMTC_MODEM_HAL_TRACE_WARNING( "TEST FUNCTION CANNOT BE CALLED: NOT IN TEST MODE\n" ); return SMTC_MODEM_RC_INVALID; } - if( sf >= SMTC_MODEM_TEST_LORA_SF_COUNT ) + if( ( sf < RAL_LORA_SF5 ) || ( sf > RAL_LORA_SF12 ) ) { SMTC_MODEM_HAL_TRACE_ERROR( "Invalid sf %d\n", sf ); return SMTC_MODEM_RC_INVALID; } - if( bw >= SMTC_MODEM_TEST_BW_COUNT ) + if( bw > RAL_LORA_BW_1600_KHZ ) { SMTC_MODEM_HAL_TRACE_ERROR( "Invalid bw %d\n", bw ); return SMTC_MODEM_RC_INVALID; } - if( cr >= SMTC_MODEM_TEST_CR_COUNT ) + if( ( cr < RAL_LORA_CR_4_5 ) || ( cr > RAL_LORA_CR_LI_4_8 ) ) { SMTC_MODEM_HAL_TRACE_ERROR( "Invalid cr %d\n", cr ); return SMTC_MODEM_RC_INVALID; } - - rp_task_t rp_task = { 0 }; - rp_radio_params_t rp_radio_params = { 0 }; - - rp_task.hook_id = modem_test_context.hook_id; - rp_task.state = RP_TASK_STATE_ASAP; - - if( sf == SMTC_MODEM_TEST_FSK ) // FSK + if( payload_length == 0 ) { - ralf_params_gfsk_t gfsk_param; - memset( &gfsk_param, 0, sizeof( ralf_params_gfsk_t ) ); - - gfsk_param.rf_freq_in_hz = frequency_hz; - gfsk_param.output_pwr_in_dbm = tx_power_dbm; - gfsk_param.sync_word = ( uint8_t* ) sync_word_gfsk; - gfsk_param.whitening_seed = GFSK_WHITENING_SEED; - gfsk_param.crc_seed = GFSK_CRC_SEED; - gfsk_param.crc_polynomial = GFSK_CRC_POLYNOMIAL; - - gfsk_param.pkt_params.header_type = RAL_GFSK_PKT_VAR_LEN; - gfsk_param.pkt_params.pld_len_in_bytes = payload_length; - gfsk_param.pkt_params.preamble_len_in_bits = 40; - gfsk_param.pkt_params.preamble_detector = RAL_GFSK_PREAMBLE_DETECTOR_MIN_16BITS; - gfsk_param.pkt_params.sync_word_len_in_bits = 24; - gfsk_param.pkt_params.crc_type = RAL_GFSK_CRC_2_BYTES_INV; - gfsk_param.pkt_params.dc_free = RAL_GFSK_DC_FREE_WHITENING; - - gfsk_param.mod_params.br_in_bps = 50000; - gfsk_param.mod_params.fdev_in_hz = 25000; - gfsk_param.mod_params.bw_dsb_in_hz = 100000; - gfsk_param.mod_params.pulse_shape = RAL_GFSK_PULSE_SHAPE_BT_1; - - rp_radio_params.pkt_type = RAL_PKT_TYPE_GFSK; - rp_radio_params.tx.gfsk = gfsk_param; - - SMTC_MODEM_HAL_TRACE_PRINTF( "GFSK Tx - Freq:%d, Power:%d, length:%u\n", frequency_hz, tx_power_dbm, - payload_length ); - - rp_task.type = RP_TASK_TYPE_TX_FSK; - rp_task.launch_task_callbacks = lr1_stack_mac_tx_gfsk_launch_callback_for_rp; - rp_task.duration_time_ms = ral_get_gfsk_time_on_air_in_ms( &( modem_test_context.rp->radio->ral ), - &( rp_radio_params.tx.gfsk.pkt_params ), - &( rp_radio_params.tx.gfsk.mod_params ) ); + SMTC_MODEM_HAL_TRACE_ERROR( "Invalid payload_length %d\n", payload_length ); + return SMTC_MODEM_RC_INVALID; } - else // LoRa - { - ralf_params_lora_t lora_param; - memset( &lora_param, 0, sizeof( ralf_params_lora_t ) ); - - lora_param.rf_freq_in_hz = frequency_hz; - lora_param.output_pwr_in_dbm = tx_power_dbm; - if( frequency_hz >= 2400000000 ) - { - lora_param.sync_word = 0x12; - } - else - { - lora_param.sync_word = 0x34; - } - - lora_param.pkt_params.preamble_len_in_symb = preamble_size; - lora_param.pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; - lora_param.pkt_params.pld_len_in_bytes = payload_length; - lora_param.pkt_params.crc_is_on = true; - lora_param.pkt_params.invert_iq_is_on = false; + modem_test_context.tx_frequency = frequency_hz; + modem_test_context.sf = sf; + modem_test_context.bw = bw; + modem_test_context.invert_iq = invert_iq; + modem_test_context.nb_of_repetition = nb_of_tx; + modem_test_context.delay_ms = delay_ms; + modem_test_context.modulation_type = LORA; + // config lora parameters + ralf_params_lora_t lora_param; + memset( &lora_param, 0, sizeof( ralf_params_lora_t ) ); + lora_param.rf_freq_in_hz = frequency_hz; + lora_param.output_pwr_in_dbm = tx_power_dbm; + lora_param.sync_word = sync_word; + lora_param.pkt_params.preamble_len_in_symb = preamble_size; + lora_param.pkt_params.header_type = header_type; + lora_param.pkt_params.pld_len_in_bytes = payload_length; + lora_param.pkt_params.crc_is_on = crc_is_on; + lora_param.pkt_params.invert_iq_is_on = invert_iq; + lora_param.mod_params.sf = sf; + lora_param.mod_params.bw = bw; + lora_param.mod_params.cr = cr; + lora_param.mod_params.ldro = ral_compute_lora_ldro( lora_param.mod_params.sf, lora_param.mod_params.bw ); + + // config radio parameters + rp_radio_params.pkt_type = RAL_PKT_TYPE_LORA; + rp_radio_params.tx.lora = lora_param; + + SMTC_MODEM_HAL_TRACE_PRINTF( "LoRa Tx - Freq:%u, Power:%d, sf:%u, bw:%u, length:%u, nb_of_repetition:%u\n", + frequency_hz, tx_power_dbm, rp_radio_params.tx.lora.mod_params.sf, + rp_radio_params.tx.lora.mod_params.bw, payload_length, + modem_test_context.nb_of_repetition ); - lora_param.mod_params.sf = ( ral_lora_sf_t ) modem_test_sf_convert[sf]; - lora_param.mod_params.bw = ( ral_lora_bw_t ) modem_test_bw_convert[bw]; - lora_param.mod_params.cr = ( ral_lora_cr_t ) modem_test_cr_convert[cr]; - lora_param.mod_params.ldro = ral_compute_lora_ldro( lora_param.mod_params.sf, lora_param.mod_params.bw ); + rp_task.type = RP_TASK_TYPE_TX_LORA; + rp_task.launch_task_callbacks = lr1_stack_mac_tx_lora_launch_callback_for_rp; + rp_task.duration_time_ms = + ral_get_lora_time_on_air_in_ms( &( modem_test_context.rp->radio->ral ), &( rp_radio_params.tx.lora.pkt_params ), + &( rp_radio_params.tx.lora.mod_params ) ); - rp_radio_params.pkt_type = RAL_PKT_TYPE_LORA; - rp_radio_params.tx.lora = lora_param; + modem_test_enqueue_task( payload, payload_length ); + return SMTC_MODEM_RC_OK; +} - SMTC_MODEM_HAL_TRACE_PRINTF( "LoRa Tx - Freq:%u, Power:%d, sf:%u, bw:%u, cr:%u, length:%u\n", frequency_hz, - tx_power_dbm, rp_radio_params.tx.lora.mod_params.sf, lora_param.mod_params.bw, - lora_param.mod_params.cr, payload_length ); +smtc_modem_return_code_t smtc_modem_test_tx_fsk( uint8_t* payload, uint8_t payload_length, uint32_t frequency_hz, + int8_t tx_power_dbm, uint32_t nb_of_tx, uint32_t delay_ms ) +{ + if( modem_get_test_mode_status( ) == false ) + { + SMTC_MODEM_HAL_TRACE_WARNING( "TEST FUNCTION CANNOT BE CALLED: NOT IN TEST MODE\n" ); + return SMTC_MODEM_RC_INVALID; + } - rp_task.type = RP_TASK_TYPE_TX_LORA; - rp_task.launch_task_callbacks = lr1_stack_mac_tx_lora_launch_callback_for_rp; - rp_task.duration_time_ms = ral_get_lora_time_on_air_in_ms( &( modem_test_context.rp->radio->ral ), - &( rp_radio_params.tx.lora.pkt_params ), - &( rp_radio_params.tx.lora.mod_params ) ); + if( payload_length == 0 ) + { + SMTC_MODEM_HAL_TRACE_ERROR( "Invalid payload_length %d\n", payload_length ); + return SMTC_MODEM_RC_INVALID; } + modem_test_context.tx_frequency = frequency_hz; + modem_test_context.nb_of_repetition = nb_of_tx; + modem_test_context.delay_ms = delay_ms; + modem_test_context.modulation_type = FSK; + + ralf_params_gfsk_t gfsk_param; + memset( &gfsk_param, 0, sizeof( ralf_params_gfsk_t ) ); + + gfsk_param.rf_freq_in_hz = frequency_hz; + gfsk_param.output_pwr_in_dbm = tx_power_dbm; + gfsk_param.sync_word = ( uint8_t* ) sync_word_gfsk; + gfsk_param.whitening_seed = GFSK_WHITENING_SEED; + gfsk_param.crc_seed = GFSK_CRC_SEED; + gfsk_param.crc_polynomial = GFSK_CRC_POLYNOMIAL; + + gfsk_param.pkt_params.header_type = RAL_GFSK_PKT_VAR_LEN; + gfsk_param.pkt_params.pld_len_in_bytes = payload_length; + gfsk_param.pkt_params.preamble_len_in_bits = 40; + gfsk_param.pkt_params.preamble_detector = RAL_GFSK_PREAMBLE_DETECTOR_MIN_16BITS; + gfsk_param.pkt_params.sync_word_len_in_bits = 24; + gfsk_param.pkt_params.crc_type = RAL_GFSK_CRC_2_BYTES_INV; + gfsk_param.pkt_params.dc_free = RAL_GFSK_DC_FREE_WHITENING; + + gfsk_param.mod_params.br_in_bps = 50000; + gfsk_param.mod_params.fdev_in_hz = 25000; + gfsk_param.mod_params.bw_dsb_in_hz = 100000; + gfsk_param.mod_params.pulse_shape = RAL_GFSK_PULSE_SHAPE_BT_1; + + rp_radio_params.pkt_type = RAL_PKT_TYPE_GFSK; + rp_radio_params.tx.gfsk = gfsk_param; + + SMTC_MODEM_HAL_TRACE_PRINTF( "GFSK Tx - Freq:%d, Power:%d, length:%u\n", frequency_hz, tx_power_dbm, + payload_length ); + + rp_task.type = RP_TASK_TYPE_TX_FSK; + rp_task.launch_task_callbacks = lr1_stack_mac_tx_gfsk_launch_callback_for_rp; + rp_task.duration_time_ms = + ral_get_gfsk_time_on_air_in_ms( &( modem_test_context.rp->radio->ral ), &( rp_radio_params.tx.gfsk.pkt_params ), + &( rp_radio_params.tx.gfsk.mod_params ) ); + + SMTC_MODEM_HAL_TRACE_PRINTF( "nb_of_repetition:%u\n", modem_test_context.nb_of_repetition ); + + modem_test_enqueue_task( payload, payload_length ); + return SMTC_MODEM_RC_OK; +} - if( smtc_modem_test_nop( ) != SMTC_MODEM_RC_OK ) +smtc_modem_return_code_t smtc_modem_test_tx_lrfhss( uint8_t* payload, uint8_t payload_length, uint32_t frequency_hz, + int8_t tx_power_dbm, lr_fhss_v1_cr_t tx_cr, lr_fhss_v1_bw_t tx_bw, + lr_fhss_v1_grid_t tx_grid, bool enable_hopping, uint32_t nb_of_tx, + uint32_t delay_ms ) +{ + if( modem_get_test_mode_status( ) == false ) { - return SMTC_MODEM_RC_FAIL; + SMTC_MODEM_HAL_TRACE_WARNING( "TEST FUNCTION CANNOT BE CALLED: NOT IN TEST MODE\n" ); + return SMTC_MODEM_RC_INVALID; } - if( continuous_tx == false ) // single tx + if( ( tx_cr != LR_FHSS_V1_CR_1_3 ) && ( tx_cr != LR_FHSS_V1_CR_2_3 ) ) { - rp_release_hook( modem_test_context.rp, modem_test_context.hook_id ); - rp_hook_init( modem_test_context.rp, modem_test_context.hook_id, - ( void ( * )( void* ) )( modem_test_empty_callback ), &modem_test_context ); + SMTC_MODEM_HAL_TRACE_ERROR( "Invalid cr %d\n", tx_cr ); + return SMTC_MODEM_RC_INVALID; } - else + if( tx_bw > LR_FHSS_V1_BW_1574219_HZ ) { - rp_release_hook( modem_test_context.rp, modem_test_context.hook_id ); - rp_hook_init( modem_test_context.rp, modem_test_context.hook_id, - ( void ( * )( void* ) )( modem_test_tx_callback ), &modem_test_context ); + SMTC_MODEM_HAL_TRACE_ERROR( "Invalid bw %d\n", tx_bw ); + return SMTC_MODEM_RC_INVALID; } - - if( payload == NULL ) + if( tx_grid > LR_FHSS_V1_GRID_3906_HZ ) { - // user payload is NULL=> generate a random before at next step - modem_test_context.random_payload = true; - for( uint8_t i = 0; i < payload_length; i++ ) - { - modem_test_context.tx_rx_payload[i] = smtc_modem_hal_get_random_nb_in_range( 0, 0xFF ); - } + SMTC_MODEM_HAL_TRACE_ERROR( "Invalid grid %d\n", tx_grid ); + return SMTC_MODEM_RC_INVALID; } - else + if( payload_length == 0 ) { - modem_test_context.random_payload = false; - // save tx payload in context - memcpy( modem_test_context.tx_rx_payload, payload, payload_length ); + SMTC_MODEM_HAL_TRACE_ERROR( "Invalid payload_length %d\n", payload_length ); + return SMTC_MODEM_RC_INVALID; } - rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + 20; + modem_test_context.tx_frequency = frequency_hz; + modem_test_context.nb_of_repetition = nb_of_tx; + modem_test_context.delay_ms = delay_ms; + modem_test_context.modulation_type = LR_FHSS; + ralf_params_lr_fhss_t lr_fhss_param; + memset( &lr_fhss_param, 0, sizeof( ralf_params_lr_fhss_t ) ); - // Enqueue task in radio planner - rp_task_enqueue( modem_test_context.rp, &rp_task, modem_test_context.tx_rx_payload, payload_length, - &rp_radio_params ); + lr_fhss_param.output_pwr_in_dbm = tx_power_dbm; + + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.modulation_type = LR_FHSS_V1_MODULATION_TYPE_GMSK_488; + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.cr = tx_cr; + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.grid = tx_grid; + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.enable_hopping = enable_hopping; + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.bw = tx_bw; + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.header_count = smtc_real_lr_fhss_get_header_count( tx_cr ); + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.sync_word = ( uint8_t* ) sync_word_lr_fhss; + + lr_fhss_param.ral_lr_fhss_params.center_frequency_in_hz = frequency_hz; + lr_fhss_param.ral_lr_fhss_params.device_offset = 0; + + unsigned int nb_max_hop_sequence = 0; + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_lr_fhss_get_hop_sequence_count( &( modem_test_context.rp->radio->ral ), + &( lr_fhss_param.ral_lr_fhss_params ), + &nb_max_hop_sequence ) == RAL_STATUS_OK ); + lr_fhss_param.hop_sequence_id = smtc_modem_hal_get_random_nb_in_range( 0, ( uint32_t ) nb_max_hop_sequence - 1 ); + rp_radio_params.tx.lr_fhss = lr_fhss_param; + + SMTC_MODEM_HAL_TRACE_PRINTF( "LR_FHSS Tx - Freq:%u, Power:%d, grid:%u, bw:%u, cr:%u, length:%u\n", frequency_hz, + tx_power_dbm, lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.grid, + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.bw, + lr_fhss_param.ral_lr_fhss_params.lr_fhss_params.cr, payload_length ); + + ral_lr_fhss_get_time_on_air_in_ms( &( modem_test_context.rp->radio->ral ), &( lr_fhss_param.ral_lr_fhss_params ), + payload_length, &rp_task.duration_time_ms ); + + SMTC_MODEM_HAL_TRACE_PRINTF( " Hop ID = %d\n", lr_fhss_param.hop_sequence_id ); + + rp_task.type = RP_TASK_TYPE_TX_LR_FHSS; + rp_task.launch_task_callbacks = lr1_stack_mac_tx_lr_fhss_launch_callback_for_rp; + + SMTC_MODEM_HAL_TRACE_PRINTF( "nb_of_repetition:%u\n", modem_test_context.nb_of_repetition ); + + modem_test_enqueue_task( payload, payload_length ); return SMTC_MODEM_RC_OK; } @@ -442,6 +449,7 @@ smtc_modem_return_code_t smtc_modem_test_tx_cw( uint32_t frequency_hz, int8_t tx } ralf_params_lora_t lora_param; + modem_test_context.tx_frequency = frequency_hz; memset( &lora_param, 0, sizeof( ralf_params_lora_t ) ); lora_param.rf_freq_in_hz = frequency_hz; @@ -461,49 +469,50 @@ smtc_modem_return_code_t smtc_modem_test_tx_cw( uint32_t frequency_hz, int8_t tx lora_param.sync_word = 0x34; } - rp_radio_params_t radio_params = { 0 }; - radio_params.pkt_type = RAL_PKT_TYPE_LORA; - radio_params.tx.lora = lora_param; + rp_radio_params.pkt_type = RAL_PKT_TYPE_LORA; + rp_radio_params.tx.lora = lora_param; - rp_task_t rp_task = { 0 }; rp_task.hook_id = modem_test_context.hook_id; rp_task.state = RP_TASK_STATE_ASAP; rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + 2; - rp_task.duration_time_ms = 2000; // toa; + rp_task.duration_time_ms = 2000; rp_task.type = RP_TASK_TYPE_TX_LORA; rp_task.launch_task_callbacks = test_mode_cw_callback_for_rp; // First disable failsafe check for radio planner as the task can be longer than failsafe value rp_disable_failsafe( modem_test_context.rp, true ); - if( rp_task_enqueue( modem_test_context.rp, &rp_task, NULL, 0, &radio_params ) != RP_HOOK_STATUS_OK ) + if( tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_TEST_MODE, 0, false, modem_test_context.tx_rx_payload, 0, 0, + rp_task.start_time_ms, TEST_STACK_ID_0 ) == ERRORLORAWAN ) { - SMTC_MODEM_HAL_TRACE_PRINTF( "Radio planner hook %d is busy \n", rp_task.hook_id ); + modem_test_empty_callback( NULL ); } SMTC_MODEM_HAL_TRACE_PRINTF( "Tx CW - Freq:%u, Power:%d\n", frequency_hz, lora_param.output_pwr_in_dbm ); return SMTC_MODEM_RC_OK; } -smtc_modem_return_code_t smtc_modem_test_rx_continuous( uint32_t frequency_hz, smtc_modem_test_sf_t sf, - smtc_modem_test_bw_t bw, smtc_modem_test_cr_t cr ) +smtc_modem_return_code_t smtc_modem_test_rx_lora( uint32_t frequency_hz, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cr_t cr, smtc_modem_test_mode_sync_word_t sync_word, + bool invert_iq, bool crc_is_on, ral_lora_pkt_len_modes_t header_type, + uint32_t preamble_size, uint8_t symb_nb_timeout ) { if( modem_get_test_mode_status( ) == false ) { SMTC_MODEM_HAL_TRACE_WARNING( "TEST FUNCTION CANNOT BE CALLED: NOT IN TEST MODE\n" ); return SMTC_MODEM_RC_INVALID; } - if( sf >= SMTC_MODEM_TEST_LORA_SF_COUNT ) + if( ( sf < RAL_LORA_SF5 ) || ( sf > RAL_LORA_SF12 ) ) { SMTC_MODEM_HAL_TRACE_ERROR( "Invalid sf %d\n", sf ); return SMTC_MODEM_RC_INVALID; } - if( bw >= SMTC_MODEM_TEST_BW_COUNT ) + if( bw > RAL_LORA_BW_1600_KHZ ) { SMTC_MODEM_HAL_TRACE_ERROR( "Invalid bw %d\n", bw ); return SMTC_MODEM_RC_INVALID; } - if( cr >= SMTC_MODEM_TEST_CR_COUNT ) + if( ( cr < RAL_LORA_CR_4_5 ) || ( cr > RAL_LORA_CR_LI_4_8 ) ) { SMTC_MODEM_HAL_TRACE_ERROR( "Invalid cr %d\n", cr ); return SMTC_MODEM_RC_INVALID; @@ -512,110 +521,106 @@ smtc_modem_return_code_t smtc_modem_test_rx_continuous( uint32_t frequency_hz, s // reset number of received packets modem_test_context.total_rx_packets = 0; + // config lora parameters + ralf_params_lora_t lora_param; + memset( &lora_param, 0, sizeof( ralf_params_lora_t ) ); + lora_param.rf_freq_in_hz = frequency_hz; + lora_param.sync_word = sync_word; + lora_param.pkt_params.preamble_len_in_symb = preamble_size; + lora_param.pkt_params.header_type = header_type; + lora_param.pkt_params.crc_is_on = crc_is_on; + lora_param.pkt_params.invert_iq_is_on = invert_iq; + lora_param.mod_params.sf = sf; + lora_param.mod_params.bw = bw; + lora_param.mod_params.cr = cr; + lora_param.mod_params.ldro = ral_compute_lora_ldro( lora_param.mod_params.sf, lora_param.mod_params.bw ); + lora_param.symb_nb_timeout = symb_nb_timeout; + lora_param.pkt_params.pld_len_in_bytes = 255; + // config radio parameters rp_radio_params_t rp_radio_params = { 0 }; rp_radio_params.rx.timeout_in_ms = RAL_RX_TIMEOUT_CONTINUOUS_MODE; + rp_radio_params.pkt_type = RAL_PKT_TYPE_LORA; + rp_radio_params.rx.lora = lora_param; - rp_task_t rp_task = { 0 }; - rp_task.hook_id = modem_test_context.hook_id; - rp_task.state = RP_TASK_STATE_ASAP; + // config radio planner task parameters + rp_task.hook_id = modem_test_context.hook_id; + rp_task.state = RP_TASK_STATE_ASAP; + rp_task.type = RP_TASK_TYPE_RX_LORA; + rp_task.launch_task_callbacks = lr1_stack_mac_rx_lora_launch_callback_for_rp; + rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + 20; + rp_task.duration_time_ms = 20; // will be extended by the radio planner + rp_disable_failsafe( modem_test_context.rp, true ); + rp_release_hook( modem_test_context.rp, modem_test_context.hook_id ); + rp_hook_init( modem_test_context.rp, modem_test_context.hook_id, ( void ( * )( void* ) )( modem_test_rx_callback ), + &modem_test_context ); - if( sf == 0 ) // FSK + if( rp_task_enqueue( modem_test_context.rp, &rp_task, modem_test_context.tx_rx_payload, 255, &rp_radio_params ) != + RP_HOOK_STATUS_OK ) { - // Radio config for FSK - ralf_params_gfsk_t gfsk_param; - memset( &gfsk_param, 0, sizeof( ralf_params_gfsk_t ) ); - - gfsk_param.rf_freq_in_hz = frequency_hz; - gfsk_param.sync_word = ( uint8_t* ) sync_word_gfsk; - gfsk_param.whitening_seed = GFSK_WHITENING_SEED; - gfsk_param.crc_seed = GFSK_CRC_SEED; - gfsk_param.crc_polynomial = GFSK_CRC_POLYNOMIAL; - - gfsk_param.pkt_params.header_type = RAL_GFSK_PKT_VAR_LEN; - gfsk_param.pkt_params.pld_len_in_bytes = 255; - gfsk_param.pkt_params.preamble_len_in_bits = 40; - gfsk_param.pkt_params.preamble_detector = RAL_GFSK_PREAMBLE_DETECTOR_MIN_16BITS; - gfsk_param.pkt_params.sync_word_len_in_bits = 24; - gfsk_param.pkt_params.crc_type = RAL_GFSK_CRC_2_BYTES_INV; - gfsk_param.pkt_params.dc_free = RAL_GFSK_DC_FREE_WHITENING; - - gfsk_param.mod_params.br_in_bps = 50000; - gfsk_param.mod_params.fdev_in_hz = 25000; - gfsk_param.mod_params.bw_dsb_in_hz = 100000; - gfsk_param.mod_params.pulse_shape = RAL_GFSK_PULSE_SHAPE_BT_1; - - rp_radio_params.pkt_type = RAL_PKT_TYPE_GFSK; - rp_radio_params.rx.gfsk = gfsk_param; - - SMTC_MODEM_HAL_TRACE_PRINTF( "GFSK Rx - Freq:%d\n", frequency_hz ); - - // Radio planner task config - rp_task.type = RP_TASK_TYPE_RX_FSK; - rp_task.launch_task_callbacks = lr1_stack_mac_rx_gfsk_launch_callback_for_rp; + return SMTC_MODEM_RC_FAIL; } - else // LoRa + return SMTC_MODEM_RC_OK; +} + +smtc_modem_return_code_t smtc_modem_test_rx_fsk_continuous( uint32_t frequency_hz ) +{ + if( modem_get_test_mode_status( ) == false ) { - // Radio config for LoRa - ralf_params_lora_t lora_param; - memset( &lora_param, 0, sizeof( ralf_params_lora_t ) ); + SMTC_MODEM_HAL_TRACE_WARNING( "TEST FUNCTION CANNOT BE CALLED: NOT IN TEST MODE\n" ); + return SMTC_MODEM_RC_INVALID; + } - lora_param.rf_freq_in_hz = frequency_hz; - if( frequency_hz >= 2400000000 ) - { - lora_param.sync_word = 0x12; - if( ( sf == 5 ) || ( sf == 6 ) ) - { - lora_param.pkt_params.preamble_len_in_symb = 12; - } - else - { - lora_param.pkt_params.preamble_len_in_symb = 8; - } - } - else - { - lora_param.sync_word = 0x34; - lora_param.pkt_params.preamble_len_in_symb = 8; - } - lora_param.symb_nb_timeout = 0; + // reset number of received packets + modem_test_context.total_rx_packets = 0; - // lora_param.pkt_params.preamble_len_in_symb = - // smtc_real_get_preamble_len( modem_test_context.lr1_mac_obj->real, modem_test_sf_convert[sf] ); - lora_param.pkt_params.header_type = RAL_LORA_PKT_EXPLICIT; - lora_param.pkt_params.pld_len_in_bytes = 255; - lora_param.pkt_params.crc_is_on = false; - lora_param.pkt_params.invert_iq_is_on = true; + rp_radio_params_t rp_radio_params = { 0 }; + rp_radio_params.rx.timeout_in_ms = RAL_RX_TIMEOUT_CONTINUOUS_MODE; - lora_param.mod_params.sf = ( ral_lora_sf_t ) modem_test_sf_convert[sf]; - lora_param.mod_params.bw = ( ral_lora_bw_t ) modem_test_bw_convert[bw]; - lora_param.mod_params.cr = ( ral_lora_cr_t ) modem_test_cr_convert[cr]; - lora_param.mod_params.ldro = ral_compute_lora_ldro( lora_param.mod_params.sf, lora_param.mod_params.bw ); + // Radio config for FSK + ralf_params_gfsk_t gfsk_param; + memset( &gfsk_param, 0, sizeof( ralf_params_gfsk_t ) ); - rp_radio_params.pkt_type = RAL_PKT_TYPE_LORA; - rp_radio_params.rx.lora = lora_param; + gfsk_param.rf_freq_in_hz = frequency_hz; + gfsk_param.sync_word = ( uint8_t* ) sync_word_gfsk; + gfsk_param.whitening_seed = GFSK_WHITENING_SEED; + gfsk_param.crc_seed = GFSK_CRC_SEED; + gfsk_param.crc_polynomial = GFSK_CRC_POLYNOMIAL; - SMTC_MODEM_HAL_TRACE_PRINTF( "LoRa Rx - Freq:%u, sf:%u, bw:%u, cr:%u\n", frequency_hz, - rp_radio_params.rx.lora.mod_params.sf, bw, cr ); + gfsk_param.pkt_params.header_type = RAL_GFSK_PKT_VAR_LEN; + gfsk_param.pkt_params.pld_len_in_bytes = 255; + gfsk_param.pkt_params.preamble_len_in_bits = 40; + gfsk_param.pkt_params.preamble_detector = RAL_GFSK_PREAMBLE_DETECTOR_MIN_16BITS; + gfsk_param.pkt_params.sync_word_len_in_bits = 24; + gfsk_param.pkt_params.crc_type = RAL_GFSK_CRC_2_BYTES_INV; + gfsk_param.pkt_params.dc_free = RAL_GFSK_DC_FREE_WHITENING; - // Radio planner task config - rp_task.type = RP_TASK_TYPE_RX_LORA; - rp_task.launch_task_callbacks = lr1_stack_mac_rx_lora_launch_callback_for_rp; - } + gfsk_param.mod_params.br_in_bps = 50000; + gfsk_param.mod_params.fdev_in_hz = 25000; + gfsk_param.mod_params.bw_dsb_in_hz = 100000; + gfsk_param.mod_params.pulse_shape = RAL_GFSK_PULSE_SHAPE_BT_1; - if( smtc_modem_test_nop( ) != SMTC_MODEM_RC_OK ) - { - return SMTC_MODEM_RC_FAIL; - } + rp_radio_params.pkt_type = RAL_PKT_TYPE_GFSK; + rp_radio_params.rx.gfsk = gfsk_param; + + SMTC_MODEM_HAL_TRACE_PRINTF( "GFSK Rx - Freq:%d\n", frequency_hz ); + // Radio planner task config + rp_task.hook_id = modem_test_context.hook_id; + rp_task.state = RP_TASK_STATE_ASAP; + rp_task.type = RP_TASK_TYPE_RX_FSK; + rp_task.launch_task_callbacks = lr1_stack_mac_rx_gfsk_launch_callback_for_rp; + rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + 20; + rp_task.duration_time_ms = 20; // toa; rp_release_hook( modem_test_context.rp, modem_test_context.hook_id ); + rp_disable_failsafe( modem_test_context.rp, true ); rp_hook_init( modem_test_context.rp, modem_test_context.hook_id, ( void ( * )( void* ) )( modem_test_rx_callback ), &modem_test_context ); - rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + 20; - rp_task.duration_time_ms = 2000; // toa; - - rp_task_enqueue( modem_test_context.rp, &rp_task, modem_test_context.tx_rx_payload, 255, &rp_radio_params ); - + if( rp_task_enqueue( modem_test_context.rp, &rp_task, modem_test_context.tx_rx_payload, 255, &rp_radio_params ) != + RP_HOOK_STATUS_OK ) + { + return SMTC_MODEM_RC_FAIL; + } return SMTC_MODEM_RC_OK; } @@ -629,28 +634,32 @@ smtc_modem_return_code_t smtc_modem_test_get_nb_rx_packets( uint32_t* nb_rx_pack *nb_rx_packets = modem_test_context.total_rx_packets; return SMTC_MODEM_RC_OK; } - -smtc_modem_return_code_t smtc_modem_test_rssi( uint32_t frequency_hz, smtc_modem_test_bw_t bw, uint16_t time_ms ) +smtc_modem_return_code_t smtc_modem_test_get_last_rx_packets( int16_t* rssi, int16_t* snr, uint8_t* rx_payload, + uint8_t* rx_payload_length ) { if( modem_get_test_mode_status( ) == false ) { SMTC_MODEM_HAL_TRACE_WARNING( "TEST FUNCTION CANNOT BE CALLED: NOT IN TEST MODE\n" ); return SMTC_MODEM_RC_INVALID; } - if( bw >= SMTC_MODEM_TEST_BW_COUNT ) - { - SMTC_MODEM_HAL_TRACE_ERROR( "Invalid bw %d\n", bw ); - return SMTC_MODEM_RC_INVALID; - } + *rssi = modem_test_context.last_rx_payload_rssi; + *snr = modem_test_context.last_rx_payload_snr; + *rx_payload_length = modem_test_context.last_rx_payload_length; + memcpy( rx_payload, modem_test_context.tx_rx_payload, modem_test_context.last_rx_payload_length ); + return SMTC_MODEM_RC_OK; +} - uint32_t bw_tmp = 0; - if( modem_test_bw_helper[bw] > 467000 ) +smtc_modem_return_code_t smtc_modem_test_rssi_lbt( uint32_t frequency_hz, uint32_t bw_hz, uint16_t time_ms ) +{ + if( modem_get_test_mode_status( ) == false ) { - bw_tmp = 467000; // Maximum supported GFSK BW + SMTC_MODEM_HAL_TRACE_WARNING( "TEST FUNCTION CANNOT BE CALLED: NOT IN TEST MODE\n" ); + return SMTC_MODEM_RC_INVALID; } - else + if( ( bw_hz < 125000 ) || ( bw_hz > 467000 ) ) // 467000 Maximum supported GFSK BW { - bw_tmp = modem_test_bw_helper[bw]; + SMTC_MODEM_HAL_TRACE_ERROR( "Invalid bw %d\n", bw_hz ); + return SMTC_MODEM_RC_INVALID; } modem_test_context.rssi_ready = false; @@ -659,7 +668,7 @@ smtc_modem_return_code_t smtc_modem_test_rssi( uint32_t frequency_hz, smtc_modem ( void ( * )( void* ) ) modem_test_compute_rssi_callback, &modem_test_context, ( void ( * )( void* ) ) modem_test_compute_rssi_callback, &modem_test_context, ( void ( * )( void* ) ) modem_test_compute_rssi_callback, &modem_test_context ); - smtc_lbt_set_parameters( &modem_test_context.lbt_obj, time_ms, 50, bw_tmp ); + smtc_lbt_set_parameters( &modem_test_context.lbt_obj, time_ms, 50, bw_hz ); smtc_lbt_set_state( &modem_test_context.lbt_obj, true ); smtc_lbt_listen_channel( &modem_test_context.lbt_obj, frequency_hz, 0, smtc_modem_hal_get_time_in_ms( ), 0 ); @@ -776,7 +785,26 @@ smtc_modem_return_code_t smtc_modem_test_direct_radio_read( uint8_t* command, ui } return SMTC_MODEM_RC_OK; } +status_lorawan_t test_mode_cb_tpm( uint8_t* payload, uint8_t payload_length, bool abort ) +{ + if( abort == true ) + { + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_TEST_MODE, SMTC_MODEM_EVENT_TEST_MODE_ENDED, 0xFF ); + return ERRORLORAWAN; + } + // Enqueue task in radio planner + if( rp_task_enqueue( modem_test_context.rp, &rp_task, modem_test_context.tx_rx_payload, payload_length, + &rp_radio_params ) != RP_HOOK_STATUS_OK ) + { + return ERRORLORAWAN; + } + return OKLORAWAN; +} +modem_test_context_t* smtc_modem_test_get_context( void ) +{ + return ( &modem_test_context ); +} /* * ----------------------------------------------------------------------------- * --- PRIVATE FUNCTIONS DEFINITION -------------------------------------------- @@ -784,6 +812,7 @@ smtc_modem_return_code_t smtc_modem_test_direct_radio_read( uint8_t* command, ui void modem_test_empty_callback( modem_test_context_t* context ) { + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_TEST_MODE, SMTC_MODEM_EVENT_TEST_MODE_ENDED, 0xFF ); SMTC_MODEM_HAL_TRACE_PRINTF( "TEST mode Empty callback\n" ); } @@ -800,106 +829,147 @@ void modem_test_compute_rssi_callback( modem_test_context_t* context ) void modem_test_tx_callback( modem_test_context_t* context ) { + // SMTC_MODEM_HAL_TRACE_PRINTF( " modem_test_tx_callback %u\n", context->nb_of_repetition ); smtc_modem_hal_reload_wdog( ); - rp_status_t rp_status = context->rp->status[context->hook_id]; - if( rp_status == RP_STATUS_TASK_ABORTED ) + context->nb_of_repetition--; + if( context->nb_of_repetition == 0 ) { - SMTC_MODEM_HAL_TRACE_PRINTF( " modem_test_tx_callback ABORTED\n" ); + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_TEST_MODE, SMTC_MODEM_EVENT_TEST_MODE_TX_COMPLETED, 0xFF ); + SMTC_MODEM_HAL_TRACE_PRINTF( " modem_test_tx_callback finished\n" ); return; } - rp_task_t rp_task = { 0 }; + else + { + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_TEST_MODE, SMTC_MODEM_EVENT_TEST_MODE_TX_DONE, 0xFF ); + } - rp_task.hook_id = context->hook_id; - rp_task.state = RP_TASK_STATE_ASAP; - rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + 20; + rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + context->delay_ms; - rp_radio_params_t radio_params = context->rp->radio_params[context->hook_id]; + rp_radio_params = context->rp->radio_params[context->hook_id]; - if( radio_params.pkt_type == RAL_PKT_TYPE_LORA ) + if( rp_task.type == RP_TASK_TYPE_TX_LORA ) { - rp_task.type = RP_TASK_TYPE_TX_LORA; rp_task.launch_task_callbacks = lr1_stack_mac_tx_lora_launch_callback_for_rp; if( context->random_payload == true ) { - for( uint8_t i = 0; i < radio_params.tx.lora.pkt_params.pld_len_in_bytes; i++ ) + for( uint8_t i = 0; i < rp_radio_params.tx.lora.pkt_params.pld_len_in_bytes; i++ ) { context->tx_rx_payload[i] = smtc_modem_hal_get_random_nb_in_range( 0, 0xFF ); } } - rp_task.duration_time_ms = ral_get_lora_time_on_air_in_ms( - &( context->rp->radio->ral ), &( radio_params.tx.lora.pkt_params ), &( radio_params.tx.lora.mod_params ) ); + rp_task.duration_time_ms = + ral_get_lora_time_on_air_in_ms( &( context->rp->radio->ral ), &( rp_radio_params.tx.lora.pkt_params ), + &( rp_radio_params.tx.lora.mod_params ) ); - rp_task_enqueue( context->rp, &rp_task, context->tx_rx_payload, - radio_params.tx.lora.pkt_params.pld_len_in_bytes, &radio_params ); + if( tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_TEST_MODE, 0, false, context->tx_rx_payload, + rp_radio_params.tx.lora.pkt_params.pld_len_in_bytes, 0, rp_task.start_time_ms, + TEST_STACK_ID_0 ) == ERRORLORAWAN ) + { + modem_test_empty_callback( NULL ); + } } - else + else if( rp_task.type == RP_TASK_TYPE_TX_FSK ) { - rp_task.type = RP_TASK_TYPE_TX_FSK; rp_task.launch_task_callbacks = lr1_stack_mac_tx_gfsk_launch_callback_for_rp; if( context->random_payload == true ) { - for( uint8_t i = 0; i < radio_params.tx.gfsk.pkt_params.pld_len_in_bytes; i++ ) + for( uint8_t i = 0; i < rp_radio_params.tx.gfsk.pkt_params.pld_len_in_bytes; i++ ) { context->tx_rx_payload[i] = smtc_modem_hal_get_random_nb_in_range( 0, 0xFF ); } } - rp_task.duration_time_ms = ral_get_gfsk_time_on_air_in_ms( - &( context->rp->radio->ral ), &( radio_params.tx.gfsk.pkt_params ), &( radio_params.tx.gfsk.mod_params ) ); + rp_task.duration_time_ms = + ral_get_gfsk_time_on_air_in_ms( &( context->rp->radio->ral ), &( rp_radio_params.tx.gfsk.pkt_params ), + &( rp_radio_params.tx.gfsk.mod_params ) ); + if( tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_TEST_MODE, 0, false, context->tx_rx_payload, + rp_radio_params.tx.gfsk.pkt_params.pld_len_in_bytes, 0, rp_task.start_time_ms, + TEST_STACK_ID_0 ) == ERRORLORAWAN ) + { + modem_test_empty_callback( NULL ); + } + } + else if( rp_task.type == RP_TASK_TYPE_TX_LR_FHSS ) + { + uint8_t payload_length = context->rp->payload_buffer_size[context->hook_id]; + rp_task.launch_task_callbacks = lr1_stack_mac_tx_lr_fhss_launch_callback_for_rp; + + ralf_params_lr_fhss_t* lr_fhss_param = &rp_radio_params.tx.lr_fhss; - rp_task_enqueue( context->rp, &rp_task, context->tx_rx_payload, - radio_params.tx.gfsk.pkt_params.pld_len_in_bytes, &radio_params ); + // Hopping sequence must be different for each uplink + unsigned int nb_max_hop_sequence = 0; + SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_lr_fhss_get_hop_sequence_count( &( context->rp->radio->ral ), + &( lr_fhss_param->ral_lr_fhss_params ), + &nb_max_hop_sequence ) == RAL_STATUS_OK ); + lr_fhss_param->hop_sequence_id = + smtc_modem_hal_get_random_nb_in_range( 0, ( uint32_t ) nb_max_hop_sequence - 1 ); + + if( context->random_payload == true ) + { + for( uint8_t i = 0; i < payload_length; i++ ) + { + context->tx_rx_payload[i] = smtc_modem_hal_get_random_nb_in_range( 0, 0xFF ); + } + } + rp_task.duration_time_ms = ral_lr_fhss_get_time_on_air_in_ms( + &( context->rp->radio->ral ), &( rp_radio_params.tx.lr_fhss.ral_lr_fhss_params ), payload_length, + &rp_task.duration_time_ms ); + + if( tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_TEST_MODE, 0, false, context->tx_rx_payload, + payload_length, 0, rp_task.start_time_ms, TEST_STACK_ID_0 ) == ERRORLORAWAN ) + { + modem_test_empty_callback( NULL ); + } } } void modem_test_rx_callback( modem_test_context_t* context ) { smtc_modem_hal_reload_wdog( ); - rp_status_t rp_status = context->rp->status[context->hook_id]; - - if( rp_status == RP_STATUS_RX_PACKET ) - { - context->total_rx_packets++; -#if( MODEM_HAL_DBG_TRACE == MODEM_HAL_FEATURE_ON ) - int16_t snr = context->rp->radio_params[context->hook_id].rx.lora_pkt_status.snr_pkt_in_db; - int16_t rssi = context->rp->radio_params[context->hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm; - uint32_t irq_timestamp_ms = context->rp->irq_timestamp_ms[context->hook_id]; - SMTC_MODEM_HAL_TRACE_PRINTF( "t: %d, rp_status %u, snr: %d, rssi: %d\n", irq_timestamp_ms, rp_status, snr, - rssi ); - SMTC_MODEM_HAL_TRACE_ARRAY( "rx_payload", context->tx_rx_payload, - context->rp->rx_payload_size[context->hook_id] ); -#endif - } - else if( rp_status == RP_STATUS_TASK_ABORTED ) - { - SMTC_MODEM_HAL_TRACE_PRINTF( " modem_test_rx_callback ABORTED\n" ); - return; - } - - rp_task_t rp_task = { 0 }; - - rp_task.hook_id = context->hook_id; - rp_task.state = RP_TASK_STATE_ASAP; + rp_status_t rp_status = context->rp->status[context->hook_id]; rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + 20; - rp_task.duration_time_ms = 2000; // toa; + rp_task.duration_time_ms = 20; // will be extended by the radio planner rp_radio_params_t radio_params = context->rp->radio_params[context->hook_id]; - if( radio_params.pkt_type == RAL_PKT_TYPE_LORA ) + if( rp_status == RP_STATUS_RX_PACKET ) { - rp_task.type = RP_TASK_TYPE_RX_LORA; - rp_task.launch_task_callbacks = lr1_stack_mac_rx_lora_launch_callback_for_rp; - rp_task_enqueue( context->rp, &rp_task, context->tx_rx_payload, - radio_params.rx.lora.pkt_params.pld_len_in_bytes, &radio_params ); + uint16_t payload_length; + if( radio_params.pkt_type == RAL_PKT_TYPE_LORA ) + { + rp_task.type = RP_TASK_TYPE_RX_LORA; + rp_task.launch_task_callbacks = lr1_stack_mac_rx_lora_launch_callback_for_rp; + payload_length = radio_params.rx.lora.pkt_params.pld_len_in_bytes; + context->last_rx_payload_snr = context->rp->radio_params[context->hook_id].rx.lora_pkt_status.snr_pkt_in_db; + context->last_rx_payload_rssi = + context->rp->radio_params[context->hook_id].rx.lora_pkt_status.rssi_pkt_in_dbm; + } + else + { + rp_task.type = RP_TASK_TYPE_RX_FSK; + rp_task.launch_task_callbacks = lr1_stack_mac_rx_gfsk_launch_callback_for_rp; + payload_length = radio_params.rx.gfsk.pkt_params.pld_len_in_bytes; + context->last_rx_payload_snr = 0; // not available for GFSK + context->last_rx_payload_rssi = + context->rp->radio_params[context->hook_id].rx.gfsk_pkt_status.rssi_avg_in_dbm; + } + + if( rp_task_enqueue( context->rp, &rp_task, context->tx_rx_payload, payload_length, &radio_params ) != + RP_HOOK_STATUS_OK ) + { + SMTC_MODEM_HAL_PANIC( ); + } + + context->total_rx_packets++; + context->last_rx_payload_length = context->rp->rx_payload_size[context->hook_id]; + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_TEST_MODE, SMTC_MODEM_EVENT_TEST_MODE_RX_DONE, 0xFF ); } else - { - rp_task.type = RP_TASK_TYPE_RX_FSK; - rp_task.launch_task_callbacks = lr1_stack_mac_rx_gfsk_launch_callback_for_rp; - rp_task_enqueue( context->rp, &rp_task, context->tx_rx_payload, - radio_params.rx.gfsk.pkt_params.pld_len_in_bytes, &radio_params ); + { // RP_STATUS_RX_TIMEOUT or RP_STATUS_RX_ABORTED + + increment_asynchronous_msgnumber( SMTC_MODEM_EVENT_TEST_MODE, SMTC_MODEM_EVENT_TEST_MODE_RX_ABORTED, 0xFF ); } } @@ -913,4 +983,36 @@ void test_mode_cw_callback_for_rp( void* rp_void ) SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_tx_cw( &( rp->radio->ral ) ) == RAL_STATUS_OK ); } +static void modem_test_enqueue_task( uint8_t* payload, uint8_t payload_length ) +{ + rp_task.hook_id = modem_test_context.hook_id; + rp_task.state = RP_TASK_STATE_ASAP; + rp_release_hook( modem_test_context.rp, modem_test_context.hook_id ); + rp_hook_init( modem_test_context.rp, modem_test_context.hook_id, ( void ( * )( void* ) )( modem_test_tx_callback ), + &modem_test_context ); + + if( payload == NULL ) + { + // user payload is NULL=> generate a random before at next step + modem_test_context.random_payload = true; + for( uint8_t i = 0; i < payload_length; i++ ) + { + modem_test_context.tx_rx_payload[i] = smtc_modem_hal_get_random_nb_in_range( 0, 0xFF ); + } + } + else + { + modem_test_context.random_payload = false; + // save tx payload in context + memcpy( modem_test_context.tx_rx_payload, payload, payload_length ); + } + rp_task.start_time_ms = smtc_modem_hal_get_time_in_ms( ) + modem_test_context.delay_ms; + + if( tx_protocol_manager_request( TX_PROTOCOL_TRANSMIT_TEST_MODE, 0, false, modem_test_context.tx_rx_payload, + payload_length, 0, rp_task.start_time_ms, TEST_STACK_ID_0 ) == ERRORLORAWAN ) + { + modem_test_empty_callback( NULL ); + } +} + /* --- EOF ------------------------------------------------------------------ */ diff --git a/lbm_lib/smtc_modem_core/smtc_modem_test.h b/lbm_lib/smtc_modem_core/smtc_modem_test.h new file mode 100644 index 0000000..571eb9e --- /dev/null +++ b/lbm_lib/smtc_modem_core/smtc_modem_test.h @@ -0,0 +1,77 @@ +/*! + * \file modem_test.h + * + * \brief soft modem task scheduler + * + * The Clear BSD License + * Copyright Semtech Corporation 2021. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Semtech corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SMTC_MODEM_TEST__H +#define __SMTC_MODEM_TEST__H + +#ifdef __cplusplus +extern "C" { +#endif +#include "radio_planner.h" +#include "lr1_stack_mac_layer.h" +#include "smtc_lbt.h" +/*! + * \typedef modem_test_context_t + * \brief Test context + */ +typedef struct modem_test_context +{ + radio_planner_t* rp; //!< Radio planner instance + lr1_stack_mac_t* lr1_mac_obj; //!< Lorawan lr1mac instance + uint8_t hook_id; //!< Lorawan lr1mac hook id used for test + uint8_t tx_rx_payload[255]; //!< Transmit/Received buffer + int16_t last_rx_payload_rssi; //!< Placeholder for last rssi + int16_t last_rx_payload_snr; //!< Placeholder for last snr + uint8_t last_rx_payload_length; //!< Placeholder for last payload length + int16_t rssi; //!< Placeholder for mean rssi + bool rssi_ready; //!< True when rssi mean test is finished + uint32_t total_rx_packets; //!< Number of received packet + bool random_payload; //!< True in case of random payload + uint32_t tx_frequency; //!< True in case of random payload + ral_lora_sf_t sf; //!< True in case of random payload + ral_lora_bw_t bw; //!< True in case of random payload + bool invert_iq; //!< True in case of random payload + uint32_t nb_of_repetition; //!< Used for multiple tx in test mode + modulation_type_t modulation_type; //!< modulation type + uint32_t delay_ms; //!< delay between two repetition tx in test mode + smtc_lbt_t lbt_obj; +} modem_test_context_t; + +modem_test_context_t* smtc_modem_test_get_context( void ); +status_lorawan_t test_mode_cb_tpm( uint8_t* payload, uint8_t payload_length, bool abort ); +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral.h index 27dedbb..a0bb13d 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral.h @@ -473,6 +473,23 @@ static inline ral_status_t ral_set_gfsk_pkt_params( const ral_t* radio, const ra return radio->driver.set_gfsk_pkt_params( radio->context, params ); } +/** + * @brief Set the parameters for GFSK address filtering + * + * @remark The command @ref ral_set_pkt_type with @ref RAL_PKT_TYPE_GFSK parameter must be called prior to this one. + * + * @param [in] radio Pointer to radio data structure + * @param [in] node_address node_address The node address used as filter + * @param [in] broadcast_address The broadcast address used as filter + * + * @returns Operation status + */ +static inline ral_status_t ral_set_gfsk_pkt_address( const ral_t* radio, const uint8_t node_address, + const uint8_t broadcast_address ) +{ + return radio->driver.set_gfsk_pkt_address( radio->context, node_address, broadcast_address ); +} + /** * @brief Set the modulation parameters for LoRa packets * @@ -714,7 +731,7 @@ static inline ral_status_t ral_set_flrc_sync_word( const ral_t* radio, const uin * * @returns Operation status */ -static inline ral_status_t ral_set_gfsk_crc_params( const ral_t* radio, const uint16_t seed, const uint16_t polynomial ) +static inline ral_status_t ral_set_gfsk_crc_params( const ral_t* radio, const uint32_t seed, const uint32_t polynomial ) { return radio->driver.set_gfsk_crc_params( radio->context, seed, polynomial ); } diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_drv.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_drv.h index 69b5929..3ae4fcd 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_drv.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_drv.h @@ -95,6 +95,8 @@ typedef ral_status_t ( *ral_set_pkt_type_f )( const void* context, const ral_pkt typedef ral_status_t ( *ral_get_pkt_type_f )( const void* context, ral_pkt_type_t* pkt_type ); typedef ral_status_t ( *ral_set_gfsk_mod_params_f )( const void* context, const ral_gfsk_mod_params_t* params ); typedef ral_status_t ( *ral_set_gfsk_pkt_params_f )( const void* context, const ral_gfsk_pkt_params_t* params ); +typedef ral_status_t ( *ral_set_gfsk_pkt_address_f )( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ); typedef ral_status_t ( *ral_set_lora_mod_params_f )( const void* context, const ral_lora_mod_params_t* params ); typedef ral_status_t ( *ral_set_lora_pkt_params_f )( const void* context, const ral_lora_pkt_params_t* params ); typedef ral_status_t ( *ral_set_lora_cad_params_f )( const void* context, const ral_lora_cad_params_t* params ); @@ -116,8 +118,8 @@ typedef ral_status_t ( *ral_set_gfsk_sync_word_f )( const void* context, const u typedef ral_status_t ( *ral_set_lora_sync_word_f )( const void* context, const uint8_t sync_word ); typedef ral_status_t ( *ral_set_flrc_sync_word_f )( const void* context, const uint8_t* sync_word, const uint8_t sync_word_len ); -typedef ral_status_t ( *ral_set_gfsk_crc_params_f )( const void* context, const uint16_t seed, - const uint16_t polynomial ); +typedef ral_status_t ( *ral_set_gfsk_crc_params_f )( const void* context, const uint32_t seed, + const uint32_t polynomial ); typedef ral_status_t ( *ral_set_flrc_crc_params_f )( const void* context, const uint32_t seed ); typedef ral_status_t ( *ral_set_gfsk_whitening_seed_f )( const void* context, const uint16_t seed ); typedef ral_status_t ( *ral_lr_fhss_init_f )( const void* context, const ral_lr_fhss_params_t* lr_fhss_params ); @@ -182,6 +184,7 @@ typedef struct ral_drv_s ral_get_pkt_type_f get_pkt_type; ral_set_gfsk_mod_params_f set_gfsk_mod_params; ral_set_gfsk_pkt_params_f set_gfsk_pkt_params; + ral_set_gfsk_pkt_address_f set_gfsk_pkt_address; ral_set_lora_mod_params_f set_lora_mod_params; ral_set_lora_pkt_params_f set_lora_pkt_params; ral_set_lora_cad_params_f set_lora_cad_params; diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68.c b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68.c index ccd59f7..a60fca8 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68.c +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68.c @@ -531,6 +531,12 @@ ral_status_t ral_llcc68_set_gfsk_pkt_params( const void* context, const ral_gfsk return ( ral_status_t ) llcc68_set_gfsk_pkt_params( context, &radio_pkt_params ); } +ral_status_t ral_llcc68_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ) +{ + return ( ral_status_t ) llcc68_set_gfsk_pkt_address( context, node_address, braodcast_address ); +} + ral_status_t ral_llcc68_set_lora_mod_params( const void* context, const ral_lora_mod_params_t* params ) { ral_status_t status = RAL_STATUS_ERROR; @@ -692,17 +698,17 @@ ral_status_t ral_llcc68_set_flrc_sync_word( const void* context, const uint8_t* return RAL_STATUS_UNSUPPORTED_FEATURE; } -ral_status_t ral_llcc68_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ) +ral_status_t ral_llcc68_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ) { ral_status_t status = RAL_STATUS_ERROR; - status = ( ral_status_t ) llcc68_set_gfsk_crc_seed( context, seed ); + status = ( ral_status_t ) llcc68_set_gfsk_crc_seed( context, ( uint16_t ) seed ); if( status != RAL_STATUS_OK ) { return status; } - status = ( ral_status_t ) llcc68_set_gfsk_crc_polynomial( context, polynomial ); + status = ( ral_status_t ) llcc68_set_gfsk_crc_polynomial( context, ( uint16_t ) polynomial ); if( status != RAL_STATUS_OK ) { return status; @@ -796,20 +802,38 @@ ral_status_t ral_llcc68_get_lora_rx_pkt_cr_crc( const void* context, ral_lora_cr ral_status_t ral_llcc68_get_tx_consumption_in_ua( const void* context, const int8_t output_pwr_in_dbm, const uint32_t rf_freq_in_hz, uint32_t* pwr_consumption_in_ua ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + llcc68_reg_mod_t radio_reg_mode; + ral_llcc68_bsp_tx_cfg_output_params_t tx_cfg_output_params; + const ral_llcc68_bsp_tx_cfg_input_params_t tx_cfg_input_params = { + .freq_in_hz = rf_freq_in_hz, + .system_output_pwr_in_dbm = output_pwr_in_dbm, + }; + ral_llcc68_bsp_get_tx_cfg( context, &tx_cfg_input_params, &tx_cfg_output_params ); + ral_llcc68_bsp_get_reg_mode( context, &radio_reg_mode ); + + return ral_llcc68_bsp_get_instantaneous_tx_power_consumption( context, &tx_cfg_output_params, radio_reg_mode, + pwr_consumption_in_ua ); } ral_status_t ral_llcc68_get_gfsk_rx_consumption_in_ua( const void* context, const uint32_t br_in_bps, const uint32_t bw_dsb_in_hz, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + llcc68_reg_mod_t radio_reg_mode; + ral_llcc68_bsp_get_reg_mode( context, &radio_reg_mode ); + + return ral_llcc68_bsp_get_instantaneous_gfsk_rx_power_consumption( context, radio_reg_mode, rx_boosted, + pwr_consumption_in_ua ); } ral_status_t ral_llcc68_get_lora_rx_consumption_in_ua( const void* context, const ral_lora_bw_t bw, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + llcc68_reg_mod_t radio_reg_mode; + ral_llcc68_bsp_get_reg_mode( context, &radio_reg_mode ); + + return ral_llcc68_bsp_get_instantaneous_lora_rx_power_consumption( context, radio_reg_mode, rx_boosted, + pwr_consumption_in_ua ); } ral_status_t ral_llcc68_get_random_numbers( const void* context, uint32_t* numbers, unsigned int n ) @@ -920,7 +944,7 @@ ral_status_t ral_llcc68_get_lora_cad_det_peak( const void* context, ral_lora_sf_ break; } - ral_llcc68_bsp_get_lora_cad_det_peak( sf, bw, nb_symbol, cad_det_peak ); + ral_llcc68_bsp_get_lora_cad_det_peak( context, sf, bw, nb_symbol, cad_det_peak ); return RAL_STATUS_OK; } diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68.h index 429bd3a..e68611c 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68.h @@ -257,6 +257,12 @@ ral_status_t ral_llcc68_set_gfsk_mod_params( const void* context, const ral_gfsk */ ral_status_t ral_llcc68_set_gfsk_pkt_params( const void* context, const ral_gfsk_pkt_params_t* params ); +/** + * @see ral_set_gfsk_pkt_address + */ +ral_status_t ral_llcc68_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ); + /** * @see ral_set_lora_mod_params */ @@ -343,8 +349,10 @@ ral_status_t ral_llcc68_set_flrc_sync_word( const void* context, const uint8_t* /** * @see ral_set_gfsk_crc_params + * + * @remark RAL Interface declares seed and polynomial as uint32_t but llcc68 drivers handles uint16_t only */ -ral_status_t ral_llcc68_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ); +ral_status_t ral_llcc68_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ); /** * @see ral_set_flrc_crc_params @@ -388,9 +396,8 @@ ral_status_t ral_llcc68_lr_fhss_get_time_on_air_in_ms( const void* context, cons /** * @see ral_lr_fhss_get_hop_sequence_count */ -ral_status_t ral_llcc68_lr_fhss_get_hop_sequence_count( const void* context, - const ral_lr_fhss_params_t* lr_fhss_params, - unsigned int* hop_sequence_count ); +ral_status_t ral_llcc68_lr_fhss_get_hop_sequence_count( const void* context, const ral_lr_fhss_params_t* lr_fhss_params, + unsigned int* hop_sequence_count ); /** * @see ral_lr_fhss_get_bit_delay_in_us diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68_bsp.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68_bsp.h index 203571d..f05a67c 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68_bsp.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_llcc68_bsp.h @@ -150,13 +150,51 @@ void ral_llcc68_bsp_get_ocp_value( const void* context, uint8_t* ocp_in_step_of_ /** * @brief Get the Channel Activity Detection (CAD) DetPeak value * + * @param [in] context Chip implementation context * @param [in] sf CAD LoRa spreading factor * @param [in] bw CAD LoRa bandwidth * @param [in] nb_symbol CAD on number of symbols * @param [in, out] in_out_cad_det_peak CAD DetPeak value proposed by the ral could be overwritten */ -void ral_llcc68_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ); +void ral_llcc68_bsp_get_lora_cad_det_peak( const void* context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ); + +/** + * @brief Get the instantaneous power consumption for the given Tx configuration + * + * @param [in] context Chip implementation context + * @param [in] tx_cfg_output_params_local The Tx configuration + * @param [in] radio_reg_mode The regulator configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_llcc68_bsp_get_instantaneous_tx_power_consumption( const void* context, + const ral_llcc68_bsp_tx_cfg_output_params_t* tx_cfg_output_params_local, llcc68_reg_mod_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given GFSK Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] radio_reg_mode The regulator configuration + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_llcc68_bsp_get_instantaneous_gfsk_rx_power_consumption( const void* context, + llcc68_reg_mod_t radio_reg_mode, bool rx_boosted, uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given LoRa Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] radio_reg_mode The regulator configuration + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_llcc68_bsp_get_instantaneous_lora_rx_power_consumption( const void* context, + llcc68_reg_mod_t radio_reg_mode, bool rx_boosted, uint32_t* pwr_consumption_in_ua ); #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx.c b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx.c index 424f1d0..39a9621 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx.c +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx.c @@ -56,207 +56,6 @@ * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define LR11XX_LP_MIN_OUTPUT_POWER -17 -#define LR11XX_LP_MAX_OUTPUT_POWER 15 - -#define LR11XX_HP_MIN_OUTPUT_POWER -9 -#define LR11XX_HP_MAX_OUTPUT_POWER 22 - -#define LR11XX_HF_MIN_OUTPUT_POWER -17 -#define LR11XX_HF_MAX_OUTPUT_POWER 13 - -#define LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET 17 -#define LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET 9 -#define LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET 17 - -static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[] = { - 10820, // -17 dBm - 10980, // -16 dBm - 11060, // -15 dBm - 11160, // -14 dBm - 11300, // -13 dBm - 11430, // -12 dBm - 11550, // -11 dBm - 11680, // -10 dBm - 11930, // -9 dBm - 12170, // -8 dBm - 12420, // -7 dBm - 12650, // -6 dBm - 12900, // -5 dBm - 13280, // -4 dBm - 13600, // -3 dBm - 14120, // -2 dBm - 14600, // -1 dBm - 15090, // 0 dBm - 15780, // 1 dBm - 16490, // 2 dBm - 17250, // 3 dBm - 17850, // 4 dBm - 18720, // 5 dBm - 19640, // 6 dBm - 20560, // 7 dBm - 21400, // 8 dBm - 22620, // 9 dBm - 23720, // 10 dBm - 25050, // 11 dBm - 26350, // 12 dBm - 27870, // 13 dBm - 28590, // 14 dBm - 37820, // 15 dBm -}; - -static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[] = { - 14950, // -17 dBm - 15280, // -16 dBm - 15530, // -15 dBm - 15770, // -14 dBm - 16020, // -13 dBm - 16290, // -12 dBm - 16550, // -11 dBm - 16760, // -10 dBm - 17280, // -9 dBm - 17770, // -8 dBm - 18250, // -7 dBm - 18750, // -6 dBm - 19250, // -5 dBm - 19960, // -4 dBm - 20710, // -3 dBm - 21620, // -2 dBm - 22570, // -1 dBm - 23570, // 0 dBm - 24990, // 1 dBm - 26320, // 2 dBm - 27830, // 3 dBm - 29070, // 4 dBm - 30660, // 5 dBm - 32490, // 6 dBm - 34220, // 7 dBm - 35820, // 8 dBm - 38180, // 9 dBm - 40220, // 10 dBm - 42800, // 11 dBm - 45030, // 12 dBm - 47900, // 13 dBm - 51220, // 14 dBm - 66060, // 15 dBm -}; - -static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[] = { - 27750, // -9 dBm - 29100, // -8 dBm - 30320, // -7 dBm - 31650, // -6 dBm - 34250, // -5 dBm - 35550, // -4 dBm - 36770, // -3 dBm - 39250, // -2 dBm - 41480, // -1 dBm - 43820, // 0 dBm - 46000, // 1 dBm - 49020, // 2 dBm - 50900, // 3 dBm - 54200, // 4 dBm - 56330, // 5 dBm - 59050, // 6 dBm - 62210, // 7 dBm - 65270, // 8 dBm - 68600, // 9 dBm - 71920, // 10 dBm - 75500, // 11 dBm - 79500, // 12 dBm - 84130, // 13 dBm - 88470, // 14 dBm - 92200, // 15 dBm - 94340, // 16 dBm - 96360, // 17 dBm - 98970, // 18 dBm - 102220, // 19 dBm - 106250, // 20 dBm - 111300, // 21 dBm - 113040, // 22 dBm -}; - -static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[] = { - 31310, // -9 dBm - 32700, // -8 dBm - 33970, // -7 dBm - 35270, // -6 dBm - 37900, // -5 dBm - 39140, // -4 dBm - 40380, // -3 dBm - 42860, // -2 dBm - 45150, // -1 dBm - 47400, // 0 dBm - 49600, // 1 dBm - 52600, // 2 dBm - 54460, // 3 dBm - 57690, // 4 dBm - 59840, // 5 dBm - 62550, // 6 dBm - 65750, // 7 dBm - 68520, // 8 dBm - 72130, // 9 dBm - 75230, // 10 dBm - 78600, // 11 dBm - 82770, // 12 dBm - 87450, // 13 dBm - 91700, // 14 dBm - 95330, // 15 dBm - 97520, // 16 dBm - 99520, // 17 dBm - 102080, // 18 dBm - 105140, // 19 dBm - 109300, // 20 dBm - 114460, // 21 dBm - 116530, // 22 dBm -}; - -static const uint32_t ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[] = { - 11800, // -17 dBm - 11800, // -16 dBm - 11900, // -15 dBm - 12020, // -14 dBm - 12120, // -13 dBm - 12230, // -12 dBm - 12390, // -11 dBm - 12540, // -10 dBm - 12740, // -9 dBm - 12960, // -8 dBm - 13150, // -7 dBm - 13460, // -6 dBm - 13770, // -5 dBm - 14070, // -4 dBm - 14460, // -3 dBm - 15030, // -2 dBm - 15440, // -1 dBm - 16030, // 0 dBm - 16980, // 1 dBm - 17590, // 2 dBm - 18270, // 3 dBm - 19060, // 4 dBm - 19900, // 5 dBm - 20740, // 6 dBm - 21610, // 7 dBm - 22400, // 8 dBm - 23370, // 9 dBm - 24860, // 10 dBm - 26410, // 11 dBm - 26430, // 12 dBm - 27890, // 13 dBm -}; - -// TODO: check values -#define LR11XX_GFSK_RX_CONSUMPTION_DCDC 5400 -#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 7500 - -#define LR11XX_GFSK_RX_CONSUMPTION_LDO 5400 -#define LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO 7500 - -#define LR11XX_LORA_RX_CONSUMPTION_DCDC 5700 -#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC 7800 - -#define LR11XX_LORA_RX_CONSUMPTION_LDO 5700 -#define LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO 7800 /* * ----------------------------------------------------------------------------- @@ -801,6 +600,12 @@ ral_status_t ral_lr11xx_set_gfsk_pkt_params( const void* context, const ral_gfsk return ( ral_status_t ) lr11xx_radio_set_gfsk_pkt_params( context, &radio_pkt_params ); } +ral_status_t ral_lr11xx_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ) +{ + return ( ral_status_t ) lr11xx_radio_set_pkt_address( context, node_address, braodcast_address ); +} + ral_status_t ral_lr11xx_set_lora_mod_params( const void* context, const ral_lora_mod_params_t* ral_mod_params ) { ral_status_t status = RAL_STATUS_ERROR; @@ -966,7 +771,7 @@ ral_status_t ral_lr11xx_set_flrc_sync_word( const void* context, const uint8_t* return RAL_STATUS_UNSUPPORTED_FEATURE; } -ral_status_t ral_lr11xx_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ) +ral_status_t ral_lr11xx_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ) { return ( ral_status_t ) lr11xx_radio_set_gfsk_crc_params( context, seed, polynomial ); } @@ -1083,167 +888,43 @@ ral_status_t ral_lr11xx_get_lora_rx_pkt_cr_crc( const void* context, ral_lora_cr ral_status_t ral_lr11xx_get_tx_consumption_in_ua( const void* context, const int8_t output_pwr_in_dbm, const uint32_t rf_freq_in_hz, uint32_t* pwr_consumption_in_ua ) { + // 1. Get the LR11xx BSP configuration corresponding to the input parameters lr11xx_system_reg_mode_t radio_reg_mode; ral_lr11xx_bsp_tx_cfg_output_params_t tx_cfg_output_params; const ral_lr11xx_bsp_tx_cfg_input_params_t tx_cfg_input_params = { .freq_in_hz = rf_freq_in_hz, .system_output_pwr_in_dbm = output_pwr_in_dbm, }; - ral_lr11xx_bsp_get_tx_cfg( context, &tx_cfg_input_params, &tx_cfg_output_params ); - ral_lr11xx_bsp_get_reg_mode( context, &radio_reg_mode ); - if( tx_cfg_output_params.pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_LP ) - { - if( tx_cfg_output_params.pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) - { - uint8_t index = 0; - - if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected > LR11XX_LP_MAX_OUTPUT_POWER ) - { - index = LR11XX_LP_MAX_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; - } - else if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected < LR11XX_LP_MIN_OUTPUT_POWER ) - { - index = LR11XX_LP_MIN_OUTPUT_POWER + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; - } - else - { - index = tx_cfg_output_params.chip_output_pwr_in_dbm_expected + LR11XX_LP_CONVERT_TABLE_INDEX_OFFSET; - } - - if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_lp_vreg[index]; - } - else - { - *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_lp_vreg[index]; - } - } - else - { - return RAL_STATUS_UNSUPPORTED_FEATURE; - } - } - else if( tx_cfg_output_params.pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HP ) - { - if( tx_cfg_output_params.pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VBAT ) - { - uint8_t index = 0; - - if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected > LR11XX_HP_MAX_OUTPUT_POWER ) - { - index = LR11XX_HP_MAX_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; - } - else if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected < LR11XX_HP_MIN_OUTPUT_POWER ) - { - index = LR11XX_HP_MIN_OUTPUT_POWER + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; - } - else - { - index = tx_cfg_output_params.chip_output_pwr_in_dbm_expected + LR11XX_HP_CONVERT_TABLE_INDEX_OFFSET; - } - - if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hp_vbat[index]; - } - else - { - *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_ldo_hp_vbat[index]; - } - } - else - { - return RAL_STATUS_UNSUPPORTED_FEATURE; - } - } - else if( tx_cfg_output_params.pa_cfg.pa_sel == LR11XX_RADIO_PA_SEL_HF ) - { - if( tx_cfg_output_params.pa_cfg.pa_reg_supply == LR11XX_RADIO_PA_REG_SUPPLY_VREG ) - { - uint8_t index = 0; - - if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected > LR11XX_HF_MAX_OUTPUT_POWER ) - { - index = LR11XX_HF_MAX_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; - } - else if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected < LR11XX_HF_MIN_OUTPUT_POWER ) - { - index = LR11XX_HF_MIN_OUTPUT_POWER + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; - } - else - { - index = tx_cfg_output_params.chip_output_pwr_in_dbm_expected + LR11XX_HF_CONVERT_TABLE_INDEX_OFFSET; - } - - if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = ral_lr11xx_convert_tx_dbm_to_ua_reg_mode_dcdc_hf_vreg[index]; - } - else - { - return RAL_STATUS_UNSUPPORTED_FEATURE; - } - } - else - { - return RAL_STATUS_UNSUPPORTED_FEATURE; - } - } - else - { - return RAL_STATUS_UNKNOWN_VALUE; - } - - return RAL_STATUS_OK; + // 2. Refer to the BSP to get the instantaneous power consumption corresponding to the LR1xx BSP configuration + return ral_lr11xx_bsp_get_instantaneous_tx_power_consumption( context, &tx_cfg_output_params, radio_reg_mode, + pwr_consumption_in_ua ); } ral_status_t ral_lr11xx_get_gfsk_rx_consumption_in_ua( const void* context, const uint32_t br_in_bps, const uint32_t bw_dsb_in_hz, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { + // 1. Get the regulator configured lr11xx_system_reg_mode_t radio_reg_mode; - ral_lr11xx_bsp_get_reg_mode( context, &radio_reg_mode ); - if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_GFSK_RX_CONSUMPTION_DCDC; - } - else - { - // TODO: find the good values - *pwr_consumption_in_ua = - ( rx_boosted ) ? LR11XX_GFSK_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_GFSK_RX_CONSUMPTION_LDO; - } - - return RAL_STATUS_OK; + // 2. Refer to BSP to get the instantaneous GFSK Rx Power consumption + return ral_lr11xx_bsp_get_instantaneous_gfsk_rx_power_consumption( context, radio_reg_mode, rx_boosted, + pwr_consumption_in_ua ); } ral_status_t ral_lr11xx_get_lora_rx_consumption_in_ua( const void* context, const ral_lora_bw_t bw, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { + // 1. Get the regulator configured lr11xx_system_reg_mode_t radio_reg_mode; - ral_lr11xx_bsp_get_reg_mode( context, &radio_reg_mode ); - if( radio_reg_mode == LR11XX_SYSTEM_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_DCDC : LR11XX_LORA_RX_CONSUMPTION_DCDC; - } - else - { - // TODO: find the good values - *pwr_consumption_in_ua = - ( rx_boosted ) ? LR11XX_LORA_RX_BOOSTED_CONSUMPTION_LDO : LR11XX_LORA_RX_CONSUMPTION_LDO; - } - - return RAL_STATUS_OK; + // 2. Refer to BSP to get the instantaneous LoRa Rx Power consumption + return ral_lr11xx_bsp_get_instantaneous_lora_rx_power_consumption( context, radio_reg_mode, rx_boosted, pwr_consumption_in_ua ); } ral_status_t ral_lr11xx_get_random_numbers( const void* context, uint32_t* numbers, unsigned int n ) @@ -1366,7 +1047,7 @@ ral_status_t ral_lr11xx_get_lora_cad_det_peak( const void* context, ral_lora_sf_ break; } - ral_lr11xx_bsp_get_lora_cad_det_peak( sf, bw, nb_symbol, cad_det_peak ); + ral_lr11xx_bsp_get_lora_cad_det_peak( context, sf, bw, nb_symbol, cad_det_peak ); return RAL_STATUS_OK; } diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx.h index a6a6bed..6b987b5 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx.h @@ -212,6 +212,12 @@ ral_status_t ral_lr11xx_set_tx_cfg( const void* context, const int8_t output_pwr */ ral_status_t ral_lr11xx_set_pkt_payload( const void* context, const uint8_t* buffer, const uint16_t size ); +/** + * @see ral_set_gfsk_pkt_address + */ +ral_status_t ral_lr11xx_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ); + /** * @see ral_get_pkt_payload */ @@ -350,7 +356,7 @@ ral_status_t ral_lr11xx_set_flrc_sync_word( const void* context, const uint8_t* /** * @see ral_set_gfsk_crc_params */ -ral_status_t ral_lr11xx_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ); +ral_status_t ral_lr11xx_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ); /** * @see ral_set_flrc_crc_params @@ -401,9 +407,8 @@ ral_status_t ral_lr11xx_lr_fhss_get_bit_delay_in_us( const void* context, const /** * @see ral_lr_fhss_get_hop_sequence_count */ -ral_status_t ral_lr11xx_lr_fhss_get_hop_sequence_count( const void* context, - const ral_lr_fhss_params_t* lr_fhss_params, - unsigned int* hop_sequence_count ); +ral_status_t ral_lr11xx_lr_fhss_get_hop_sequence_count( const void* context, const ral_lr_fhss_params_t* lr_fhss_params, + unsigned int* hop_sequence_count ); /** * @see ral_get_lora_rx_pkt_cr_crc diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx_bsp.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx_bsp.h index 470c0f3..5a6b2b7 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx_bsp.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_lr11xx_bsp.h @@ -144,13 +144,14 @@ void ral_lr11xx_bsp_get_rssi_calibration_table( const void* context, const uint3 /** * @brief Get the Channel Activity Detection (CAD) DetPeak value * + * @param [in] context Chip implementation context * @param [in] sf CAD LoRa spreading factor * @param [in] bw CAD LoRa bandwidth * @param [in] nb_symbol CAD on number of symbols * @param [in, out] in_out_cad_det_peak CAD DetPeak value proposed by the ral could be overwritten */ -void ral_lr11xx_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ); +void ral_lr11xx_bsp_get_lora_cad_det_peak( const void* context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ); /** * Get the Rx boost configuration @@ -168,6 +169,42 @@ void ral_lr11xx_bsp_get_rx_boost_cfg( const void* context, bool* rx_boost_is_act */ void ral_lr11xx_bsp_get_lfclk_cfg_in_sleep( const void* context, bool* lfclk_is_running ); +/** + * @brief Get the instantaneous power consumption for the given Tx configuration + * + * @param [in] context Chip implementation context + * @param [in] tx_cfg The Tx configuration + * @param [in] radio_reg_mode The regulator configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_lr11xx_bsp_get_instantaneous_tx_power_consumption( const void* context, + const ral_lr11xx_bsp_tx_cfg_output_params_t* tx_cfg, lr11xx_system_reg_mode_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given GFSK Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] radio_reg_mode The regulator configuration + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_lr11xx_bsp_get_instantaneous_gfsk_rx_power_consumption( const void* context, + lr11xx_system_reg_mode_t radio_reg_mode, bool rx_boosted, uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given LoRa Rx configuration + * + * @param [in] context Chip implementation context + * @param radio_reg_mode The regulator configuration + * @param rx_boosted The Rx boosted configuration + * @param pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_lr11xx_bsp_get_instantaneous_lora_rx_power_consumption( const void* context, + lr11xx_system_reg_mode_t radio_reg_mode, bool rx_boosted, uint32_t* pwr_consumption_in_ua ); #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x.c b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x.c index 6436ab2..dbf427c 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x.c +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x.c @@ -55,170 +55,6 @@ * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define SX126X_LP_MIN_OUTPUT_POWER -17 -#define SX126X_LP_MAX_OUTPUT_POWER 15 - -#define SX126X_HP_MIN_OUTPUT_POWER -9 -#define SX126X_HP_MAX_OUTPUT_POWER 22 - -#define SX126X_LP_CONVERT_TABLE_INDEX_OFFSET 17 -#define SX126X_HP_CONVERT_TABLE_INDEX_OFFSET 9 - -static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_lp[] = { - 5200, // -17 dBm - 5400, // -16 dBm - 5600, // -15 dBm - 5700, // -14 dBm - 5800, // -13 dBm - 6000, // -12 dBm - 6100, // -11 dBm - 6200, // -10 dBm - 6500, // -9 dBm - 6800, // -8 dBm - 7000, // -7 dBm - 7300, // -6 dBm - 7500, // -5 dBm - 7900, // -4 dBm - 8300, // -3 dBm - 8800, // -2 dBm - 9300, // -1 dBm - 9800, // 0 dBm - 10600, // 1 dBm - 11400, // 2 dBm - 12200, // 3 dBm - 12900, // 4 dBm - 13800, // 5 dBm - 14700, // 6 dBm - 15700, // 7 dBm - 16600, // 8 dBm - 17900, // 9 dBm - 18500, // 10 dBm - 20500, // 11 dBm - 21900, // 12 dBm - 23500, // 13 dBm - 25500, // 14 dBm - 32500, // 15 dBm -}; - -static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_lp[] = { - 9800, // -17 dBm - 10300, // -16 dBm - 10500, // -15 dBm - 10800, // -14 dBm - 11100, // -13 dBm - 11300, // -12 dBm - 11600, // -11 dBm - 11900, // -10 dBm - 12400, // -9 dBm - 12900, // -8 dBm - 13400, // -7 dBm - 13900, // -6 dBm - 14500, // -5 dBm - 15300, // -4 dBm - 16000, // -3 dBm - 17000, // -2 dBm - 18000, // -1 dBm - 19000, // 0 dBm - 20600, // 1 dBm - 22000, // 2 dBm - 23500, // 3 dBm - 24900, // 4 dBm - 26600, // 5 dBm - 28400, // 6 dBm - 30200, // 7 dBm - 32000, // 8 dBm - 34300, // 9 dBm - 36600, // 10 dBm - 39200, // 11 dBm - 41700, // 12 dBm - 44700, // 13 dBm - 48200, // 14 dBm - 52200, // 15 dBm -}; - -static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_hp[] = { - 24000, // -9 dBm - 25400, // -8 dBm - 26700, // -7 dBm - 28000, // -6 dBm - 30600, // -5 dBm - 31900, // -4 dBm - 33200, // -3 dBm - 35700, // -2 dBm - 38200, // -1 dBm - 40600, // 0 dBm - 42900, // 1 dBm - 46200, // 2 dBm - 48200, // 3 dBm - 51800, // 4 dBm - 54100, // 5 dBm - 57000, // 6 dBm - 60300, // 7 dBm - 63500, // 8 dBm - 67100, // 9 dBm - 70500, // 10 dBm - 74200, // 11 dBm - 78400, // 12 dBm - 83500, // 13 dBm - 89300, // 14 dBm - 92400, // 15 dBm - 94500, // 16 dBm - 95400, // 17 dBm - 97500, // 18 dBm - 100100, // 19 dBm - 103800, // 20 dBm - 109100, // 21 dBm - 117900, // 22 dBm -}; - -static const uint32_t ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_hp[] = { - 25900, // -9 dBm - 27400, // -8 dBm - 28700, // -7 dBm - 30000, // -6 dBm - 32600, // -5 dBm - 33900, // -4 dBm - 35200, // -3 dBm - 37700, // -2 dBm - 40100, // -1 dBm - 42600, // 0 dBm - 44900, // 1 dBm - 48200, // 2 dBm - 50200, // 3 dBm - 53800, // 4 dBm - 56100, // 5 dBm - 59000, // 6 dBm - 62300, // 7 dBm - 65500, // 8 dBm - 69000, // 9 dBm - 72500, // 10 dBm - 76200, // 11 dBm - 80400, // 12 dBm - 85400, // 13 dBm - 90200, // 14 dBm - 94400, // 15 dBm - 96500, // 16 dBm - 97700, // 17 dBm - 99500, // 18 dBm - 102100, // 19 dBm - 105800, // 20 dBm - 111000, // 21 dBm - 119800, // 22 dBm -}; - -// TODO: check values -#define SX126X_GFSK_RX_CONSUMPTION_DCDC 4200 -#define SX126X_GFSK_RX_BOOSTED_CONSUMPTION_DCDC 4800 - -#define SX126X_GFSK_RX_CONSUMPTION_LDO 8000 -#define SX126X_GFSK_RX_BOOSTED_CONSUMPTION_LDO 9300 - -#define SX126X_LORA_RX_CONSUMPTION_DCDC 4600 -#define SX126X_LORA_RX_BOOSTED_CONSUMPTION_DCDC 5300 - -#define SX126X_LORA_RX_CONSUMPTION_LDO 8880 -#define SX126X_LORA_RX_BOOSTED_CONSUMPTION_LDO 10100 - /* * ----------------------------------------------------------------------------- * --- PRIVATE TYPES ----------------------------------------------------------- @@ -805,6 +641,12 @@ ral_status_t ral_sx126x_set_gfsk_pkt_params( const void* context, const ral_gfsk return ( ral_status_t ) sx126x_set_gfsk_pkt_params( context, &radio_pkt_params ); } +ral_status_t ral_sx126x_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ) +{ + return ( ral_status_t ) sx126x_set_gfsk_pkt_address( context, node_address, braodcast_address ); +} + ral_status_t ral_sx126x_set_lora_mod_params( const void* context, const ral_lora_mod_params_t* params ) { ral_status_t status = RAL_STATUS_ERROR; @@ -965,17 +807,17 @@ ral_status_t ral_sx126x_set_flrc_sync_word( const void* context, const uint8_t* return RAL_STATUS_UNSUPPORTED_FEATURE; } -ral_status_t ral_sx126x_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ) +ral_status_t ral_sx126x_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ) { ral_status_t status = RAL_STATUS_ERROR; - status = ( ral_status_t ) sx126x_set_gfsk_crc_seed( context, seed ); + status = ( ral_status_t ) sx126x_set_gfsk_crc_seed( context, ( uint16_t ) seed ); if( status != RAL_STATUS_OK ) { return status; } - status = ( ral_status_t ) sx126x_set_gfsk_crc_polynomial( context, polynomial ); + status = ( ral_status_t ) sx126x_set_gfsk_crc_polynomial( context, ( uint16_t ) polynomial ); if( status != RAL_STATUS_OK ) { return status; @@ -1094,71 +936,11 @@ ral_status_t ral_sx126x_get_tx_consumption_in_ua( const void* context, const int .freq_in_hz = rf_freq_in_hz, .system_output_pwr_in_dbm = output_pwr_in_dbm, }; - ral_sx126x_bsp_get_tx_cfg( context, &tx_cfg_input_params, &tx_cfg_output_params ); - ral_sx126x_bsp_get_reg_mode( context, &radio_reg_mode ); - // SX1261 - if( tx_cfg_output_params.pa_cfg.device_sel == 0x01 ) - { - uint8_t index = 0; - - if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected > SX126X_LP_MAX_OUTPUT_POWER ) - { - index = SX126X_LP_MAX_OUTPUT_POWER + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; - } - else if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected < SX126X_LP_MIN_OUTPUT_POWER ) - { - index = SX126X_LP_MIN_OUTPUT_POWER + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; - } - else - { - index = tx_cfg_output_params.chip_output_pwr_in_dbm_expected + SX126X_LP_CONVERT_TABLE_INDEX_OFFSET; - } - - if( radio_reg_mode == SX126X_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_lp[index]; - } - else - { - *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_lp[index]; - } - } - // SX1262 - else if( tx_cfg_output_params.pa_cfg.device_sel == 0x00 ) - { - uint8_t index = 0; - - if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected > SX126X_HP_MAX_OUTPUT_POWER ) - { - index = SX126X_HP_MAX_OUTPUT_POWER + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; - } - else if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected < SX126X_HP_MIN_OUTPUT_POWER ) - { - index = SX126X_HP_MIN_OUTPUT_POWER + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; - } - else - { - index = tx_cfg_output_params.chip_output_pwr_in_dbm_expected + SX126X_HP_CONVERT_TABLE_INDEX_OFFSET; - } - - if( radio_reg_mode == SX126X_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_dcdc_hp[index]; - } - else - { - *pwr_consumption_in_ua = ral_sx126x_convert_tx_dbm_to_ua_reg_mode_ldo_hp[index]; - } - } - else - { - return RAL_STATUS_UNKNOWN_VALUE; - } - - return RAL_STATUS_OK; + return ral_sx126x_bsp_get_instantaneous_tx_power_consumption( context, &tx_cfg_output_params, radio_reg_mode, + pwr_consumption_in_ua ); } ral_status_t ral_sx126x_get_gfsk_rx_consumption_in_ua( const void* context, const uint32_t br_in_bps, @@ -1166,46 +948,20 @@ ral_status_t ral_sx126x_get_gfsk_rx_consumption_in_ua( const void* context, cons uint32_t* pwr_consumption_in_ua ) { sx126x_reg_mod_t radio_reg_mode; - ral_sx126x_bsp_get_reg_mode( context, &radio_reg_mode ); - // TODO: find the br/bw dependent values - - if( radio_reg_mode == SX126X_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? SX126X_GFSK_RX_BOOSTED_CONSUMPTION_DCDC : SX126X_GFSK_RX_CONSUMPTION_DCDC; - } - else - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? SX126X_GFSK_RX_BOOSTED_CONSUMPTION_LDO : SX126X_GFSK_RX_CONSUMPTION_LDO; - } - - return RAL_STATUS_OK; + return ral_sx126x_bsp_get_instantaneous_gfsk_rx_power_consumption( context, radio_reg_mode, rx_boosted, + pwr_consumption_in_ua ); } ral_status_t ral_sx126x_get_lora_rx_consumption_in_ua( const void* context, const ral_lora_bw_t bw, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { sx126x_reg_mod_t radio_reg_mode; - ral_sx126x_bsp_get_reg_mode( context, &radio_reg_mode ); - // TODO: find the bw dependent values - - if( radio_reg_mode == SX126X_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? SX126X_LORA_RX_BOOSTED_CONSUMPTION_DCDC : SX126X_LORA_RX_CONSUMPTION_DCDC; - } - else - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? SX126X_LORA_RX_BOOSTED_CONSUMPTION_LDO : SX126X_LORA_RX_CONSUMPTION_LDO; - } - - return RAL_STATUS_OK; + return ral_sx126x_bsp_get_instantaneous_lora_rx_power_consumption( context, radio_reg_mode, rx_boosted, + pwr_consumption_in_ua ); } ral_status_t ral_sx126x_get_random_numbers( const void* context, uint32_t* numbers, unsigned int n ) @@ -1316,7 +1072,7 @@ ral_status_t ral_sx126x_get_lora_cad_det_peak( const void* context, ral_lora_sf_ break; } - ral_sx126x_bsp_get_lora_cad_det_peak( sf, bw, nb_symbol, cad_det_peak ); + ral_sx126x_bsp_get_lora_cad_det_peak( context, sf, bw, nb_symbol, cad_det_peak ); return RAL_STATUS_OK; } diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x.h index a3a006f..eb6f042 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x.h @@ -283,6 +283,12 @@ ral_status_t ral_sx126x_set_gfsk_mod_params( const void* context, const ral_gfsk */ ral_status_t ral_sx126x_set_gfsk_pkt_params( const void* context, const ral_gfsk_pkt_params_t* params ); +/** + * @see ral_set_gfsk_pkt_address + */ +ral_status_t ral_sx126x_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ); + /** * @see ral_set_lora_mod_params */ @@ -369,8 +375,10 @@ ral_status_t ral_sx126x_set_flrc_sync_word( const void* context, const uint8_t* /** * @see ral_set_gfsk_crc_params + * + * @remark RAL Interface declares seed and polynomial as uint32_t but sx126x drivers handles uint16_t only */ -ral_status_t ral_sx126x_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ); +ral_status_t ral_sx126x_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ); /** * @see ral_set_flrc_crc_params diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x_bsp.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x_bsp.h index e1e91a8..9fe1f00 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x_bsp.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx126x_bsp.h @@ -150,13 +150,51 @@ void ral_sx126x_bsp_get_ocp_value( const void* context, uint8_t* ocp_in_step_of_ /** * @brief Get the Channel Activity Detection (CAD) DetPeak value * + * @param [in] context Chip implementation context * @param [in] sf CAD LoRa spreading factor * @param [in] bw CAD LoRa bandwidth * @param [in] nb_symbol CAD on number of symbols * @param [in, out] in_out_cad_det_peak CAD DetPeak value proposed by the ral could be overwritten */ -void ral_sx126x_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ); +void ral_sx126x_bsp_get_lora_cad_det_peak( const void* context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ); + +/** + * @brief Get the instantaneous power consumption for the given Tx configuration + * + * @param [in] context Chip implementation context + * @param [in] tx_cfg_output_params_local The Tx configuration + * @param [in] radio_reg_mode The regulator configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx126x_bsp_get_instantaneous_tx_power_consumption( const void* context, + const ral_sx126x_bsp_tx_cfg_output_params_t* tx_cfg_output_params_local, sx126x_reg_mod_t radio_reg_mode, + uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given GFSK Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] radio_reg_mode The regulator configuration + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx126x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void* context, + sx126x_reg_mod_t radio_reg_mode, bool rx_boosted, uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given LoRa Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] radio_reg_mode The regulator configuration + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx126x_bsp_get_instantaneous_lora_rx_power_consumption( const void* context, + sx126x_reg_mod_t radio_reg_mode, bool rx_boosted, uint32_t* pwr_consumption_in_ua ); #ifdef __cplusplus } diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x.c b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x.c index e709a3f..5e9e7f1 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x.c +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x.c @@ -253,8 +253,8 @@ ral_status_t ral_sx127x_set_tx_cfg( const void* context, const int8_t output_pwr ral_status_t status = RAL_STATUS_ERROR; ral_sx127x_bsp_tx_cfg_output_params_t tx_cfg_output_params = { 0 }; const ral_sx127x_bsp_tx_cfg_input_params_t tx_cfg_input_params = { - .freq_in_hz = rf_freq_in_hz, - .system_output_pwr_in_dbm = output_pwr_in_dbm, + .freq_in_hz = rf_freq_in_hz, + .system_output_pwr_in_dbm = output_pwr_in_dbm, }; ral_sx127x_bsp_get_tx_cfg( context, &tx_cfg_input_params, &tx_cfg_output_params ); @@ -593,7 +593,13 @@ ral_status_t ral_sx127x_set_flrc_sync_word( const void* context, const uint8_t* return RAL_STATUS_UNSUPPORTED_FEATURE; } -ral_status_t ral_sx127x_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ) +ral_status_t ral_sx127x_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ) +{ + return RAL_STATUS_UNSUPPORTED_FEATURE; +} + +ral_status_t ral_sx127x_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ) { return RAL_STATUS_UNSUPPORTED_FEATURE; } @@ -698,20 +704,27 @@ ral_status_t ral_sx127x_get_lora_rx_pkt_cr_crc( const void* context, ral_lora_cr ral_status_t ral_sx127x_get_tx_consumption_in_ua( const void* context, const int8_t output_pwr_in_dbm, const uint32_t rf_freq_in_hz, uint32_t* pwr_consumption_in_ua ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + ral_sx127x_bsp_tx_cfg_output_params_t tx_cfg_output_params; + const ral_sx127x_bsp_tx_cfg_input_params_t tx_cfg_input_params = { + .freq_in_hz = rf_freq_in_hz, + .system_output_pwr_in_dbm = output_pwr_in_dbm, + }; + ral_sx127x_bsp_get_tx_cfg( context, &tx_cfg_input_params, &tx_cfg_output_params ); + + return ral_sx127x_bsp_get_instantaneous_tx_power_consumption( context, &tx_cfg_output_params, pwr_consumption_in_ua ); } ral_status_t ral_sx127x_get_gfsk_rx_consumption_in_ua( const void* context, const uint32_t br_in_bps, const uint32_t bw_dsb_in_hz, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + return ral_sx127x_bsp_get_instantaneous_gfsk_rx_power_consumption( context, rx_boosted, pwr_consumption_in_ua ); } ral_status_t ral_sx127x_get_lora_rx_consumption_in_ua( const void* context, const ral_lora_bw_t bw, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + return ral_sx127x_bsp_get_instantaneous_lora_rx_power_consumption( context, rx_boosted, pwr_consumption_in_ua ); } ral_status_t ral_sx127x_get_random_numbers( const void* context, uint32_t* numbers, unsigned int n ) diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x.h index 5b3dbf2..5e63205 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x.h @@ -349,9 +349,16 @@ ral_status_t ral_sx127x_set_flrc_sync_word( const void* context, const uint8_t* /** * @see ral_set_gfsk_crc_params + * + * @remark RAL Interface declares seed and polynomial as uint32_t but sx127x drivers handles uint16_t only */ -ral_status_t ral_sx127x_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ); +ral_status_t ral_sx127x_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ); +/** + * @see ral_set_gfsk_pkt_address + */ +ral_status_t ral_sx127x_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ); /** * @see ral_set_flrc_crc_params */ diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x_bsp.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x_bsp.h index ccc8792..5bf41a5 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x_bsp.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx127x_bsp.h @@ -1,7 +1,7 @@ /** * @file ral_sx127x_bsp.h * - * @brief Board Support Package for the SX126x-specific RAL. + * @brief Board Support Package for the SX127x-specific RAL. * * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. @@ -105,6 +105,39 @@ void ral_sx127x_bsp_get_tx_cfg( const void* context, const ral_sx127x_bsp_tx_cfg */ void ral_sx127x_bsp_get_ocp_value( const void* context, uint8_t* ocp_trim_value ); +/** + * @brief Get the instantaneous power consumption for the given Tx configuration + * + * @param [in] context Chip implementation context + * @param [in] tx_cfg_output_params_local The Tx configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx127x_bsp_get_instantaneous_tx_power_consumption( const void* context, + const ral_sx127x_bsp_tx_cfg_output_params_t* tx_cfg_output_params_local, uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given GFSK Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx127x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void* context, + bool rx_boosted, uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given LoRa Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx127x_bsp_get_instantaneous_lora_rx_power_consumption( const void* context, + bool rx_boosted, uint32_t* pwr_consumption_in_ua ); + #ifdef __cplusplus } #endif diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x.c b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x.c index d3f82e1..e6625ca 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x.c +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x.c @@ -53,101 +53,6 @@ * ----------------------------------------------------------------------------- * --- PRIVATE CONSTANTS ------------------------------------------------------- */ -#define SX128X_CONVERT_TABLE_INDEX_OFFSET 18 - -static const uint32_t ral_sx128x_convert_tx_dbm_to_ua_reg_mode_dcdc[] = { - 6200, // -18 dBm - 6300, // -17 dBm - 6400, // -16 dBm - 6500, // -15 dBm - 6600, // -14 dBm - 6700, // -13 dBm - 6800, // -12 dBm - 7000, // -11 dBm - 7100, // -10 dBm - 7300, // -9 dBm - 7400, // -8 dBm - 7700, // -7 dBm - 7900, // -6 dBm - 8100, // -5 dBm - 8500, // -4 dBm - 8800, // -3 dBm - 9200, // -2 dBm - 9700, // -1 dBm - 10100, // 0 dBm - 10700, // 1 dBm - 11300, // 2 dBm - 12000, // 3 dBm - 12700, // 4 dBm - 13600, // 5 dBm - 14500, // 6 dBm - 15500, // 7 dBm - 16800, // 8 dBm - 17700, // 9 dBm - 18600, // 10 dBm - 20300, // 11 dBm - 22000, // 12 dBm - 24000, // 13 dBm -}; - -static const uint32_t ral_sx128x_convert_tx_dbm_to_ua_reg_mode_ldo[] = { - 11800, // -18 dBm - 12000, // -17 dBm - 12200, // -16 dBm - 12400, // -15 dBm - 12600, // -14 dBm - 12800, // -13 dBm - 13000, // -12 dBm - 13300, // -11 dBm - 13500, // -10 dBm - 14000, // -9 dBm - 14200, // -8 dBm - 14700, // -7 dBm - 15200, // -6 dBm - 15600, // -5 dBm - 16300, // -4 dBm - 17000, // -3 dBm - 17700, // -2 dBm - 18600, // -1 dBm - 19600, // 0 dBm - 20700, // 1 dBm - 21900, // 2 dBm - 23200, // 3 dBm - 24600, // 4 dBm - 26300, // 5 dBm - 28000, // 6 dBm - 30000, // 7 dBm - 32200, // 8 dBm - 34500, // 9 dBm - 36800, // 10 dBm - 39200, // 11 dBm - 41900, // 12 dBm - 45500, // 13 dBm -}; - -#define SX128X_LORA_RX_CONSUMPTION_BW_200_DCDC 5500 -#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_DCDC 6200 - -#define SX128X_LORA_RX_CONSUMPTION_BW_400_DCDC 6000 -#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_DCDC 6700 - -#define SX128X_LORA_RX_CONSUMPTION_BW_800_DCDC 7000 -#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_DCDC 7700 - -#define SX128X_LORA_RX_CONSUMPTION_BW_1600_DCDC 7500 -#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_DCDC 8200 - -#define SX128X_LORA_RX_CONSUMPTION_BW_200_LDO 10800 -#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_LDO 12200 - -#define SX128X_LORA_RX_CONSUMPTION_BW_400_LDO 11800 -#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_LDO 13200 - -#define SX128X_LORA_RX_CONSUMPTION_BW_800_LDO 13700 -#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_LDO 15200 - -#define SX128X_LORA_RX_CONSUMPTION_BW_1600_LDO 14800 -#define SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_LDO 16300 /* * ----------------------------------------------------------------------------- @@ -683,6 +588,12 @@ ral_status_t ral_sx128x_set_gfsk_pkt_params( const void* context, const ral_gfsk return ( ral_status_t ) sx128x_set_gfsk_pkt_params( context, &radio_pkt_params ); } +ral_status_t ral_sx128x_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ) +{ + return RAL_STATUS_UNSUPPORTED_FEATURE; +} + ral_status_t ral_sx128x_set_lora_mod_params( const void* context, const ral_lora_mod_params_t* params ) { ral_status_t status = RAL_STATUS_ERROR; @@ -870,17 +781,17 @@ ral_status_t ral_sx128x_set_flrc_sync_word( const void* context, const uint8_t* return ( ral_status_t ) sx128x_set_flrc_sync_word( context, 1, sync_word ); } -ral_status_t ral_sx128x_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ) +ral_status_t ral_sx128x_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ) { ral_status_t status = RAL_STATUS_ERROR; - status = ( ral_status_t ) sx128x_set_gfsk_crc_seed( context, seed ); + status = ( ral_status_t ) sx128x_set_gfsk_crc_seed( context, ( uint16_t ) seed ); if( status != RAL_STATUS_OK ) { return status; } - status = ( ral_status_t ) sx128x_set_gfsk_crc_polynomial( context, polynomial ); + status = ( ral_status_t ) sx128x_set_gfsk_crc_polynomial( context, ( uint16_t ) polynomial ); if( status != RAL_STATUS_OK ) { return status; @@ -1003,134 +914,37 @@ ral_status_t ral_sx128x_get_tx_consumption_in_ua( const void* context, const int const uint32_t rf_freq_in_hz, uint32_t* pwr_consumption_in_ua ) { sx128x_reg_mod_t reg_mode; - uint8_t index; ral_sx128x_bsp_tx_cfg_output_params_t tx_cfg_output_params; const ral_sx128x_bsp_tx_cfg_input_params_t tx_cfg_input_params = { .freq_in_hz = rf_freq_in_hz, .system_output_pwr_in_dbm = output_pwr_in_dbm, }; - ral_sx128x_bsp_get_reg_mode( context, ®_mode ); ral_sx128x_bsp_get_tx_cfg( context, &tx_cfg_input_params, &tx_cfg_output_params ); - if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected > SX128X_PWR_MAX ) - { - index = SX128X_PWR_MAX + SX128X_CONVERT_TABLE_INDEX_OFFSET; - } - else if( tx_cfg_output_params.chip_output_pwr_in_dbm_expected < SX128X_PWR_MIN ) - { - index = SX128X_PWR_MIN + SX128X_CONVERT_TABLE_INDEX_OFFSET; - } - else - { - index = tx_cfg_output_params.chip_output_pwr_in_dbm_expected + SX128X_CONVERT_TABLE_INDEX_OFFSET; - } - - if( reg_mode == SX128X_REG_MODE_DCDC ) - { - *pwr_consumption_in_ua = ral_sx128x_convert_tx_dbm_to_ua_reg_mode_dcdc[index]; - } - else if( reg_mode == SX128X_REG_MODE_LDO ) - { - *pwr_consumption_in_ua = ral_sx128x_convert_tx_dbm_to_ua_reg_mode_ldo[index]; - } - else - { - return RAL_STATUS_UNKNOWN_VALUE; - } - - return RAL_STATUS_OK; + return ral_sx128x_bsp_get_instantaneous_tx_power_consumption( context, tx_cfg_output_params, reg_mode, + pwr_consumption_in_ua ); } ral_status_t ral_sx128x_get_gfsk_rx_consumption_in_ua( const void* context, const uint32_t br_in_bps, const uint32_t bw_dsb_in_hz, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { - return RAL_STATUS_UNSUPPORTED_FEATURE; + sx128x_reg_mod_t radio_reg_mode; + ral_sx128x_bsp_get_reg_mode( context, &radio_reg_mode ); + + return ral_sx128x_bsp_get_instantaneous_gfsk_rx_power_consumption( context, radio_reg_mode, rx_boosted, + pwr_consumption_in_ua ); } ral_status_t ral_sx128x_get_lora_rx_consumption_in_ua( const void* context, const ral_lora_bw_t bw, const bool rx_boosted, uint32_t* pwr_consumption_in_ua ) { sx128x_reg_mod_t reg_mode; - ral_sx128x_bsp_get_reg_mode( context, ®_mode ); - switch( reg_mode ) - { - case SX128X_REG_MODE_DCDC: - { - switch( bw ) - { - case RAL_LORA_BW_200_KHZ: - { - *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_DCDC - : SX128X_LORA_RX_CONSUMPTION_BW_200_DCDC; - return RAL_STATUS_OK; - } - case RAL_LORA_BW_400_KHZ: - { - *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_DCDC - : SX128X_LORA_RX_CONSUMPTION_BW_400_DCDC; - return RAL_STATUS_OK; - } - case RAL_LORA_BW_800_KHZ: - { - *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_DCDC - : SX128X_LORA_RX_CONSUMPTION_BW_800_DCDC; - return RAL_STATUS_OK; - } - case RAL_LORA_BW_1600_KHZ: - { - *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_DCDC - : SX128X_LORA_RX_CONSUMPTION_BW_1600_DCDC; - return RAL_STATUS_OK; - } - default: - return RAL_STATUS_UNKNOWN_VALUE; - } - break; - } - case SX128X_REG_MODE_LDO: - { - switch( bw ) - { - case RAL_LORA_BW_200_KHZ: - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_200_LDO : SX128X_LORA_RX_CONSUMPTION_BW_200_LDO; - return RAL_STATUS_OK; - } - case RAL_LORA_BW_400_KHZ: - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_400_LDO : SX128X_LORA_RX_CONSUMPTION_BW_400_LDO; - return RAL_STATUS_OK; - } - case RAL_LORA_BW_800_KHZ: - { - *pwr_consumption_in_ua = - ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_800_LDO : SX128X_LORA_RX_CONSUMPTION_BW_800_LDO; - return RAL_STATUS_OK; - } - case RAL_LORA_BW_1600_KHZ: - { - *pwr_consumption_in_ua = ( rx_boosted ) ? SX128X_LORA_RX_BOOSTED_CONSUMPTION_BW_1600_LDO - : SX128X_LORA_RX_CONSUMPTION_BW_1600_LDO; - return RAL_STATUS_OK; - } - default: - { - return RAL_STATUS_UNKNOWN_VALUE; - } - } - break; - } - default: - { - return RAL_STATUS_UNKNOWN_VALUE; - } - } + return ral_sx128x_bsp_get_instantaneous_lora_rx_power_consumption( context, reg_mode, bw, rx_boosted, + pwr_consumption_in_ua ); } ral_status_t ral_sx128x_get_random_numbers( const void* context, uint32_t* numbers, unsigned int n ) diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x.h index 34675cf..a2e509b 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x.h @@ -263,6 +263,12 @@ ral_status_t ral_sx128x_set_gfsk_mod_params( const void* context, const ral_gfsk */ ral_status_t ral_sx128x_set_gfsk_pkt_params( const void* context, const ral_gfsk_pkt_params_t* params ); +/** + * @see ral_set_gfsk_pkt_address + */ +ral_status_t ral_sx128x_set_gfsk_pkt_address( const void* context, const uint8_t node_address, + const uint8_t braodcast_address ); + /** * @see ral_set_lora_mod_params */ @@ -350,8 +356,10 @@ ral_status_t ral_sx128x_set_flrc_sync_word( const void* context, const uint8_t* /** * @see ral_set_gfsk_crc_params + * + * @remark RAL Interface declares seed and polynomial as uint32_t but sx128x drivers handles uint16_t only */ -ral_status_t ral_sx128x_set_gfsk_crc_params( const void* context, const uint16_t seed, const uint16_t polynomial ); +ral_status_t ral_sx128x_set_gfsk_crc_params( const void* context, const uint32_t seed, const uint32_t polynomial ); /** * @see ral_set_flrc_crc_params @@ -396,9 +404,8 @@ ral_status_t ral_sx128x_lr_fhss_get_time_on_air_in_ms( const void* context, cons /** * @see ral_lr_fhss_get_hop_sequence_count */ -ral_status_t ral_sx128x_lr_fhss_get_hop_sequence_count( const void* context, - const ral_lr_fhss_params_t* lr_fhss_params, - unsigned int* hop_sequence_count ); +ral_status_t ral_sx128x_lr_fhss_get_hop_sequence_count( const void* context, const ral_lr_fhss_params_t* lr_fhss_params, + unsigned int* hop_sequence_count ); /** * @see ral_lr_fhss_get_bit_delay_in_us diff --git a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x_bsp.h b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x_bsp.h index 5de539a..7913168 100644 --- a/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x_bsp.h +++ b/lbm_lib/smtc_modem_core/smtc_ral/src/ral_sx128x_bsp.h @@ -103,13 +103,52 @@ void ral_sx128x_bsp_get_tx_cfg( const void* context, const ral_sx128x_bsp_tx_cfg /** * @brief Get the Channel Activity Detection (CAD) DetPeak value * + * @param [in] context Chip implementation context * @param [in] sf CAD LoRa spreading factor * @param [in] bw CAD LoRa bandwidth * @param [in] nb_symbol CAD on number of symbols * @param [in out] in_out_cad_det_peak CAD DetPeak value proposed by the ral could be overwritten */ -void ral_sx128x_bsp_get_lora_cad_det_peak( ral_lora_sf_t sf, ral_lora_bw_t bw, ral_lora_cad_symbs_t nb_symbol, - uint8_t* in_out_cad_det_peak ); +void ral_sx128x_bsp_get_lora_cad_det_peak( const void* context, ral_lora_sf_t sf, ral_lora_bw_t bw, + ral_lora_cad_symbs_t nb_symbol, uint8_t* in_out_cad_det_peak ); + +/** + * @brief Get the instantaneous power consumption for the given Tx configuration + * + * @param [in] context Chip implementation context + * @param [in] tx_cfg_output_params_local The Tx configuration + * @param [in] reg_mode The regulator configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx128x_bsp_get_instantaneous_tx_power_consumption(const void* context, + ral_sx128x_bsp_tx_cfg_output_params_t tx_cfg_output_params_local, sx128x_reg_mod_t reg_mode, + uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given GFSK Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] radio_reg_mode The regulator configuration + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx128x_bsp_get_instantaneous_gfsk_rx_power_consumption( const void* context, + sx128x_reg_mod_t radio_reg_mode, bool rx_boosted, uint32_t* pwr_consumption_in_ua ); + +/** + * @brief Get the instantaneous power consumption for the given LoRa Rx configuration + * + * @param [in] context Chip implementation context + * @param [in] reg_mode The regulator configuration + * @param [in] bw The LoRa bandwidth configured + * @param [in] rx_boosted The Rx boosted configuration + * @param [out] pwr_consumption_in_ua The corresponding instantaneous power consumption + * @return ral_status_t + */ +ral_status_t ral_sx128x_bsp_get_instantaneous_lora_rx_power_consumption( const void* context, + sx128x_reg_mod_t reg_mode, ral_lora_bw_t bw, bool rx_boosted, uint32_t* pwr_consumption_in_ua ); #ifdef __cplusplus } diff --git a/lbm_lib/smtc_modem_core/smtc_ralf/src/ralf_sx127x_bsp.h b/lbm_lib/smtc_modem_core/smtc_ralf/src/ralf_sx127x_bsp.h index 568ce5f..2f1cc35 100644 --- a/lbm_lib/smtc_modem_core/smtc_ralf/src/ralf_sx127x_bsp.h +++ b/lbm_lib/smtc_modem_core/smtc_ralf/src/ralf_sx127x_bsp.h @@ -3,11 +3,12 @@ * * @brief RALF Board Support Package. * - * Revised BSD License + * The Clear BSD License * Copyright Semtech Corporation 2021. All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted (subject to the limitations in the disclaimer + * below) provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright @@ -17,16 +18,18 @@ * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef RALF_SX127X_BSP_H__ diff --git a/lbm_lib/smtc_modem_hal/CHANGELOG.md b/lbm_lib/smtc_modem_hal/CHANGELOG.md index 196518c..5448918 100644 --- a/lbm_lib/smtc_modem_hal/CHANGELOG.md +++ b/lbm_lib/smtc_modem_hal/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v4.8.0] 2024-12-20 + +### Changed + +* [radio_irq] `smtc_modem_hal_radio_irq_clear_pending()` function has been removed + ## [v4.3.0] 2023-12-15 ### Added @@ -16,15 +22,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * Re-add Device Management related functions `smtc_modem_hal_get_temperature` and `smtc_modem_hal_get_voltage_mv` * Add `smtc_modem_hal_user_lbm_irq` function for Real Time OS compatibility - ### Changed * `smtc_modem_hal_on_panic` prototype changed to add variadic arguments -* `SMTC_MODEM_HAL_PANIC` macro implentation does not handle the error trace print directetly and relay on `smtc_modem_hal_on_panic` to handle it +* `SMTC_MODEM_HAL_PANIC` macro implementation does not handle the error trace print directly and relay on `smtc_modem_hal_on_panic` to handle it * `SMTC_MODEM_HAL_PANIC_ON_FAILURE` macro implementation forwards now the failed expression string to `smtc_modem_hal_on_panic` function * `CONTEXT_MODEM` is not used anymore to store key crc in case lr11xx crypto element is used - ## [v4.0.0] 2023-03-10 ### Added @@ -33,7 +37,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * `SMTC_MODEM_HAL_PANIC_ON_FAILURE` macro for any internal modem panic on expression check * [context] New context type `CONTEXT_FUOTA` for fuota in `modem_context_type_t` - ### Changed * `smtc_modem_hal_assert_fail` has been replaced by `smtc_modem_hal_on_panic` function @@ -42,7 +45,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * add `offset` argument for `smtc_modem_hal_context_restore` * add `offset` argument for `smtc_modem_hal_context_store` - ### Removed * `smtc_modem_hal_get_temperature` function @@ -77,7 +79,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Removed - ## [v2.1.0] 2021-09-24 ### Added diff --git a/lbm_lib/smtc_modem_hal/smtc_modem_hal.h b/lbm_lib/smtc_modem_hal/smtc_modem_hal.h index b9a0e76..01267d7 100644 --- a/lbm_lib/smtc_modem_hal/smtc_modem_hal.h +++ b/lbm_lib/smtc_modem_hal/smtc_modem_hal.h @@ -153,7 +153,7 @@ uint32_t smtc_modem_hal_get_time_in_s( void ); uint32_t smtc_modem_hal_get_time_in_ms( void ); /** - * @brief set an offset into the rtc ounter + * @brief set an offset into the rtc counter * * @remark Used for debug purpose such as wrapping issue. * @@ -265,11 +265,6 @@ uint32_t smtc_modem_hal_get_random_nb_in_range( const uint32_t val_1, const uint */ void smtc_modem_hal_irq_config_radio_irq( void ( *callback )( void* context ), void* context ); -/* - * @brief Clear any MCU-layer pending radio IRQ flags - */ -void smtc_modem_hal_radio_irq_clear_pending( void ); - /** * @brief Start radio tcxo * @@ -305,6 +300,12 @@ void smtc_modem_hal_set_ant_switch( bool is_tx_on ); /** * @brief Return the battery level * + * @remark + * Please implement according to used board + * According to LoRaWan 1.0.4 spec: + * 0: The end-device is connected to an external power source. + * 1..254: Battery level, where 1 is the minimum and 254 is the maximum. + * 255: The end-device was not able to measure the battery level. * @return uint8_t Battery level for lorawan stack */ uint8_t smtc_modem_hal_get_battery_level( void ); diff --git a/zephyr/module.yml b/zephyr/module.yml new file mode 100644 index 0000000..b5d4f5a --- /dev/null +++ b/zephyr/module.yml @@ -0,0 +1,7 @@ + +build: + # Path to the Kconfig file that will be sourced into Zephyr Kconfig tree under + # Zephyr > Modules > example-application. Path is relative from root of this + # repository. + kconfig-ext: true + cmake-ext: true