mgmt: hawkbit: seperate autohandler
seperate the autohandler from the main hawkbit source. This way the autohandler can be disabled if it is not needed. Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
This commit is contained in:
parent
621cf5baec
commit
dce3d2de66
5 changed files with 198 additions and 171 deletions
|
|
@ -88,62 +88,6 @@ int hawkbit_set_custom_data_cb(hawkbit_config_device_data_cb_handler_t cb);
|
|||
*/
|
||||
int hawkbit_init(void);
|
||||
|
||||
/**
|
||||
* @brief Runs hawkBit probe and hawkBit update automatically
|
||||
*
|
||||
* @details The hawkbit_autohandler handles the whole process
|
||||
* in pre-determined time intervals.
|
||||
*
|
||||
* @param auto_reschedule If true, the handler will reschedule itself
|
||||
*/
|
||||
void hawkbit_autohandler(bool auto_reschedule);
|
||||
|
||||
/**
|
||||
* @brief Wait for the autohandler to finish.
|
||||
*
|
||||
* @param events Set of desired events on which to wait. Set to ::UINT32_MAX to wait for the
|
||||
* autohandler to finish one run, or BIT() together with a value from
|
||||
* ::hawkbit_response to wait for a specific event.
|
||||
* @param timeout Waiting period for the desired set of events or one of the
|
||||
* special values ::K_NO_WAIT and ::K_FOREVER.
|
||||
*
|
||||
* @retval HAWKBIT_OK if success.
|
||||
* @retval HAWKBIT_NO_RESPONSE if matching events were not received within the specified time
|
||||
* @retval HAWKBIT_NETWORKING_ERROR fail to connect to the hawkBit server.
|
||||
* @retval HAWKBIT_UNCONFIRMED_IMAGE image is unconfirmed.
|
||||
* @retval HAWKBIT_PERMISSION_ERROR fail to get the permission to access the hawkBit server.
|
||||
* @retval HAWKBIT_METADATA_ERROR fail to parse or to encode the metadata.
|
||||
* @retval HAWKBIT_DOWNLOAD_ERROR fail while downloading the update package.
|
||||
* @retval HAWKBIT_UPDATE_INSTALLED if an update was installed. Reboot is required to apply it.
|
||||
* @retval HAWKBIT_NO_UPDATE if no update was available.
|
||||
* @retval HAWKBIT_CANCEL_UPDATE update was cancelled.
|
||||
* @retval HAWKBIT_NOT_INITIALIZED if hawkBit is not initialized.
|
||||
* @retval HAWKBIT_PROBE_IN_PROGRESS if probe is currently running.
|
||||
*/
|
||||
enum hawkbit_response hawkbit_autohandler_wait(uint32_t events, k_timeout_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Cancel the run of the hawkBit autohandler.
|
||||
*
|
||||
* @return a value from k_work_cancel_delayable().
|
||||
*/
|
||||
int hawkbit_autohandler_cancel(void);
|
||||
|
||||
/**
|
||||
* @brief Set the delay for the next run of the autohandler.
|
||||
*
|
||||
* @details This function will only delay the next run of the autohandler. The delay will not
|
||||
* persist after the autohandler runs.
|
||||
*
|
||||
* @param timeout The delay to set.
|
||||
* @param if_bigger If true, the delay will be set only if the new delay is bigger than the current
|
||||
* one.
|
||||
*
|
||||
* @retval 0 if @a if_bigger was true and the current delay was bigger than the new one.
|
||||
* @retval otherwise, a value from k_work_reschedule().
|
||||
*/
|
||||
int hawkbit_autohandler_set_delay(k_timeout_t timeout, bool if_bigger);
|
||||
|
||||
/**
|
||||
* @brief The hawkBit probe verify if there is some update to be performed.
|
||||
*
|
||||
|
|
@ -330,6 +274,70 @@ uint32_t hawkbit_get_poll_interval(void);
|
|||
int hawkbit_reset_action_id(void);
|
||||
|
||||
/**
|
||||
* @brief hawkBit autohandler.
|
||||
* @defgroup hawkbit_autohandler hawkBit autohandler
|
||||
* @ingroup hawkbit
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Runs hawkBit probe and hawkBit update automatically
|
||||
*
|
||||
* @details The hawkbit_autohandler handles the whole process
|
||||
* in pre-determined time intervals.
|
||||
*
|
||||
* @param auto_reschedule If true, the handler will reschedule itself
|
||||
*/
|
||||
void hawkbit_autohandler(bool auto_reschedule);
|
||||
|
||||
/**
|
||||
* @brief Wait for the autohandler to finish.
|
||||
*
|
||||
* @param events Set of desired events on which to wait. Set to ::UINT32_MAX to wait for the
|
||||
* autohandler to finish one run, or BIT() together with a value from
|
||||
* ::hawkbit_response to wait for a specific event.
|
||||
* @param timeout Waiting period for the desired set of events or one of the
|
||||
* special values ::K_NO_WAIT and ::K_FOREVER.
|
||||
*
|
||||
* @retval HAWKBIT_OK if success.
|
||||
* @retval HAWKBIT_NO_RESPONSE if matching events were not received within the specified time
|
||||
* @retval HAWKBIT_NETWORKING_ERROR fail to connect to the hawkBit server.
|
||||
* @retval HAWKBIT_UNCONFIRMED_IMAGE image is unconfirmed.
|
||||
* @retval HAWKBIT_PERMISSION_ERROR fail to get the permission to access the hawkBit server.
|
||||
* @retval HAWKBIT_METADATA_ERROR fail to parse or to encode the metadata.
|
||||
* @retval HAWKBIT_DOWNLOAD_ERROR fail while downloading the update package.
|
||||
* @retval HAWKBIT_UPDATE_INSTALLED if an update was installed. Reboot is required to apply it.
|
||||
* @retval HAWKBIT_NO_UPDATE if no update was available.
|
||||
* @retval HAWKBIT_CANCEL_UPDATE update was cancelled.
|
||||
* @retval HAWKBIT_NOT_INITIALIZED if hawkBit is not initialized.
|
||||
* @retval HAWKBIT_PROBE_IN_PROGRESS if probe is currently running.
|
||||
*/
|
||||
enum hawkbit_response hawkbit_autohandler_wait(uint32_t events, k_timeout_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Cancel the run of the hawkBit autohandler.
|
||||
*
|
||||
* @return a value from k_work_cancel_delayable().
|
||||
*/
|
||||
int hawkbit_autohandler_cancel(void);
|
||||
|
||||
/**
|
||||
* @brief Set the delay for the next run of the autohandler.
|
||||
*
|
||||
* @details This function will only delay the next run of the autohandler. The delay will not
|
||||
* persist after the autohandler runs.
|
||||
*
|
||||
* @param timeout The delay to set.
|
||||
* @param if_bigger If true, the delay will be set only if the new delay is bigger than the current
|
||||
* one.
|
||||
*
|
||||
* @retval 0 if @a if_bigger was true and the current delay was bigger than the new one.
|
||||
* @retval otherwise, a value from k_work_reschedule().
|
||||
*/
|
||||
int hawkbit_autohandler_set_delay(k_timeout_t timeout, bool if_bigger);
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_HAWKBIT hawkbit.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_HAWKBIT_AUTOHANDLER hawkbit_autohandler.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_HAWKBIT hawkbit_device.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_HAWKBIT hawkbit_firmware.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_HAWKBIT_SHELL shell.c)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ menuconfig HAWKBIT
|
|||
depends on DNS_RESOLVER
|
||||
depends on JSON_LIBRARY
|
||||
depends on BOOTLOADER_MCUBOOT
|
||||
select EVENTS
|
||||
select MPU_ALLOW_FLASH_WRITE
|
||||
select IMG_ENABLE_IMAGE_CHECK
|
||||
select IMG_ERASE_PROGRESSIVELY
|
||||
|
|
@ -34,9 +33,17 @@ config HAWKBIT_POLL_INTERVAL
|
|||
This time interval is zero and 43200 minutes(30 days). This will be overridden
|
||||
by the value configured in the settings of the hawkBit server.
|
||||
|
||||
config HAWKBIT_AUTOHANDLER
|
||||
bool "hawkBit autohandler"
|
||||
select EVENTS
|
||||
default y
|
||||
help
|
||||
Activate autohandler to handle the update process automatically.
|
||||
|
||||
config HAWKBIT_SHELL
|
||||
bool "hawkBit shell utilities"
|
||||
depends on SHELL
|
||||
depends on HAWKBIT_AUTOHANDLER
|
||||
help
|
||||
Activate shell module that provides hawkBit commands.
|
||||
|
||||
|
|
|
|||
|
|
@ -145,13 +145,6 @@ int hawkbit_default_config_data_cb(const char *device_id, uint8_t *buffer,
|
|||
static hawkbit_config_device_data_cb_handler_t hawkbit_config_device_data_cb_handler =
|
||||
hawkbit_default_config_data_cb;
|
||||
|
||||
static void autohandler(struct k_work *work);
|
||||
|
||||
static K_WORK_DELAYABLE_DEFINE(hawkbit_work_handle, autohandler);
|
||||
static K_WORK_DELAYABLE_DEFINE(hawkbit_work_handle_once, autohandler);
|
||||
|
||||
static K_EVENT_DEFINE(hawkbit_autohandler_event);
|
||||
|
||||
K_SEM_DEFINE(probe_sem, 1, 1);
|
||||
|
||||
static const struct json_obj_descr json_href_descr[] = {
|
||||
|
|
@ -1480,110 +1473,3 @@ error:
|
|||
k_sem_give(&probe_sem);
|
||||
return hb_context.code_status;
|
||||
}
|
||||
|
||||
static void autohandler(struct k_work *work)
|
||||
{
|
||||
k_event_clear(&hawkbit_autohandler_event, UINT32_MAX);
|
||||
|
||||
enum hawkbit_response response = hawkbit_probe();
|
||||
|
||||
k_event_set(&hawkbit_autohandler_event, BIT(response));
|
||||
|
||||
switch (response) {
|
||||
case HAWKBIT_UNCONFIRMED_IMAGE:
|
||||
LOG_ERR("Current image is not confirmed");
|
||||
LOG_ERR("Rebooting to previous confirmed image");
|
||||
LOG_ERR("If this image is flashed using a hardware tool");
|
||||
LOG_ERR("Make sure that it is a confirmed image");
|
||||
hawkbit_reboot();
|
||||
break;
|
||||
|
||||
case HAWKBIT_NO_UPDATE:
|
||||
LOG_INF("No update found");
|
||||
break;
|
||||
|
||||
case HAWKBIT_CANCEL_UPDATE:
|
||||
LOG_INF("hawkBit update cancelled from server");
|
||||
break;
|
||||
|
||||
case HAWKBIT_OK:
|
||||
LOG_INF("Image is already updated");
|
||||
break;
|
||||
|
||||
case HAWKBIT_UPDATE_INSTALLED:
|
||||
LOG_INF("Update installed");
|
||||
hawkbit_reboot();
|
||||
break;
|
||||
|
||||
case HAWKBIT_DOWNLOAD_ERROR:
|
||||
LOG_INF("Update failed");
|
||||
break;
|
||||
|
||||
case HAWKBIT_NETWORKING_ERROR:
|
||||
LOG_INF("Network error");
|
||||
break;
|
||||
|
||||
case HAWKBIT_PERMISSION_ERROR:
|
||||
LOG_INF("Permission error");
|
||||
break;
|
||||
|
||||
case HAWKBIT_METADATA_ERROR:
|
||||
LOG_INF("Metadata error");
|
||||
break;
|
||||
|
||||
case HAWKBIT_NOT_INITIALIZED:
|
||||
LOG_INF("hawkBit not initialized");
|
||||
break;
|
||||
|
||||
case HAWKBIT_PROBE_IN_PROGRESS:
|
||||
LOG_INF("hawkBit is already running");
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_ERR("Invalid response: %d", response);
|
||||
break;
|
||||
}
|
||||
|
||||
if (k_work_delayable_from_work(work) == &hawkbit_work_handle) {
|
||||
k_work_reschedule(&hawkbit_work_handle, K_SECONDS(poll_sleep));
|
||||
}
|
||||
}
|
||||
|
||||
enum hawkbit_response hawkbit_autohandler_wait(uint32_t events, k_timeout_t timeout)
|
||||
{
|
||||
uint32_t ret = k_event_wait(&hawkbit_autohandler_event, events, false, timeout);
|
||||
|
||||
for (int i = 1; i < HAWKBIT_PROBE_IN_PROGRESS; i++) {
|
||||
if (ret & BIT(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return HAWKBIT_NO_RESPONSE;
|
||||
}
|
||||
|
||||
int hawkbit_autohandler_cancel(void)
|
||||
{
|
||||
return k_work_cancel_delayable(&hawkbit_work_handle);
|
||||
}
|
||||
|
||||
int hawkbit_autohandler_set_delay(k_timeout_t timeout, bool if_bigger)
|
||||
{
|
||||
if (!if_bigger || timeout.ticks > k_work_delayable_remaining_get(&hawkbit_work_handle)) {
|
||||
hawkbit_autohandler_cancel();
|
||||
LOG_INF("Setting new delay for next run: %02u:%02u:%02u",
|
||||
(uint32_t)(timeout.ticks / CONFIG_SYS_CLOCK_TICKS_PER_SEC) / 3600,
|
||||
(uint32_t)((timeout.ticks / CONFIG_SYS_CLOCK_TICKS_PER_SEC) % 3600) / 60,
|
||||
(uint32_t)(timeout.ticks / CONFIG_SYS_CLOCK_TICKS_PER_SEC) % 60);
|
||||
return k_work_reschedule(&hawkbit_work_handle, timeout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hawkbit_autohandler(bool auto_reschedule)
|
||||
{
|
||||
if (auto_reschedule) {
|
||||
k_work_reschedule(&hawkbit_work_handle, K_NO_WAIT);
|
||||
} else {
|
||||
k_work_reschedule(&hawkbit_work_handle_once, K_NO_WAIT);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
125
subsys/mgmt/hawkbit/hawkbit_autohandler.c
Normal file
125
subsys/mgmt/hawkbit/hawkbit_autohandler.c
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Vogl Electronic GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/mgmt/hawkbit.h>
|
||||
|
||||
LOG_MODULE_DECLARE(hawkbit);
|
||||
|
||||
static void autohandler(struct k_work *work);
|
||||
|
||||
static K_WORK_DELAYABLE_DEFINE(hawkbit_work_handle, autohandler);
|
||||
static K_WORK_DELAYABLE_DEFINE(hawkbit_work_handle_once, autohandler);
|
||||
|
||||
static K_EVENT_DEFINE(hawkbit_autohandler_event);
|
||||
|
||||
static void autohandler(struct k_work *work)
|
||||
{
|
||||
k_event_clear(&hawkbit_autohandler_event, UINT32_MAX);
|
||||
|
||||
enum hawkbit_response response = hawkbit_probe();
|
||||
|
||||
k_event_set(&hawkbit_autohandler_event, BIT(response));
|
||||
|
||||
switch (response) {
|
||||
case HAWKBIT_UNCONFIRMED_IMAGE:
|
||||
LOG_ERR("Current image is not confirmed");
|
||||
LOG_ERR("Rebooting to previous confirmed image");
|
||||
LOG_ERR("If this image is flashed using a hardware tool");
|
||||
LOG_ERR("Make sure that it is a confirmed image");
|
||||
hawkbit_reboot();
|
||||
break;
|
||||
|
||||
case HAWKBIT_NO_UPDATE:
|
||||
LOG_INF("No update found");
|
||||
break;
|
||||
|
||||
case HAWKBIT_CANCEL_UPDATE:
|
||||
LOG_INF("hawkBit update cancelled from server");
|
||||
break;
|
||||
|
||||
case HAWKBIT_OK:
|
||||
LOG_INF("Image is already updated");
|
||||
break;
|
||||
|
||||
case HAWKBIT_UPDATE_INSTALLED:
|
||||
LOG_INF("Update installed");
|
||||
hawkbit_reboot();
|
||||
break;
|
||||
|
||||
case HAWKBIT_DOWNLOAD_ERROR:
|
||||
LOG_INF("Update failed");
|
||||
break;
|
||||
|
||||
case HAWKBIT_NETWORKING_ERROR:
|
||||
LOG_INF("Network error");
|
||||
break;
|
||||
|
||||
case HAWKBIT_PERMISSION_ERROR:
|
||||
LOG_INF("Permission error");
|
||||
break;
|
||||
|
||||
case HAWKBIT_METADATA_ERROR:
|
||||
LOG_INF("Metadata error");
|
||||
break;
|
||||
|
||||
case HAWKBIT_NOT_INITIALIZED:
|
||||
LOG_INF("hawkBit not initialized");
|
||||
break;
|
||||
|
||||
case HAWKBIT_PROBE_IN_PROGRESS:
|
||||
LOG_INF("hawkBit is already running");
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_ERR("Invalid response: %d", response);
|
||||
break;
|
||||
}
|
||||
|
||||
if (k_work_delayable_from_work(work) == &hawkbit_work_handle) {
|
||||
k_work_reschedule(&hawkbit_work_handle, K_SECONDS(hawkbit_get_poll_interval()));
|
||||
}
|
||||
}
|
||||
|
||||
enum hawkbit_response hawkbit_autohandler_wait(uint32_t events, k_timeout_t timeout)
|
||||
{
|
||||
uint32_t ret = k_event_wait(&hawkbit_autohandler_event, events, false, timeout);
|
||||
|
||||
for (int i = 1; i < HAWKBIT_PROBE_IN_PROGRESS; i++) {
|
||||
if (ret & BIT(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return HAWKBIT_NO_RESPONSE;
|
||||
}
|
||||
|
||||
int hawkbit_autohandler_cancel(void)
|
||||
{
|
||||
return k_work_cancel_delayable(&hawkbit_work_handle);
|
||||
}
|
||||
|
||||
int hawkbit_autohandler_set_delay(k_timeout_t timeout, bool if_bigger)
|
||||
{
|
||||
if (!if_bigger || timeout.ticks > k_work_delayable_remaining_get(&hawkbit_work_handle)) {
|
||||
hawkbit_autohandler_cancel();
|
||||
LOG_INF("Setting new delay for next run: %02u:%02u:%02u",
|
||||
(uint32_t)(timeout.ticks / CONFIG_SYS_CLOCK_TICKS_PER_SEC) / 3600,
|
||||
(uint32_t)((timeout.ticks / CONFIG_SYS_CLOCK_TICKS_PER_SEC) % 3600) / 60,
|
||||
(uint32_t)(timeout.ticks / CONFIG_SYS_CLOCK_TICKS_PER_SEC) % 60);
|
||||
return k_work_reschedule(&hawkbit_work_handle, timeout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hawkbit_autohandler(bool auto_reschedule)
|
||||
{
|
||||
if (auto_reschedule) {
|
||||
k_work_reschedule(&hawkbit_work_handle, K_NO_WAIT);
|
||||
} else {
|
||||
k_work_reschedule(&hawkbit_work_handle_once, K_NO_WAIT);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue