Skip to content

Commit

Permalink
fw_download: implement retry with backoff for firmware update
Browse files Browse the repository at this point in the history
When awaiting a retry, use the timeout value of the manifest semaphore to
wait until the appropriate backoff duration has passed before retrying a
download. This allows a new manifest to be received and acted upon while
awaiting a retry.

Set up the component for a retry as soon as the download step has finished
(whether it is a success or failure). The retry continues to be in effect
until all validation and other steps of the fw_update process have been
confirmed. Finally, reset the backoff values to indicate a retry
is not necessary.

Signed-off-by: Mike Szczys <[email protected]>
  • Loading branch information
szczys committed Dec 10, 2024
1 parent 329e203 commit 0e88b3b
Showing 1 changed file with 35 additions and 8 deletions.
43 changes: 35 additions & 8 deletions src/fw_update.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,16 +368,34 @@ static void fw_update_thread(void *arg)
true);

GLTH_LOGI(TAG, "Waiting to receive OTA manifest");
golioth_sys_sem_take(_manifest_rcvd, GOLIOTH_SYS_WAIT_FOREVER);
GLTH_LOGI(TAG, "Received OTA manifest");

bool new_component_received =
received_new_target_component(&_ota_manifest, &_component_ctx);

if (!new_component_received)
while (1)
{
GLTH_LOGI(TAG, "Manifest does not contain different firmware version. Nothing to do.");
continue;
int32_t manifest_timeout = (_component_ctx.backoff_duration_ms == 0)
? GOLIOTH_SYS_WAIT_FOREVER
: backoff_ms_before_expiration(&_component_ctx);

if (!golioth_sys_sem_take(_manifest_rcvd, manifest_timeout))
{
GLTH_LOGI(TAG,
"Retry component download: %s",
_component_ctx.config.fw_package_name);
break;
}

GLTH_LOGI(TAG, "Received OTA manifest");

bool new_component_received =
received_new_target_component(&_ota_manifest, &_component_ctx);

if (!new_component_received)
{
GLTH_LOGI(TAG,
"Manifest does not contain different firmware version. Nothing to do.");
continue;
}

break;
}

GLTH_LOGI(TAG, "State = Downloading");
Expand Down Expand Up @@ -465,6 +483,9 @@ static void fw_update_thread(void *arg)
}
}

/* Download finished, prepare backoff in case needed */
backoff_increment(&_component_ctx);

if (err != GOLIOTH_OK)
{
switch (err)
Expand Down Expand Up @@ -538,6 +559,9 @@ static void fw_update_thread(void *arg)
continue;
}

/* Download successful. Reset backoff */
backoff_reset(&_component_ctx);

int countdown = 5;
while (countdown > 0)
{
Expand All @@ -564,7 +588,10 @@ void golioth_fw_update_init_with_config(struct golioth_client *client,
static bool initialized = false;

_client = client;

_component_ctx.config = *config;
backoff_reset(&_component_ctx);

_manifest_update_mut = golioth_sys_mutex_create(); // never destroyed
_manifest_rcvd = golioth_sys_sem_create(1, 0); // never destroyed

Expand Down

0 comments on commit 0e88b3b

Please sign in to comment.