diff --git a/CHANGELOG.md b/CHANGELOG.md index 428a1d0e..f4337a8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * Add user access to the `smtc_modem_factory_reset` function. * Add support for 2.4 Ghz multicast class C session frequency setting. +### Changed + +* Starting join bank can be set over SMTC modem API for regions that support this (AU915, US915) +* Subsequent join attempts cycle through all banks for regions that support this (AU915, US915) + ## [v4.8.0] 2024-12-20 This version is based on feature branch v4.5.0 of the LoRa Basics Modem. diff --git a/lbm_lib/smtc_modem_api/smtc_modem_api.h b/lbm_lib/smtc_modem_api/smtc_modem_api.h index bd131915..b016f5cf 100755 --- a/lbm_lib/smtc_modem_api/smtc_modem_api.h +++ b/lbm_lib/smtc_modem_api/smtc_modem_api.h @@ -1289,6 +1289,31 @@ smtc_modem_return_code_t smtc_modem_set_adr_ack_limit_delay( uint8_t stack_id, u smtc_modem_return_code_t smtc_modem_get_adr_ack_limit_delay( uint8_t stack_id, uint8_t* adr_ack_limit, uint8_t* adr_ack_delay ); +/** + * @brief Set the starting bank for join channel cycling + * + * @remark Join attempts cycle through banks sequentially, + * picking one random channel per bank on each attempt. This + * setting controls which bank the cycle starts from or join failure + * reset occurs. It also sets number of banks supported for used + * region. Only applicable to regions that use channel banks to + * choose next channel for join request (AU915, US915). + * Returns SMTC_MODEM_RC_INVALID for other regions or invalid bank. + * Default is 0 (LoRaWAN spec default). + * + * @param [in] stack_id Stack identifier + * @param [in] start_bank Starting bank index + * @param [in] p_bank_count Pointer to set value of number of banks supported + * + * @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 Invalid bank or unsupported region + * @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_join_start_bank( uint8_t stack_id, + uint8_t start_bank, + uint8_t* p_bank_count); /* * ----------------------------------------------------------------------------- * ----------- BOARD MANAGEMENT MODEM FUNCTIONS -------------------------------- diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.c index 648b05f1..935adb0e 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_au_915.c @@ -166,7 +166,7 @@ void region_au_915_init( smtc_real_t* real ) memset( &unwrapped_channel_mask[0], 0xFF, BANK_MAX_AU915 ); memset( &snapshot_channel_tx_mask[0], 0xFF, BANK_MAX_AU915 ); - snapshot_bank_tx_mask = 0; + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; } void region_au_915_config( smtc_real_t* real ) @@ -453,7 +453,7 @@ void region_au_915_set_channel_mask( smtc_real_t* real ) void region_au_915_init_join_snapshot_channel_mask( smtc_real_t* real ) { memset( snapshot_channel_tx_mask, 0xFF, BANK_MAX_AU915 ); - snapshot_bank_tx_mask = 0; + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; } void region_au_915_init_after_join_snapshot_channel_mask( smtc_real_t* real, uint8_t tx_data_rate, diff --git a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c index 8d1bfb4d..97c9c1e2 100644 --- a/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c +++ b/lbm_lib/smtc_modem_core/lr1mac/src/smtc_real/src/region_us_915.c @@ -164,7 +164,7 @@ void region_us_915_init( smtc_real_t* real ) memset( &unwrapped_channel_mask[0], 0xFF, BANK_MAX_US915 ); memset( &snapshot_channel_tx_mask[0], 0xFF, BANK_MAX_US915 ); - snapshot_bank_tx_mask = 0; + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; } void region_us_915_config( smtc_real_t* real ) @@ -450,7 +450,7 @@ void region_us_915_set_channel_mask( smtc_real_t* real ) void region_us_915_init_join_snapshot_channel_mask( smtc_real_t* real ) { memset( snapshot_channel_tx_mask, 0xFF, BANK_MAX_US915 ); - snapshot_bank_tx_mask = 0; + snapshot_bank_tx_mask = real_ctx.join_start_bank_tx_mask; } void region_us_915_init_after_join_snapshot_channel_mask( smtc_real_t* real, uint8_t tx_data_rate, 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 f2fbe59d..72745a70 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 @@ -98,6 +98,7 @@ #define custom_dr_distribution_init_ctx real_ctx.custom_dr_distribution_init_ctx #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 smtc_real_status_t smtc_real_is_supported_region( smtc_real_region_types_t region_type ) { @@ -206,6 +207,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; } void smtc_real_config( smtc_real_t* real ) 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 5f497975..2be1630e 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 @@ -236,6 +236,7 @@ typedef struct smtc_real_ctx_s uint8_t sync_word_ctx; bool uplink_dwell_time_ctx; bool downlink_dwell_time_ctx; + uint8_t join_start_bank_tx_mask; } 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 fac6a25e..84261749 100644 --- a/lbm_lib/smtc_modem_core/smtc_modem.c +++ b/lbm_lib/smtc_modem_core/smtc_modem.c @@ -1404,6 +1404,43 @@ smtc_modem_return_code_t smtc_modem_get_adr_ack_limit_delay( uint8_t stack_id, u return SMTC_MODEM_RC_OK; } +smtc_modem_return_code_t smtc_modem_set_join_start_bank( uint8_t stack_id, + uint8_t start_bank, + uint8_t* p_bank_count) +{ + 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; + } + + /* Only regions with channel banks support this setting */ + if( (stack_mac->real->region_type != SMTC_REAL_REGION_AU_915) && + (stack_mac->real->region_type != SMTC_REAL_REGION_US_915) ) + { + SMTC_MODEM_HAL_TRACE_WARNING( + "smtc_modem_set_join_start_bank: region does not support " + "channel bank cycling\n" ); + return SMTC_MODEM_RC_INVALID; + } + + /* Validate bank index against region's bank count */ + if( start_bank >= stack_mac->real->real_const.const_number_of_channel_bank ) + { + SMTC_MODEM_HAL_TRACE_WARNING( + "smtc_modem_set_join_start_bank: invalid bank %d for region, " + "max is %d\n", start_bank, + stack_mac->real->real_const.const_number_of_channel_bank - 1); + return SMTC_MODEM_RC_INVALID; + } + + *p_bank_count = stack_mac->real->real_const.const_number_of_channel_bank; + stack_mac->real->real_ctx.join_start_bank_tx_mask = start_bank; + return SMTC_MODEM_RC_OK; +} + /* * ----------------------------------------------------------------------------- * ----------- BOARD MANAGEMENT MODEM FUNCTIONS --------------------------------