diff --git a/CHANGELOG.md b/CHANGELOG.md index f4337a8..db453df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * Add user access to the beacon statistics data with `smtc_modem_class_b_beacon_get_statistics` function. * Add user access to the `smtc_modem_factory_reset` function. * Add support for 2.4 Ghz multicast class C session frequency setting. +* Add support over SMTC modem API to set LoRaWAN uplink dwell time restriction. +* Add support over SMTC modem API to lock LoRaWAN uplink dwell time against network changes via `TxParamSetupReq`. ### Changed diff --git a/lbm_lib/smtc_modem_api/smtc_modem_api.h b/lbm_lib/smtc_modem_api/smtc_modem_api.h index b016f5c..0fb612f 100755 --- a/lbm_lib/smtc_modem_api/smtc_modem_api.h +++ b/lbm_lib/smtc_modem_api/smtc_modem_api.h @@ -1314,6 +1314,43 @@ smtc_modem_return_code_t smtc_modem_get_adr_ack_limit_delay( uint8_t stack_id, u smtc_modem_return_code_t smtc_modem_set_join_start_bank( uint8_t stack_id, uint8_t start_bank, uint8_t* p_bank_count); + +/** + * @brief Set the uplink dwell time value + * + * @param [in] stack_id Stack identifier + * @param [in] dwell_time Determines if uplink dwell time is enabled + * + * @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_INVALID_STACK_ID Invalid \p stack_id + */ +smtc_modem_return_code_t smtc_modem_set_uplink_dwell_time( + uint8_t stack_id, bool dwell_time); + +/** + * @brief Lock or unlock the uplink dwell time value against network changes. + * + * @remark When locked, TxParamSetupReq MAC commands received from the network + * attempting to change uplink dwell time are ignored. + * + * @remark Only applicable to regions supporting TxParamSetupReq. + * Returns SMTC_MODEM_RC_INVALID for other regions. + * + * @param [in] stack_id Stack identifier + * @param [in] locked true = lock value, ignore network TxParamSetupReq + * false = unlock, network can change via TxParamSetupReq + * + * @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_INVALID Region does not support TxParamSetupReq + * @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_set_uplink_dwell_time_locked( + uint8_t stack_id, bool locked ); + /* * ----------------------------------------------------------------------------- * ----------- BOARD MANAGEMENT MODEM FUNCTIONS -------------------------------- 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 402b86e..570f73f 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 @@ -2287,8 +2287,25 @@ static void tx_param_setup_parser( lr1_stack_mac_t* lr1_mac ) 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 ); + + /* Extract uplink dwell time bits from TxParamSetupReq payload byte */ + bool network_uplink_dwell = + ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + 1] & 0x10 ) >> 4; + + /* Apply uplink dwell time only if dwell time locked is disabled. + When enabled, the application has locked the value via + smtc_modem_set_uplink_dwell_time_locked and network requests are ignored. */ + if( !lr1_mac->real->real_ctx.uplink_dwell_time_locked ) + { + smtc_real_set_uplink_dwell_time( lr1_mac->real, network_uplink_dwell); + } + else + { + SMTC_MODEM_HAL_TRACE_WARNING( + "TxParamSetupReq: uplink_dwell=%d ignored, dwell time locked enabled\n", + network_uplink_dwell ); + } + smtc_real_set_downlink_dwell_time( lr1_mac->real, ( lr1_mac->nwk_payload[lr1_mac->nwk_payload_index + 1] & 0x20 ) >> 5 ); 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 72745a7..8cc50ef 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 @@ -99,6 +99,7 @@ #define uplink_dwell_time_ctx real_ctx.uplink_dwell_time_ctx #define downlink_dwell_time_ctx real_ctx.downlink_dwell_time_ctx #define join_start_bank_tx_mask real_ctx.join_start_bank_tx_mask +#define uplink_dwell_time_locked real_ctx.uplink_dwell_time_locked smtc_real_status_t smtc_real_is_supported_region( smtc_real_region_types_t region_type ) { @@ -208,6 +209,7 @@ void smtc_real_init( smtc_real_t* real, smtc_real_region_types_t region_type ) real_ctx.sync_word_ctx = real_const.const_sync_word_public; join_start_bank_tx_mask = 0; + uplink_dwell_time_locked = false; } void smtc_real_config( smtc_real_t* real ) @@ -287,6 +289,7 @@ void smtc_real_config( smtc_real_t* real ) uplink_dwell_time_ctx = real_const.const_uplink_dwell_time; downlink_dwell_time_ctx = false; + uplink_dwell_time_locked = false; } void smtc_real_config_session( smtc_real_t* real ) @@ -2891,6 +2894,7 @@ uint8_t smtc_real_get_ping_slot_datarate( smtc_real_t* real ) void smtc_real_set_uplink_dwell_time( smtc_real_t* real, bool dwell_time ) { uplink_dwell_time_ctx = dwell_time; + SMTC_MODEM_HAL_TRACE_INFO( "Dwell time update = %d\n", dwell_time ); } void smtc_real_set_downlink_dwell_time( smtc_real_t* real, bool dwell_time ) diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real_defs.h b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real_defs.h index 2be1630..3235ebe 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real_defs.h +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/smtc_real_defs.h @@ -237,6 +237,7 @@ typedef struct smtc_real_ctx_s bool uplink_dwell_time_ctx; bool downlink_dwell_time_ctx; uint8_t join_start_bank_tx_mask; + bool uplink_dwell_time_locked; } smtc_real_ctx_t; typedef struct smtc_real_const_s diff --git a/lbm_lib/smtc_modem_core/smtc_modem.c b/lbm_lib/smtc_modem_core/smtc_modem.c index 8426174..9dccb99 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem.c +++ b/lbm_lib/smtc_modem_core/smtc_modem.c @@ -115,6 +115,8 @@ #include "aes.h" #endif // USE_LR11XX_CE && ( ADD_FUOTA == 2 ) +#include "smtc_real.h" + /* * ----------------------------------------------------------------------------- * --- PRIVATE MACROS----------------------------------------------------------- @@ -1441,6 +1443,55 @@ smtc_modem_return_code_t smtc_modem_set_join_start_bank( uint8_t stack_id, return SMTC_MODEM_RC_OK; } +smtc_modem_return_code_t smtc_modem_set_uplink_dwell_time( + uint8_t stack_id, bool dwell_time) +{ + RETURN_BUSY_IF_TEST_MODE( ); + + lr1_stack_mac_t* stack_mac = lorawan_api_stack_mac_get( stack_id ); + if( stack_mac == NULL ) + { + return SMTC_MODEM_RC_INVALID_STACK_ID; + } + + /* Dwell time is only valid for regions that support TxParamSetupReq. + Enabling dwell time on unsupported regions (e.g. EU868) causes a + errors in SMTC real functions. */ + if( smtc_real_is_tx_param_setup_req_supported( stack_mac->real ) == false ) + { + SMTC_MODEM_HAL_TRACE_WARNING( + "Region does not support TxParamSetupReq, ignoring dwell time set request\n" ); + return SMTC_MODEM_RC_INVALID; + } + + smtc_real_set_uplink_dwell_time( stack_mac->real, dwell_time ); + return SMTC_MODEM_RC_OK; +} + +smtc_modem_return_code_t smtc_modem_set_uplink_dwell_time_locked( + uint8_t stack_id, bool locked) +{ + RETURN_BUSY_IF_TEST_MODE( ); + + lr1_stack_mac_t* stack_mac = lorawan_api_stack_mac_get( stack_id ); + if( stack_mac == NULL ) + { + return SMTC_MODEM_RC_INVALID_STACK_ID; + } + + /* Unsupported locking network control for regions that don't support + receiving TxParamSetupReq anyway. */ + if( smtc_real_is_tx_param_setup_req_supported( stack_mac->real ) == false ) + { + SMTC_MODEM_HAL_TRACE_WARNING( + "Region does not support TxParamSetupReq, ignoring uplink dwell time locked set request\n" ); + return SMTC_MODEM_RC_INVALID; + } + + stack_mac->real->real_ctx.uplink_dwell_time_locked = locked; + return SMTC_MODEM_RC_OK; +} + /* * ----------------------------------------------------------------------------- * ----------- BOARD MANAGEMENT MODEM FUNCTIONS --------------------------------