Replace exponential_backoff with submodule to FreeRTOS/backoffAlgorithm (#419)

A new repository, FreeRTOS/backoffAlgorithm, has been created for hosting the library for backoff calculation. This repo replaces the FreeRTOS-Plus/Source/Utilities/exponential_backoff with the submodule to the new repository, and updates all the demos that use retry logic to use the backoffAlgorithm API
This commit is contained in:
Archit Aggarwal
2020-11-24 14:54:31 -08:00
committed by GitHub
parent 5ba1e4cf95
commit 036ec83b65
33 changed files with 699 additions and 554 deletions

3
.gitmodules vendored
View File

@ -34,3 +34,6 @@
[submodule "FreeRTOS-Plus/Source/Application-Protocols/coreHTTP"]
path = FreeRTOS-Plus/Source/Application-Protocols/coreHTTP
url = https://github.com/FreeRTOS/coreHTTP
[submodule "FreeRTOS-Plus/Source/Utilities/backoff_algorithm"]
path = FreeRTOS-Plus/Source/Utilities/backoff_algorithm
url = https://github.com/FreeRTOS/backoffAlgorithm.git

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\..\..\Common\WinPCap;..\..\..\..\..\FreeRTOS\Source\include;..\..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Utilities\exponential_backoff;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\..\Source\mbedtls_utils;..\..\..\..\ThirdParty\mbedtls\include;..\..\..\..\Source\AWS\device-defender\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\Mqtt_Demo_Helpers;..\..\..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\..\..\Common\WinPCap;..\..\..\..\..\FreeRTOS\Source\include;..\..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\..\Source\mbedtls_utils;..\..\..\..\ThirdParty\mbedtls\include;..\..\..\..\Source\AWS\device-defender\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\Mqtt_Demo_Helpers;..\..\..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MBEDTLS_CONFIG_FILE="mbedtls_config.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -160,7 +160,7 @@
<ClCompile Include="..\..\..\..\Source\FreeRTOS-Plus-TCP\tools\tcp_utilities\tcp_netstat.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_freertos_port.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
@ -528,7 +528,7 @@
<ClInclude Include="..\..\..\..\Source\Utilities\mbedtls_freertos\threading_alt.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.h" />
<ClInclude Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />

View File

@ -152,7 +152,7 @@
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\freertos</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c">
@ -500,7 +500,7 @@
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="mbedtls_config.h" />

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\..\..\Common\WinPCap;..\..\..\..\..\FreeRTOS\Source\include;..\..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Utilities\exponential_backoff;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\..\Source\mbedtls_utils;..\..\..\..\ThirdParty\mbedtls\include;..\..\..\..\Source\AWS\device-shadow\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\Mqtt_Demo_Helpers;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\..\..\Common\WinPCap;..\..\..\..\..\FreeRTOS\Source\include;..\..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\..\Source\mbedtls_utils;..\..\..\..\ThirdParty\mbedtls\include;..\..\..\..\Source\AWS\device-shadow\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\Mqtt_Demo_Helpers;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MBEDTLS_CONFIG_FILE="mbedtls_config.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -159,7 +159,7 @@
<ClCompile Include="..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_freertos_port.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
@ -523,7 +523,7 @@
<ClInclude Include="..\..\..\..\Source\Utilities\mbedtls_freertos\threading_alt.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.h" />
<ClInclude Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />

View File

@ -156,7 +156,7 @@
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\freertos</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c">
@ -504,7 +504,7 @@
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="mbedtls_config.h" />

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\..\..\Common\WinPCap;..\..\..\..\..\FreeRTOS\Source\include;..\..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Utilities\exponential_backoff;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\..\Source\mbedtls_utils;..\..\..\..\ThirdParty\mbedtls\include;..\..\..\..\Source\AWS\jobs\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\Mqtt_Demo_Helpers;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\..\..\Common\WinPCap;..\..\..\..\..\FreeRTOS\Source\include;..\..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\..\Source\mbedtls_utils;..\..\..\..\ThirdParty\mbedtls\include;..\..\..\..\Source\AWS\jobs\source\include;..\..\..\..\Source\coreJSON\source\include;..\..\Mqtt_Demo_Helpers;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MBEDTLS_CONFIG_FILE="mbedtls_config.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -159,7 +159,7 @@
<ClCompile Include="..\..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_freertos_port.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c" />
<ClCompile Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
@ -523,7 +523,7 @@
<ClInclude Include="..\..\..\..\Source\Utilities\mbedtls_freertos\threading_alt.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.h" />
<ClInclude Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />

View File

@ -156,7 +156,7 @@
<ClCompile Include="..\..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\freertos</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c">
@ -504,7 +504,7 @@
<ClInclude Include="..\..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="mbedtls_config.h" />

View File

@ -51,7 +51,7 @@
#include "core_mqtt.h"
/* Exponential backoff retry include. */
#include "exponential_backoff.h"
#include "backoff_algorithm.h"
/* Transport interface implementation include header for TLS. */
#include "using_mbedtls.h"
@ -84,6 +84,23 @@
/*-----------------------------------------------------------*/
/**
* @brief The maximum number of retries for network operation with server.
*/
#define RETRY_MAX_ATTEMPTS ( 5U )
/**
* @brief The maximum back-off delay (in milliseconds) for retrying failed operation
* with server.
*/
#define RETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
/**
* @brief The base back-off delay (in milliseconds) to use for network operation retry
* attempts.
*/
#define RETRY_BACKOFF_BASE_MS ( 500U )
/**
* @brief Timeout for receiving CONNACK packet in milliseconds.
*/
@ -220,6 +237,22 @@ static PublishPackets_t outgoingPublishPackets[ MAX_OUTGOING_PUBLISHES ] = { 0 }
/*-----------------------------------------------------------*/
/**
* @brief A wrapper to the "uxRand()" random number generator so that it
* can be passed to the backoffAlgorithm library for retry logic.
*
* This function implements the #BackoffAlgorithm_RNG_T type interface
* in the backoffAlgorithm library API.
*
* @note The "uxRand" function represents a pseudo random number generator.
* However, it is recommended to use a True Randon Number Generator (TRNG)
* for generating unique device-specific random values to avoid possibility
* of network collisions from multiple devices retrying network operations.
*
* @return The generated randon number. This function ALWAYS succeeds.
*/
static int32_t prvGenerateRandomNumber();
/**
* @brief Connect to MQTT broker with reconnection retries.
*
@ -285,12 +318,20 @@ static uint32_t prvGetTimeMs( void );
/*-----------------------------------------------------------*/
static int32_t prvGenerateRandomNumber()
{
return( uxRand() & INT32_MAX );
}
/*-----------------------------------------------------------*/
static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkContext_t * pxNetworkContext )
{
TlsTransportStatus_t xNetworkStatus = TLS_TRANSPORT_SUCCESS;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xReconnectParams = { 0 };
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xReconnectParams = { 0 };
NetworkCredentials_t xNetworkCredentials = { 0 };
uint16_t usNextRetryBackOff = 0U;
/* ALPN protocols must be a NULL-terminated list of strings. Therefore,
* the first entry will contain the actual ALPN protocol string while the
@ -318,9 +359,15 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkContext
#endif
xNetworkCredentials.pAlpnProtos = pcAlpnProtocols;
/* Initialize reconnect attempts and interval. */
RetryUtils_ParamsReset( &xReconnectParams );
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize reconnect attempts and interval.
* Note: This utility uses a pseudo random number generator for use with the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying connection. */
BackoffAlgorithm_InitializeParams( &xReconnectParams,
RETRY_BACKOFF_BASE_MS,
RETRY_MAX_BACKOFF_DELAY_MS,
RETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
/* Attempt to connect to MQTT broker. If connection fails, retry after
* a timeout. Timeout value will exponentially increase until maximum
@ -343,16 +390,22 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkContext
if( xNetworkStatus != TLS_TRANSPORT_SUCCESS )
{
LogWarn( ( "Connection to the broker failed. Retrying connection with backoff and jitter." ) );
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
}
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xReconnectParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xRetryUtilsStatus == RetryUtilsRetriesExhausted )
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Connection to the broker failed, all attempts exhausted." ) );
xNetworkStatus = TLS_TRANSPORT_CONNECT_FAILURE;
}
} while( ( xNetworkStatus != TLS_TRANSPORT_SUCCESS ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Connection to the broker failed. "
"Retrying connection with backoff and jitter." ) );
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
}
} while( ( xNetworkStatus != TLS_TRANSPORT_SUCCESS ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
return xNetworkStatus;
}

View File

@ -26,7 +26,7 @@
#include "http_demo_utils.h"
/* Exponential backoff retry include. */
#include "exponential_backoff.h"
#include "backoff_algorithm.h"
/* Parser utilities. */
#include "http_parser.h"
@ -38,15 +38,18 @@ BaseType_t connectToServerWithBackoffRetries( TransportConnect_t connectFunction
{
BaseType_t xReturn = pdFAIL;
/* Status returned by the retry utilities. */
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
/* Struct containing the next backoff time. */
RetryUtilsParams_t xReconnectParams;
BackoffAlgorithmContext_t xReconnectParams;
assert( connectFunction != NULL );
/* Initialize reconnect attempts and interval */
RetryUtils_ParamsReset( &xReconnectParams );
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
BackoffAlgorithm_InitializeParams( &xReconnectParams,
RETRY_BACKOFF_BASE_MS,
RETRY_MAX_BACKOFF_DELAY_MS,
RETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
/* Attempt to connect to the HTTP server. If connection fails, retry after a
* timeout. The timeout value will exponentially increase until either the
@ -63,9 +66,9 @@ BaseType_t connectToServerWithBackoffRetries( TransportConnect_t connectFunction
LogInfo( ( "Retry attempt %lu out of maximum retry attempts %lu.",
( xReconnectParams.attemptsDone + 1 ),
MAX_RETRY_ATTEMPTS ) );
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xReconnectParams, &usNextBackoff );
}
} while( ( xReturn == pdFAIL ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
} while( ( xReturn == pdFAIL ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
if( xReturn == pdFAIL )
{

View File

@ -54,7 +54,7 @@
#include "core_mqtt.h"
/* Exponential backoff retry include. */
#include "exponential_backoff.h"
#include "backoff_algorithm.h"
/* Transport interface implementation include header for TLS. */
#include "using_mbedtls.h"
@ -97,6 +97,23 @@
/*-----------------------------------------------------------*/
/**
* @brief The maximum number of retries for network operation with server.
*/
#define mqttexampleRETRY_MAX_ATTEMPTS ( 5U )
/**
* @brief The maximum back-off delay (in milliseconds) for retrying failed operation
* with server.
*/
#define mqttexampleRETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
/**
* @brief The base back-off delay (in milliseconds) to use for network operation retry
* attempts.
*/
#define mqttexampleRETRY_BACKOFF_BASE_MS ( 500U )
/**
* @brief Timeout for receiving CONNACK packet in milliseconds.
*/
@ -176,6 +193,22 @@
*/
static void prvMQTTDemoTask( void * pvParameters );
/**
* @brief A wrapper to the "uxRand()" random number generator so that it
* can be passed to the backoffAlgorithm library for retry logic.
*
* This function implements the #BackoffAlgorithm_RNG_T type interface
* in the backoffAlgorithm library API.
*
* @note The "uxRand" function represents a pseudo random number generator.
* However, it is recommended to use a True Randon Number Generator (TRNG)
* for generating unique device-specific random values to avoid possibility
* of network collisions from multiple devices retrying network operations.
*
* @return The generated randon number. This function ALWAYS succeeds.
*/
static int32_t prvGenerateRandomNumber();
/**
* @brief Connect to MQTT broker with reconnection retries.
*
@ -407,7 +440,7 @@ static void prvMQTTDemoTask( void * pvParameters )
/* If the server rejected the subscription request, attempt to resubscribe to the
* topic. Attempts are made according to the exponential backoff retry strategy
* implemented in retryUtils. */
* implemented in BackoffAlgorithm. */
prvMQTTSubscribeWithBackoffRetries( &xMQTTContext );
/* Process incoming packet from the broker. After sending a subscribe packet, the
@ -475,20 +508,35 @@ static void prvMQTTDemoTask( void * pvParameters )
}
/*-----------------------------------------------------------*/
static int32_t prvGenerateRandomNumber()
{
return( uxRand() & INT32_MAX );
}
/*-----------------------------------------------------------*/
static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredentials_t * pxNetworkCredentials,
NetworkContext_t * pxNetworkContext )
{
TlsTransportStatus_t xNetworkStatus;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xReconnectParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xReconnectParams;
uint16_t usNextRetryBackOff = 0U;
/* Set the credentials for establishing a TLS connection. */
pxNetworkCredentials->pRootCa = ( const unsigned char * ) democonfigROOT_CA_PEM;
pxNetworkCredentials->rootCaSize = sizeof( democonfigROOT_CA_PEM );
pxNetworkCredentials->disableSni = democonfigDISABLE_SNI;
/* Initialize reconnect attempts and interval. */
RetryUtils_ParamsReset( &xReconnectParams );
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize reconnect attempts and interval.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying connection. */
BackoffAlgorithm_InitializeParams( &xReconnectParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNum );
/* Attempt to connect to the MQTT broker. If connection fails, retry after
* a timeout. Timeout value will exponentially increase until maximum
@ -512,16 +560,22 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredent
if( xNetworkStatus != TLS_TRANSPORT_SUCCESS )
{
LogWarn( ( "Connection to the broker failed. Retrying connection with backoff and jitter." ) );
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
}
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xReconnectParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xRetryUtilsStatus == RetryUtilsRetriesExhausted )
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Connection to the broker failed, all attempts exhausted." ) );
xNetworkStatus = TLS_TRANSPORT_CONNECT_FAILURE;
}
} while( ( xNetworkStatus != TLS_TRANSPORT_SUCCESS ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Connection to the broker failed. "
"Retrying connection with backoff and jitter." ) );
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
}
} while( ( xNetworkStatus != TLS_TRANSPORT_SUCCESS ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
return xNetworkStatus;
}
@ -605,8 +659,9 @@ static void prvUpdateSubAckStatus( MQTTPacketInfo_t * pxPacketInfo )
static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
{
MQTTStatus_t xResult = MQTTSuccess;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xRetryParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xRetryParams;
uint16_t usNextRetryBackOff = 0U;
MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ];
bool xFailedSubscribeToTopic = false;
uint32_t ulTopicCount = 0U;
@ -623,9 +678,15 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC;
xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );
/* Initialize retry attempts and interval. */
RetryUtils_ParamsReset( &xRetryParams );
xRetryParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize context for backoff retry attempts if SUBSCRIBE request fails.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying network operations. */
BackoffAlgorithm_InitializeParams( &xRetryParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNum );
do
{
@ -665,17 +726,32 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ )
{
if( xTopicFilterContext[ ulTopicCount ].xSubAckStatus == MQTTSubAckFailure )
{
xFailedSubscribeToTopic = true;
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xRetryParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Server rejected subscription request. All retry attempts have exhausted. Topic=%s",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
}
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Server rejected subscription request. Attempting to re-subscribe to topic %s.",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
xFailedSubscribeToTopic = true;
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xRetryParams );
/* Backoff before the next re-subscribe attempt. */
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
break;
}
}
configASSERT( xRetryUtilsStatus != RetryUtilsRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
}
/*-----------------------------------------------------------*/

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\exponential_backoff;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\Source\mbedtls_utils;..\..\..\ThirdParty\mbedtls\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\Source\mbedtls_utils;..\..\..\ThirdParty\mbedtls\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MBEDTLS_CONFIG_FILE="mbedtls_config.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -159,7 +159,7 @@
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_freertos_port.c" />
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c" />
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
@ -520,7 +520,7 @@
<ClInclude Include="..\..\..\Source\Utilities\mbedtls_freertos\threading_alt.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.h" />
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />

View File

@ -393,7 +393,7 @@
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\freertos</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c">
@ -489,7 +489,7 @@
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\ThirdParty\mbedtls\include\mbedtls\aes.h">

View File

@ -57,7 +57,7 @@
#include "core_mqtt.h"
/* Exponential backoff retry include. */
#include "exponential_backoff.h"
#include "backoff_algorithm.h"
/* Transport interface include. */
#include "using_plaintext.h"
@ -97,6 +97,23 @@
/*-----------------------------------------------------------*/
/**
* @brief The maximum number of retries for network operation with server.
*/
#define mqttexampleRETRY_MAX_ATTEMPTS ( 5U )
/**
* @brief The maximum back-off delay (in milliseconds) for retrying failed operation
* with server.
*/
#define mqttexampleRETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
/**
* @brief The base back-off delay (in milliseconds) to use for network operation retry
* attempts.
*/
#define mqttexampleRETRY_BACKOFF_BASE_MS ( 500U )
/**
* @brief Timeout for receiving CONNACK packet in milliseconds.
*/
@ -198,6 +215,22 @@
*/
static void prvMQTTDemoTask( void * pvParameters );
/**
* @brief A wrapper to the "uxRand()" random number generator so that it
* can be passed to the backoffAlgorithm library for retry logic.
*
* This function implements the #BackoffAlgorithm_RNG_T type interface
* in the backoffAlgorithm library API.
*
* @note The "uxRand" function represents a pseudo random number generator.
* However, it is recommended to use a True Randon Number Generator (TRNG)
* for generating unique device-specific random values to avoid possibility
* of network collisions from multiple devices retrying network operations.
*
* @return The generated randon number. This function ALWAYS succeeds.
*/
static int32_t prvGenerateRandomNumber();
/**
* @brief Connect to MQTT broker with reconnection retries.
*
@ -508,7 +541,7 @@ static void prvMQTTDemoTask( void * pvParameters )
/* If the server rejected the subscription request, attempt to resubscribe
* to the topic. Attempts are made according to the exponential backoff retry
* strategy declared in exponential_backoff.h. */
* strategy declared in backoff_algorithm.h. */
prvMQTTSubscribeWithBackoffRetries( &xMQTTContext );
/************************ Send PINGREQ packet. ************************/
@ -601,15 +634,29 @@ static void prvMQTTDemoTask( void * pvParameters )
}
/*-----------------------------------------------------------*/
static int32_t prvGenerateRandomNumber()
{
return( uxRand() & INT32_MAX );
}
/*-----------------------------------------------------------*/
static PlaintextTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkContext_t * pxNetworkContext )
{
PlaintextTransportStatus_t xNetworkStatus;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xReconnectParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xReconnectParams;
uint16_t usNextRetryBackOff = 0U;
/* Initialize reconnect attempts and interval. */
RetryUtils_ParamsReset( &xReconnectParams );
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize reconnect attempts and interval.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying connection. */
BackoffAlgorithm_InitializeParams( &xReconnectParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
/* Attempt to connect to MQTT broker. If connection fails, retry after
* a timeout. Timeout value will exponentially increase till maximum
@ -631,16 +678,22 @@ static PlaintextTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkC
if( xNetworkStatus != PLAINTEXT_TRANSPORT_SUCCESS )
{
LogWarn( ( "Connection to the broker failed. Retrying connection with backoff and jitter." ) );
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
}
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xReconnectParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xRetryUtilsStatus == RetryUtilsRetriesExhausted )
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Connection to the broker failed, all attempts exhausted." ) );
xNetworkStatus = PLAINTEXT_TRANSPORT_CONNECT_FAILURE;
}
} while( ( xNetworkStatus != PLAINTEXT_TRANSPORT_SUCCESS ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Connection to the broker failed. "
"Retrying connection with backoff and jitter." ) );
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
}
} while( ( xNetworkStatus != PLAINTEXT_TRANSPORT_SUCCESS ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
return xNetworkStatus;
}
@ -723,12 +776,13 @@ static void prvUpdateSubAckStatus( MQTTPacketInfo_t * pxPacketInfo )
static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
{
MQTTStatus_t xResult = MQTTSuccess;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xRetryParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xRetryParams;
MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ];
BaseType_t xTimerStatus;
bool xFailedSubscribeToTopic = false;
uint32_t ulTopicCount = 0U;
uint16_t usNextRetryBackOff = 0U;
/* Some fields are not used by this demo so start with everything at 0. */
( void ) memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) );
@ -742,9 +796,15 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC;
xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );
/* Initialize retry attempts and interval. */
RetryUtils_ParamsReset( &xRetryParams );
xRetryParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize context for backoff retry attempts if SUBSCRIBE request fails.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying network operations. */
BackoffAlgorithm_InitializeParams( &xRetryParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
do
{
@ -801,17 +861,32 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ )
{
if( xTopicFilterContext[ ulTopicCount ].xSubAckStatus == MQTTSubAckFailure )
{
xFailedSubscribeToTopic = true;
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xRetryParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Server rejected subscription request. All retry attempts have exhausted. Topic=%s",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
}
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Server rejected subscription request. Attempting to re-subscribe to topic %s.",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
xFailedSubscribeToTopic = true;
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xRetryParams );
/* Backoff before the next re-subscribe attempt. */
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
break;
}
}
configASSERT( xRetryUtilsStatus != RetryUtilsRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
}
/*-----------------------------------------------------------*/

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\Common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\exponential_backoff;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\Common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -159,7 +159,7 @@
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext\using_plaintext.c" />
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_state.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt.c" />
@ -196,7 +196,7 @@
<ClInclude Include="..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging\logging_stack.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext\using_plaintext.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt.h" />

View File

@ -123,7 +123,7 @@
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext\using_plaintext.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClCompile>
</ItemGroup>
@ -216,7 +216,7 @@
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
</ItemGroup>

View File

@ -89,7 +89,7 @@
#include "core_mqtt_state.h"
/* Exponential backoff retry include. */
#include "exponential_backoff.h"
#include "backoff_algorithm.h"
/* Transport interface include. */
#if defined( democonfigUSE_TLS ) && ( democonfigUSE_TLS == 1 )
@ -109,6 +109,22 @@
#define mqttexampleNETWORK_BUFFER_SIZE ( 1024U )
#endif
/**
* @brief The maximum number of retries for network operation with server.
*/
#define mqttexampleRETRY_MAX_ATTEMPTS ( 5U )
/**
* @brief The maximum back-off delay (in milliseconds) for retrying failed operation
* with server.
*/
#define mqttexampleRETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
/**
* @brief The base back-off delay (in milliseconds) to use for network operation retry
* attempts.
*/
#define mqttexampleRETRY_BACKOFF_BASE_MS ( 500U )
/**
* @brief Timeout for receiving CONNACK packet in milliseconds.
@ -393,6 +409,22 @@ static MQTTStatus_t prvMQTTConnect( MQTTContext_t * pxMQTTContext,
*/
static MQTTStatus_t prvResumeSession( bool xSessionPresent );
/**
* @brief A wrapper to the "uxRand()" random number generator so that it
* can be passed to the backoffAlgorithm library for retry logic.
*
* This function implements the #BackoffAlgorithm_RNG_T type interface
* in the backoffAlgorithm library API.
*
* @note The "uxRand" function represents a pseudo random number generator.
* However, it is recommended to use a True Randon Number Generator (TRNG)
* for generating unique device-specific random values to avoid possibility
* of network collisions from multiple devices retrying network operations.
*
* @return The generated randon number. This function ALWAYS succeeds.
*/
static int32_t prvGenerateRandomNumber();
/**
* @brief Form a TCP connection to a server.
*
@ -956,11 +988,19 @@ static MQTTStatus_t prvResumeSession( bool xSessionPresent )
/*-----------------------------------------------------------*/
static int32_t prvGenerateRandomNumber()
{
return( uxRand() & INT32_MAX );
}
/*-----------------------------------------------------------*/
static BaseType_t prvSocketConnect( NetworkContext_t * pxNetworkContext )
{
BaseType_t xConnected = pdFAIL;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xReconnectParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xReconnectParams;
uint16_t usNextRetryBackOff = 0U;
#if defined( democonfigUSE_TLS ) && ( democonfigUSE_TLS == 1 )
TlsTransportStatus_t xNetworkStatus = TLS_TRANSPORT_CONNECT_FAILURE;
@ -997,9 +1037,15 @@ static BaseType_t prvSocketConnect( NetworkContext_t * pxNetworkContext )
#endif /* if defined( democonfigUSE_TLS ) && ( democonfigUSE_TLS == 1 ) */
/* We will use a retry mechanism with an exponential backoff mechanism and
* jitter. We initialize reconnect attempts and interval here. */
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
RetryUtils_ParamsReset( &xReconnectParams );
* jitter. We initialize the context required for backoff period calculation here.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying connection. */
BackoffAlgorithm_InitializeParams( &xReconnectParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
/* Attempt to connect to MQTT broker. If connection fails, retry after a
* timeout. Timeout value will exponentially increase until the maximum
@ -1035,15 +1081,22 @@ static BaseType_t prvSocketConnect( NetworkContext_t * pxNetworkContext )
if( !xConnected )
{
LogWarn( ( "Connection to the broker failed. Retrying connection with backoff and jitter." ) );
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
}
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xReconnectParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xRetryUtilsStatus == RetryUtilsRetriesExhausted )
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Connection to the broker failed. All attempts exhausted." ) );
LogError( ( "Connection to the broker failed, all attempts exhausted." ) );
}
} while( ( xConnected != pdPASS ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Connection to the broker failed. "
"Retrying connection with backoff and jitter." ) );
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
}
} while( ( xConnected != pdPASS ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
/* Set the socket wakeup callback. */
if( xConnected )

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\exponential_backoff;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\Source\mbedtls_utils;..\..\..\ThirdParty\mbedtls\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\Source\mbedtls_utils;..\..\..\ThirdParty\mbedtls\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MBEDTLS_CONFIG_FILE="mbedtls_config.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -159,7 +159,7 @@
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_freertos_port.c" />
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c" />
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext\using_plaintext.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c" />
@ -522,7 +522,7 @@
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext\using_plaintext.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.h" />
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />

View File

@ -393,7 +393,7 @@
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\freertos</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c">
@ -492,7 +492,7 @@
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\ThirdParty\mbedtls\include\mbedtls\aes.h">

View File

@ -55,7 +55,7 @@
#include "core_mqtt.h"
/* Exponential backoff retry include. */
#include "exponential_backoff.h"
#include "backoff_algorithm.h"
/* Transport interface implementation include header for TLS. */
#include "using_mbedtls.h"
@ -128,6 +128,23 @@
/*-----------------------------------------------------------*/
/**
* @brief The maximum number of retries for network operation with server.
*/
#define mqttexampleRETRY_MAX_ATTEMPTS ( 5U )
/**
* @brief The maximum back-off delay (in milliseconds) for retrying failed operation
* with server.
*/
#define mqttexampleRETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
/**
* @brief The base back-off delay (in milliseconds) to use for network operation retry
* attempts.
*/
#define mqttexampleRETRY_BACKOFF_BASE_MS ( 500U )
/**
* @brief Timeout for receiving CONNACK packet in milliseconds.
*/
@ -265,6 +282,22 @@
*/
static void prvMQTTDemoTask( void * pvParameters );
/**
* @brief A wrapper to the "uxRand()" random number generator so that it
* can be passed to the backoffAlgorithm library for retry logic.
*
* This function implements the #BackoffAlgorithm_RNG_T type interface
* in the backoffAlgorithm library API.
*
* @note The "uxRand" function represents a pseudo random number generator.
* However, it is recommended to use a True Randon Number Generator (TRNG)
* for generating unique device-specific random values to avoid possibility
* of network collisions from multiple devices retrying network operations.
*
* @return The generated randon number. This function ALWAYS succeeds.
*/
static int32_t prvGenerateRandomNumber();
/**
* @brief Connect to MQTT broker with reconnection retries.
*
@ -494,7 +527,7 @@ static void prvMQTTDemoTask( void * pvParameters )
/* If server rejected the subscription request, attempt to resubscribe to
* topic. Attempts are made according to the exponential backoff retry
* strategy implemented in retryUtils. */
* strategy implemented in BackoffAlgorithm. */
prvMQTTSubscribeWithBackoffRetries( &xMQTTContext );
/****************** Publish and Keep Alive Loop. **********************/
@ -557,12 +590,20 @@ static void prvMQTTDemoTask( void * pvParameters )
}
/*-----------------------------------------------------------*/
static int32_t prvGenerateRandomNumber()
{
return( uxRand() & INT32_MAX );
}
/*-----------------------------------------------------------*/
static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredentials_t * pxNetworkCredentials,
NetworkContext_t * pxNetworkContext )
{
TlsTransportStatus_t xNetworkStatus;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xReconnectParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xReconnectParams;
uint16_t usNextRetryBackOff = 0U;
#ifdef democonfigUSE_AWS_IOT_CORE_BROKER
@ -590,9 +631,16 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredent
pxNetworkCredentials->pPrivateKey = ( const unsigned char * ) democonfigCLIENT_PRIVATE_KEY_PEM;
pxNetworkCredentials->privateKeySize = sizeof( democonfigCLIENT_PRIVATE_KEY_PEM );
#endif
/* Initialize reconnect attempts and interval. */
RetryUtils_ParamsReset( &xReconnectParams );
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize reconnect attempts and interval.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying connection. */
BackoffAlgorithm_InitializeParams( &xReconnectParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
/* Attempt to connect to MQTT broker. If connection fails, retry after
* a timeout. Timeout value will exponentially increase till maximum
@ -616,16 +664,22 @@ static TlsTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkCredent
if( xNetworkStatus != TLS_TRANSPORT_SUCCESS )
{
LogWarn( ( "Connection to the broker failed. Retrying connection with backoff and jitter." ) );
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
}
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xReconnectParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xRetryUtilsStatus == RetryUtilsRetriesExhausted )
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Connection to the broker failed, all attempts exhausted." ) );
xNetworkStatus = TLS_TRANSPORT_CONNECT_FAILURE;
}
} while( ( xNetworkStatus != TLS_TRANSPORT_SUCCESS ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Connection to the broker failed. "
"Retrying connection with backoff and jitter." ) );
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
}
} while( ( xNetworkStatus != TLS_TRANSPORT_SUCCESS ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
return xNetworkStatus;
}
@ -732,8 +786,9 @@ static void prvUpdateSubAckStatus( MQTTPacketInfo_t * pxPacketInfo )
static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
{
MQTTStatus_t xResult = MQTTSuccess;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xRetryParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xRetryParams;
uint16_t usNextRetryBackOff = 0U;
MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ];
bool xFailedSubscribeToTopic = false;
uint32_t ulTopicCount = 0U;
@ -750,9 +805,15 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC;
xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );
/* Initialize retry attempts and interval. */
RetryUtils_ParamsReset( &xRetryParams );
xRetryParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize context for backoff retry attempts if SUBSCRIBE request fails.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying network operations. */
BackoffAlgorithm_InitializeParams( &xRetryParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
do
{
@ -792,17 +853,32 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ )
{
if( xTopicFilterContext[ ulTopicCount ].xSubAckStatus == MQTTSubAckFailure )
{
xFailedSubscribeToTopic = true;
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xRetryParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Server rejected subscription request. All retry attempts have exhausted. Topic=%s",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
}
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Server rejected subscription request. Attempting to re-subscribe to topic %s.",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
xFailedSubscribeToTopic = true;
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xRetryParams );
/* Backoff before the next re-subscribe attempt. */
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
break;
}
}
configASSERT( xRetryUtilsStatus != RetryUtilsRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
}
/*-----------------------------------------------------------*/

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\exponential_backoff;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\Source\mbedtls_utils;..\..\..\ThirdParty\mbedtls\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls;..\..\..\Source\Utilities\mbedtls_freertos;..\..\..\..\Source\mbedtls_utils;..\..\..\ThirdParty\mbedtls\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MBEDTLS_CONFIG_FILE="mbedtls_config.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -159,7 +159,7 @@
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_freertos_port.c" />
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c" />
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
@ -520,7 +520,7 @@
<ClInclude Include="..\..\..\Source\Utilities\mbedtls_freertos\threading_alt.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.h" />
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />

View File

@ -393,7 +393,7 @@
<ClCompile Include="..\..\..\Source\Utilities\mbedtls_freertos\mbedtls_error.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform\freertos</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls\using_mbedtls.c">
@ -489,7 +489,7 @@
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\ThirdParty\mbedtls\include\mbedtls\aes.h">

View File

@ -53,7 +53,7 @@
#include "core_mqtt.h"
/* Exponential backoff retry include. */
#include "exponential_backoff.h"
#include "backoff_algorithm.h"
/* Transport interface include. */
#include "using_plaintext.h"
@ -93,6 +93,24 @@
/*-----------------------------------------------------------*/
/**
* @brief The maximum number of retries for network operation with server.
*/
#define mqttexampleRETRY_MAX_ATTEMPTS ( 5U )
/**
* @brief The maximum back-off delay (in milliseconds) for retrying failed operation
* with server.
*/
#define mqttexampleRETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
/**
* @brief The base back-off delay (in milliseconds) to use for network operation retry
* attempts.
*/
#define mqttexampleRETRY_BACKOFF_BASE_MS ( 500U )
/**
* @brief Timeout for receiving CONNACK packet in milliseconds.
*/
@ -166,6 +184,22 @@
*/
static void prvMQTTDemoTask( void * pvParameters );
/**
* @brief A wrapper to the "uxRand()" random number generator so that it
* can be passed to the backoffAlgorithm library for retry logic.
*
* This function implements the #BackoffAlgorithm_RNG_T type interface
* in the backoffAlgorithm library API.
*
* @note The "uxRand" function represents a pseudo random number generator.
* However, it is recommended to use a True Randon Number Generator (TRNG)
* for generating unique device-specific random values to avoid possibility
* of network collisions from multiple devices retrying network operations.
*
* @return The generated randon number. This function ALWAYS succeeds.
*/
static int32_t prvGenerateRandomNumber();
/**
* @brief Connect to MQTT broker with reconnection retries.
*
@ -370,7 +404,7 @@ static void prvMQTTDemoTask( void * pvParameters )
/* If server rejected the subscription request, attempt to resubscribe to
* the topic. Attempts are made according to the exponential backoff retry
* strategy declared in exponential_backoff.h. */
* strategy declared in backoff_algorithm.h. */
prvMQTTSubscribeWithBackoffRetries( &xMQTTContext );
/******************* Publish and Keep Alive Loop. *********************/
@ -434,15 +468,29 @@ static void prvMQTTDemoTask( void * pvParameters )
}
/*-----------------------------------------------------------*/
static int32_t prvGenerateRandomNumber()
{
return( uxRand() & INT32_MAX );
}
/*-----------------------------------------------------------*/
static PlaintextTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkContext_t * pxNetworkContext )
{
PlaintextTransportStatus_t xNetworkStatus;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xReconnectParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xReconnectParams;
uint16_t usNextRetryBackOff = 0U;
/* Initialize reconnect attempts and interval. */
RetryUtils_ParamsReset( &xReconnectParams );
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize reconnect attempts and interval.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying connection. */
BackoffAlgorithm_InitializeParams( &xReconnectParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
/* Attempt to connect to MQTT broker. If connection fails, retry after
* a timeout. Timeout value will exponentially increase till maximum
@ -464,16 +512,22 @@ static PlaintextTransportStatus_t prvConnectToServerWithBackoffRetries( NetworkC
if( xNetworkStatus != PLAINTEXT_TRANSPORT_SUCCESS )
{
LogWarn( ( "Connection to the broker failed. Retrying connection with backoff and jitter." ) );
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
}
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xReconnectParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xRetryUtilsStatus == RetryUtilsRetriesExhausted )
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Connection to the broker failed, all attempts exhausted." ) );
xNetworkStatus = PLAINTEXT_TRANSPORT_CONNECT_FAILURE;
}
} while( ( xNetworkStatus != PLAINTEXT_TRANSPORT_SUCCESS ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Connection to the broker failed. "
"Retrying connection with backoff and jitter." ) );
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
}
} while( ( xNetworkStatus != PLAINTEXT_TRANSPORT_SUCCESS ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
return xNetworkStatus;
}
@ -555,8 +609,9 @@ static void prvUpdateSubAckStatus( MQTTPacketInfo_t * pxPacketInfo )
static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
{
MQTTStatus_t xResult = MQTTSuccess;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xRetryParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xRetryParams;
uint16_t usNextRetryBackOff = 0U;
MQTTSubscribeInfo_t xMQTTSubscription[ mqttexampleTOPIC_COUNT ];
bool xFailedSubscribeToTopic = false;
uint32_t ulTopicCount = 0U;
@ -573,9 +628,15 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC;
xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );
/* Initialize retry attempts and interval. */
RetryUtils_ParamsReset( &xRetryParams );
xRetryParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize context for backoff retry attempts if SUBSCRIBE request fails.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying network operations. */
BackoffAlgorithm_InitializeParams( &xRetryParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
do
{
@ -615,17 +676,32 @@ static void prvMQTTSubscribeWithBackoffRetries( MQTTContext_t * pxMQTTContext )
for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ )
{
if( xTopicFilterContext[ ulTopicCount ].xSubAckStatus == MQTTSubAckFailure )
{
xFailedSubscribeToTopic = true;
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xRetryParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Server rejected subscription request. All retry attempts have exhausted. Topic=%s",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
}
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Server rejected subscription request. Attempting to re-subscribe to topic %s.",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
xFailedSubscribeToTopic = true;
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xRetryParams );
/* Backoff before the next re-subscribe attempt. */
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
break;
}
}
configASSERT( xRetryUtilsStatus != RetryUtilsRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
}
/*-----------------------------------------------------------*/

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\Common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\exponential_backoff;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\Common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -159,7 +159,7 @@
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext\using_plaintext.c" />
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_state.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt.c" />
@ -196,7 +196,7 @@
<ClInclude Include="..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging\logging_stack.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_plaintext\using_plaintext.h" />
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />

View File

@ -126,7 +126,7 @@
<ClCompile Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClCompile>
</ItemGroup>
@ -219,7 +219,7 @@
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h">

View File

@ -61,7 +61,7 @@
#include "core_mqtt_serializer.h"
/* Exponential backoff retry include. */
#include "exponential_backoff.h"
#include "backoff_algorithm.h"
/*-----------------------------------------------------------*/
@ -122,6 +122,23 @@
*/
#define mqttexampleSHARED_BUFFER_SIZE ( 500U )
/**
* @brief The maximum number of retries for network operation with server.
*/
#define mqttexampleRETRY_MAX_ATTEMPTS ( 5U )
/**
* @brief The maximum back-off delay (in milliseconds) for retrying failed operation
* with server.
*/
#define mqttexampleRETRY_MAX_BACKOFF_DELAY_MS ( 5000U )
/**
* @brief The base back-off delay (in milliseconds) to use for network operation retry
* attempts.
*/
#define mqttexampleRETRY_BACKOFF_BASE_MS ( 500U )
/**
* @brief Time to wait between each cycle of the demo implemented by prvMQTTDemoTask().
*/
@ -172,6 +189,22 @@ static void prvMQTTDemoTask( void * pvParameters );
*/
static Socket_t prvCreateTCPConnectionToBroker( void );
/**
* @brief A wrapper to the "uxRand()" random number generator so that it
* can be passed to the backoffAlgorithm library for retry logic.
*
* This function implements the #BackoffAlgorithm_RNG_T type interface
* in the backoffAlgorithm library API.
*
* @note The "uxRand" function represents a pseudo random number generator.
* However, it is recommended to use a True Randon Number Generator (TRNG)
* for generating unique device-specific random values to avoid possibility
* of network collisions from multiple devices retrying network operations.
*
* @return The generated randon number. This function ALWAYS succeeds.
*/
static int32_t prvGenerateRandomNumber();
/**
* @brief Connect to MQTT broker with reconnection retries.
*
@ -421,7 +454,7 @@ static void prvMQTTDemoTask( void * pvParameters )
/* If the server rejected the subscription request, attempt to resubscribe
* to the topic. Attempts are made according to the exponential backoff
* retry strategy declared in exponential_backoff.h. */
* retry strategy declared in backoff_algorithm.h. */
prvMQTTSubscribeWithBackoffRetries( xMQTTSocket );
/**************************** Publish and Keep-Alive Loop. ******************************/
@ -610,15 +643,29 @@ static Socket_t prvCreateTCPConnectionToBroker( void )
}
/*-----------------------------------------------------------*/
static int32_t prvGenerateRandomNumber()
{
return( uxRand() & INT32_MAX );
}
/*-----------------------------------------------------------*/
static Socket_t prvConnectToServerWithBackoffRetries()
{
Socket_t xSocket;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xReconnectParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xReconnectParams;
uint16_t usNextRetryBackOff = 0U;
/* Initialize reconnect attempts and interval. */
RetryUtils_ParamsReset( &xReconnectParams );
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize reconnect attempts and interval.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying connection. */
BackoffAlgorithm_InitializeParams( &xReconnectParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
/* Attempt to connect to MQTT broker. If connection fails, retry after
* a timeout. Timeout value will exponentially increase till maximum
@ -636,16 +683,22 @@ static Socket_t prvConnectToServerWithBackoffRetries()
if( xSocket == FREERTOS_INVALID_SOCKET )
{
LogWarn( ( "Connection to the broker failed. Retrying connection with backoff and jitter." ) );
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
}
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xReconnectParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xRetryUtilsStatus == RetryUtilsRetriesExhausted )
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Connection to the broker failed, all attempts exhausted." ) );
xSocket = FREERTOS_INVALID_SOCKET;
}
} while( ( xSocket == FREERTOS_INVALID_SOCKET ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Connection to the broker failed. "
"Retrying connection with backoff and jitter." ) );
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
}
} while( ( xSocket == FREERTOS_INVALID_SOCKET ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
return xSocket;
}
@ -812,13 +865,20 @@ static void prvMQTTSubscribeToTopic( Socket_t xMQTTSocket )
static void prvMQTTSubscribeWithBackoffRetries( Socket_t xMQTTSocket )
{
uint32_t ulTopicCount = 0U;
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
RetryUtilsParams_t xRetryParams;
BackoffAlgorithmStatus_t xBackoffAlgStatus = BackoffAlgorithmSuccess;
BackoffAlgorithmContext_t xRetryParams;
uint16_t usNextRetryBackOff = 0U;
bool xFailedSubscribeToTopic = false;
/* Initialize retry attempts and interval. */
RetryUtils_ParamsReset( &xRetryParams );
xRetryParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
/* Initialize context for backoff retry attempts if SUBSCRIBE request fails.
* Note: This demo is using pseudo random number generator for the backoff
* algorithm. However, it is recommended to use a True Random Number generator to
* avoid possibility of collisions between multiple devices retrying network operations. */
BackoffAlgorithm_InitializeParams( &xRetryParams,
mqttexampleRETRY_BACKOFF_BASE_MS,
mqttexampleRETRY_MAX_BACKOFF_DELAY_MS,
mqttexampleRETRY_MAX_ATTEMPTS,
prvGenerateRandomNumber );
do
{
@ -853,17 +913,32 @@ static void prvMQTTSubscribeWithBackoffRetries( Socket_t xMQTTSocket )
for( ulTopicCount = 0; ulTopicCount < mqttexampleTOPIC_COUNT; ulTopicCount++ )
{
if( xTopicFilterContext[ ulTopicCount ].xSubAckSuccess == false )
{
xFailedSubscribeToTopic = true;
/* Get back-off value (in milliseconds) for the next connection retry. */
xBackoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &xRetryParams, &usNextRetryBackOff );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRngFailure );
if( xBackoffAlgStatus == BackoffAlgorithmRetriesExhausted )
{
LogError( ( "Server rejected subscription request. All retry attempts have exhausted. Topic=%s",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
}
else if( xBackoffAlgStatus == BackoffAlgorithmSuccess )
{
LogWarn( ( "Server rejected subscription request. Attempting to re-subscribe to topic %s.",
xTopicFilterContext[ ulTopicCount ].pcTopicFilter ) );
xFailedSubscribeToTopic = true;
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xRetryParams );
/* Backoff before the next re-subscribe attempt. */
vTaskDelay( pdMS_TO_TICKS( usNextRetryBackOff ) );
}
break;
}
}
configASSERT( xRetryUtilsStatus != RetryUtilsRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
configASSERT( xBackoffAlgStatus != BackoffAlgorithmRetriesExhausted );
} while( ( xFailedSubscribeToTopic == true ) && ( xBackoffAlgStatus == BackoffAlgorithmSuccess ) );
}
/*-----------------------------------------------------------*/

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\Common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Utilities\exponential_backoff;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\Common\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\Utilities\backoff_algorithm\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\..\Source\Application-Protocols\coreMQTT\source\interface;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -157,7 +157,7 @@
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\FreeRTOS_UDP_IP.c" />
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.c" />
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
<ClCompile Include="..\..\..\..\FreeRTOS-Plus\Demo\Common\Logging\windows\Logging_WinSim.c" />
<ClCompile Include="..\Common\main.c" />

View File

@ -114,7 +114,7 @@
<ClCompile Include="..\..\..\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\coreMQTT\src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClCompile>
</ItemGroup>

View File

@ -58,7 +58,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\coreMQTT_Windows_Simulator\Common;..\coreMQTT_Windows_Simulator\common\WinPCap;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\corePKCS11\source\include;..\..\Source\corePKCS11\3rdparty\pkcs11;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\Source\Utilities\exponential_backoff;..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls_pkcs11;..\..\Source\Utilities\mbedtls_freertos;..\..\Source\mbedtls_utils;..\..\ThirdParty\mbedtls\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\coreMQTT_Windows_Simulator\Common;..\coreMQTT_Windows_Simulator\common\WinPCap;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\corePKCS11\source\include;..\..\Source\corePKCS11\3rdparty\pkcs11;..\..\Source\Application-Protocols\coreMQTT\source\include;..\..\Source\Application-Protocols\coreMQTT\source\interface;..\..\Source\Utilities\backoff_algorithm\source\include;..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp;..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls_pkcs11;..\..\Source\Utilities\mbedtls_freertos;..\..\Source\mbedtls_utils;..\..\ThirdParty\mbedtls\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MBEDTLS_CONFIG_FILE="mbedtls_config.h";WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -159,7 +159,7 @@
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Utilities\mbedtls_freertos\mbedtls_freertos_port.c" />
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Utilities\mbedtls_freertos\mbedtls_error.c" />
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Utilities\exponential_backoff\exponential_backoff.c" />
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c" />
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.c" />
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\core_mqtt_serializer.c" />
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Application-Protocols\coreMQTT\source\core_mqtt_state.c" />
@ -290,7 +290,7 @@
<ClInclude Include="..\..\..\Source\Utilities\mbedtls_freertos\threading_alt.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\sockets_wrapper.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\network_transport\freertos_plus_tcp\using_mbedtls_pkcs11\using_mbedtls_pkcs11.h" />
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h" />
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_serializer.h" />
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\include\core_mqtt_state.h" />

View File

@ -175,7 +175,7 @@
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Utilities\mbedtls_freertos\mbedtls_freertos_port.c">
<Filter>Transport</Filter>
</ClCompile>
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Utilities\exponential_backoff\exponential_backoff.c">
<ClCompile Include="..\..\..\FreeRTOS-Plus\Source\Utilities\backoff_algorithm\source\backoff_algorithm.c">
<Filter>Transport</Filter>
</ClCompile>
<ClCompile Include="main.c" />
@ -541,7 +541,7 @@
<ClInclude Include="..\..\..\Source\Application-Protocols\coreMQTT\source\interface\transport_interface.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Source\Utilities\exponential_backoff\exponential_backoff.h">
<ClInclude Include="..\..\..\Source\Utilities\backoff_algorithm\source\include\backoff_algorithm.h">
<Filter>FreeRTOS+\FreeRTOS IoT Libraries\platform</Filter>
</ClInclude>
<ClInclude Include="mbedtls_config.h" />

View File

@ -1,101 +0,0 @@
/*
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file exponential_backoff.c
* @brief Utility implementation of backoff logic, used for attempting retries of failed processes.
*/
/* Standard includes. */
#include <stdint.h>
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "exponential_backoff.h"
#define MILLISECONDS_PER_SECOND ( 1000U ) /**< @brief Milliseconds per second. */
extern UBaseType_t uxRand( void );
/*-----------------------------------------------------------*/
RetryUtilsStatus_t RetryUtils_BackoffAndSleep( RetryUtilsParams_t * pRetryParams )
{
RetryUtilsStatus_t status = RetryUtilsRetriesExhausted;
uint32_t backOffDelayMs = 0;
/* If pRetryParams->maxRetryAttempts is set to 0, try forever. */
if( ( pRetryParams->attemptsDone < pRetryParams->maxRetryAttempts ) ||
( 0U == pRetryParams->maxRetryAttempts ) )
{
/* Choose a random value for back-off time between 0 and the max jitter value. */
backOffDelayMs = uxRand() % pRetryParams->nextJitterMax;
/* Wait for backoff time to expire for the next retry. */
vTaskDelay( pdMS_TO_TICKS( backOffDelayMs * MILLISECONDS_PER_SECOND ) );
/* Increment backoff counts. */
pRetryParams->attemptsDone++;
/* Double the max jitter value for the next retry attempt, only
* if the new value will be less than the max backoff time value. */
if( pRetryParams->nextJitterMax < ( MAX_RETRY_BACKOFF_SECONDS / 2U ) )
{
pRetryParams->nextJitterMax += pRetryParams->nextJitterMax;
}
else
{
pRetryParams->nextJitterMax = MAX_RETRY_BACKOFF_SECONDS;
}
status = RetryUtilsSuccess;
}
else
{
/* When max retry attempts are exhausted, let application know by
* returning RetryUtilsRetriesExhausted. Application may choose to
* restart the retry process after calling RetryUtils_ParamsReset(). */
status = RetryUtilsRetriesExhausted;
RetryUtils_ParamsReset( pRetryParams );
}
return status;
}
/*-----------------------------------------------------------*/
void RetryUtils_ParamsReset( RetryUtilsParams_t * pRetryParams )
{
uint32_t jitter = 0;
/* Reset attempts done to zero so that the next retry cycle can start. */
pRetryParams->attemptsDone = 0;
/* Calculate jitter value using picking a random number. */
jitter = ( uxRand() % MAX_JITTER_VALUE_SECONDS );
/* Reset the backoff value to the initial time out value plus jitter. */
pRetryParams->nextJitterMax = INITIAL_RETRY_BACKOFF_SECONDS + jitter;
}
/*-----------------------------------------------------------*/

View File

@ -1,245 +0,0 @@
/*
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* @file exponential_backoff.h
* @brief Declaration of the exponential backoff retry logic utility functions
* and constants.
*/
#ifndef EXPONENTIAL_BACKOFF_H
#define EXPONENTIAL_BACKOFF_H
/* Standard include. */
#include <stdint.h>
/**
* @page retryutils_page Retry Utilities
* @brief An abstraction of utilities for retrying with exponential back off and
* jitter.
*
* @section retryutils_overview Overview
* The retry utilities are a set of APIs that aid in retrying with exponential
* backoff and jitter. Exponential backoff with jitter is strongly recommended
* for retrying failed actions over the network with servers. Please see
* https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ for
* more information about the benefits with AWS.
*
* Exponential backoff with jitter is typically used when retrying a failed
* connection to the server. In an environment with poor connectivity, a client
* can get disconnected at any time. A backoff strategy helps the client to
* conserve battery by not repeatedly attempting reconnections when they are
* unlikely to succeed.
*
* Before retrying the failed communication to the server there is a quiet period.
* In this quiet period, the task that is retrying must sleep for some random
* amount of seconds between 0 and the lesser of a base value and a predefined
* maximum. The base is doubled with each retry attempt until the maximum is
* reached.<br>
*
* > sleep_seconds = random_between( 0, min( 2<sup>attempts_count</sup> * base_seconds, maximum_seconds ) )
*
* @section retryutils_implementation Implementing Retry Utils
*
* The functions that must be implemented are:<br>
* - @ref RetryUtils_ParamsReset
* - @ref RetryUtils_BackoffAndSleep
*
* The functions are used as shown in the diagram below. This is the exponential
* backoff with jitter loop:
*
* @image html exponential_backoff_flow.png width=25%
*
* The following steps give guidance on implementing the Retry Utils. An example
* implementation of the Retry Utils for the FreeRTOS platform can be found in file
* @ref exponential_backoff.c.
*
* -# Implementing @ref RetryUtils_ParamsReset
* @snippet this define_retryutils_paramsreset
*<br>
* This function initializes @ref RetryUtilsParams_t. It is expected to set
* @ref RetryUtilsParams_t.attemptsDone to zero. It is also expected to set
* @ref RetryUtilsParams_t.nextJitterMax to @ref INITIAL_RETRY_BACKOFF_SECONDS
* plus some random amount of seconds, jitter. This jitter is a random number
* between 0 and @ref MAX_JITTER_VALUE_SECONDS. This function must be called
* before entering the exponential backoff with jitter loop using
* @ref RetryUtils_BackoffAndSleep.<br><br>
* Please follow the example below to implement your own @ref RetryUtils_ParamsReset.
* The lines with FIXME comments should be updated.
* @code{c}
* void RetryUtils_ParamsReset( RetryUtilsParams_t * pRetryParams )
* {
* uint32_t jitter = 0;
*
* // Reset attempts done to zero so that the next retry cycle can start.
* pRetryParams->attemptsDone = 0;
*
* // Seed pseudo random number generator with the current time. FIXME: Your
* // system may have another method to retrieve the current time to seed the
* // pseudo random number generator.
* srand( time( NULL ) );
*
* // Calculate jitter value using picking a random number.
* jitter = ( rand() % MAX_JITTER_VALUE_SECONDS );
*
* // Reset the backoff value to the initial time out value plus jitter.
* pRetryParams->nextJitterMax = INITIAL_RETRY_BACKOFF_SECONDS + jitter;
* }
* @endcode<br>
*
* -# Implementing @ref RetryUtils_BackoffAndSleep
* @snippet this define_retryutils_backoffandsleep
* <br>
* When this function is invoked, the calling task is expected to sleep a random
* number of seconds between 0 and @ref RetryUtilsParams_t.nextJitterMax. After
* sleeping this function must double @ref RetryUtilsParams_t.nextJitterMax, but
* not exceeding @ref MAX_RETRY_BACKOFF_SECONDS. When @ref RetryUtilsParams_t.maxRetryAttempts
* are reached this function should return @ref RetryUtilsRetriesExhausted, unless
* @ref RetryUtilsParams_t.maxRetryAttempts is set to zero.
* When @ref RetryUtilsRetriesExhausted is returned the calling application can
* stop trying with a failure, or it can call @ref RetryUtils_ParamsReset again
* and restart the exponential back off with jitter loop.<br><br>
* Please follow the example below to implement your own @ref RetryUtils_BackoffAndSleep.
* The lines with FIXME comments should be updated.
* @code{c}
* RetryUtilsStatus_t RetryUtils_BackoffAndSleep( RetryUtilsParams_t * pRetryParams )
* {
* RetryUtilsStatus_t status = RetryUtilsRetriesExhausted;
* // The quiet period delay in seconds.
* int backOffDelay = 0;
*
* // If pRetryParams->maxRetryAttempts is set to 0, try forever.
* if( ( pRetryParams->attemptsDone < pRetryParams->maxRetryAttempts ) ||
* ( 0U == pRetryParams->maxRetryAttempts ) )
* {
* // Choose a random value for back-off time between 0 and the max jitter value.
* backOffDelay = rand() % pRetryParams->nextJitterMax;
*
* // Wait for backoff time to expire for the next retry.
* ( void ) myThreadSleepFunction( backOffDelay ); // FIXME: Replace with your system's thread sleep function.
*
* // Increment backoff counts.
* pRetryParams->attemptsDone++;
*
* // Double the max jitter value for the next retry attempt, only
* // if the new value will be less than the max backoff time value.
* if( pRetryParams->nextJitterMax < ( MAX_RETRY_BACKOFF_SECONDS / 2U ) )
* {
* pRetryParams->nextJitterMax += pRetryParams->nextJitterMax;
* }
* else
* {
* pRetryParams->nextJitterMax = MAX_RETRY_BACKOFF_SECONDS;
* }
*
* status = RetryUtilsSuccess;
* }
* else
* {
* // When max retry attempts are exhausted, let application know by
* // returning RetryUtilsRetriesExhausted. Application may choose to
* // restart the retry process after calling RetryUtils_ParamsReset().
* status = RetryUtilsRetriesExhausted;
* RetryUtils_ParamsReset( pRetryParams );
* }
*
* return status;
* }
* @endcode
*/
/**
* @brief Max number of retry attempts. Set this value to 0 if the client must
* retry forever.
*/
#define MAX_RETRY_ATTEMPTS 4U
/**
* @brief Initial fixed backoff value in seconds between two successive
* retries. A random jitter value is added to every backoff value.
*/
#define INITIAL_RETRY_BACKOFF_SECONDS 1U
/**
* @brief Max backoff value in seconds.
*/
#define MAX_RETRY_BACKOFF_SECONDS 128U
/**
* @brief Max jitter value in seconds.
*/
#define MAX_JITTER_VALUE_SECONDS 5U
/**
* @brief Status for @ref RetryUtils_BackoffAndSleep.
*/
typedef enum RetryUtilsStatus
{
RetryUtilsSuccess = 0, /**< @brief The function returned successfully after sleeping. */
RetryUtilsRetriesExhausted /**< @brief The function exhausted all retry attempts. */
} RetryUtilsStatus_t;
/**
* @brief Represents parameters required for retry logic.
*/
typedef struct RetryUtilsParams
{
/**
* @brief Max number of retry attempts. Set this value to 0 if the client must
* retry forever.
*/
uint32_t maxRetryAttempts;
/**
* @brief The cumulative count of backoff delay cycles completed
* for retries.
*/
uint32_t attemptsDone;
/**
* @brief The max jitter value for backoff time in retry attempt.
*/
uint32_t nextJitterMax;
} RetryUtilsParams_t;
/**
* @brief Resets the retry timeout value and number of attempts.
* This function must be called by the application before a new retry attempt.
*
* @param[in, out] pRetryParams Structure containing attempts done and timeout
* value.
*/
void RetryUtils_ParamsReset( RetryUtilsParams_t * pRetryParams );
/**
* @brief Simple platform specific exponential backoff function. The application
* must use this function between retry failures to add exponential delay.
* This function will block the calling task for the current timeout value.
*
* @param[in, out] pRetryParams Structure containing retry parameters.
*
* @return #RetryUtilsSuccess after a successful sleep, #RetryUtilsRetriesExhausted
* when all attempts are exhausted.
*/
RetryUtilsStatus_t RetryUtils_BackoffAndSleep( RetryUtilsParams_t * pRetryParams );
#endif /* ifndef EXPONENTIAL_BACKOFF_H */

View File

@ -1,6 +1,6 @@
Directories:
+ Utilities/exponential_backoff contains a utility that calculates an
+ Utilities/backoff_algorithm contains a utility that calculates an
exponential back off time, with some jitter. It is used to ensure fleets of
IoT devices that become disconnected don't all try and reconnect at the same
time.