diff --git a/include/zephyr/mgmt/hawkbit.h b/include/zephyr/mgmt/hawkbit.h index 46a0ff34328b7a3..f46b8bc7abc3e56 100644 --- a/include/zephyr/mgmt/hawkbit.h +++ b/include/zephyr/mgmt/hawkbit.h @@ -24,6 +24,7 @@ * */ enum hawkbit_response { + HAWKBIT_NO_RESPONSE, HAWKBIT_NETWORKING_ERROR, HAWKBIT_UNCONFIRMED_IMAGE, HAWKBIT_PERMISSION_ERROR, @@ -48,8 +49,30 @@ int hawkbit_init(void); * * @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 + * @param timeout Waiting period for the desired set of events or one of the + * special values K_NO_WAIT and K_FOREVER. + * + * @return HAWKBIT_NO_RESPONSE if matching events were not received within the specified time + * @return HAWKBIT_NETWORKING_ERROR fail to connect to the hawkBit server. + * @return HAWKBIT_UNCONFIRMED_IMAGE image is unconfirmed. + * @return HAWKBIT_PERMISSION_ERROR fail to get the permission to access the hawkBit server. + * @return HAWKBIT_METADATA_ERROR fail to parse or to encode the metadata. + * @return HAWKBIT_DOWNLOAD_ERROR fail while downloading the update package. + * @return HAWKBIT_OK if success. + * @return HAWKBIT_UPDATE_INSTALLED has an update available. + * @return HAWKBIT_NO_UPDATE no update available. + * @return HAWKBIT_CANCEL_UPDATE update was cancelled. */ -void hawkbit_autohandler(void); +enum hawkbit_response hawkbit_autohandler_wait(uint32_t events, k_timeout_t timeout); /** * @brief The hawkBit probe verify if there is some update to be performed. diff --git a/subsys/mgmt/hawkbit/Kconfig b/subsys/mgmt/hawkbit/Kconfig index e2365cf3c1d7700..2621dde4a6dc58e 100644 --- a/subsys/mgmt/hawkbit/Kconfig +++ b/subsys/mgmt/hawkbit/Kconfig @@ -15,6 +15,7 @@ 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 diff --git a/subsys/mgmt/hawkbit/hawkbit.c b/subsys/mgmt/hawkbit/hawkbit.c index 3f5d5a8db1fc95d..4ae67f2d5a682ba 100644 --- a/subsys/mgmt/hawkbit/hawkbit.c +++ b/subsys/mgmt/hawkbit/hawkbit.c @@ -95,6 +95,9 @@ static union { 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_event); static struct k_sem probe_sem; @@ -1188,7 +1191,13 @@ enum hawkbit_response hawkbit_probe(void) static void autohandler(struct k_work *work) { - switch (hawkbit_probe()) { + k_event_clear(&hawkbit_event, __UINT32_MAX__); + + enum hawkbit_response response = hawkbit_probe(); + + k_event_set(&hawkbit_event, BIT(response)); + + switch (response) { case HAWKBIT_UNCONFIRMED_IMAGE: LOG_ERR("Current image is not confirmed"); LOG_ERR("Rebooting to previous confirmed image"); @@ -1233,12 +1242,34 @@ static void autohandler(struct k_work *work) 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_event, events, false, timeout); - k_work_reschedule(&hawkbit_work_handle, K_SECONDS(poll_sleep)); + for (int i = HAWKBIT_NETWORKING_ERROR; i < HAWKBIT_PROBE_IN_PROGRESS; i++) { + if (ret & BIT(i)) { + return i; + } + } + return HAWKBIT_NO_RESPONSE; } -void hawkbit_autohandler(void) +void hawkbit_autohandler(bool auto_reschedule) { - k_work_reschedule(&hawkbit_work_handle, K_NO_WAIT); + if (auto_reschedule) { + k_work_reschedule(&hawkbit_work_handle, K_NO_WAIT); + } else { + k_work_reschedule(&hawkbit_work_handle_once, K_NO_WAIT); + } }