From 56e02a8eaa36f52e8fb2ee5e2053d42f95673fcf Mon Sep 17 00:00:00 2001 From: Joel Guittet Date: Mon, 25 Sep 2023 23:42:48 +0200 Subject: [PATCH 1/3] rtos: permit modification of the work period after startingthe work --- include/mender-rtos.h | 8 ++++++++ platform/rtos/freertos/src/mender-rtos.c | 18 ++++++++++++++++++ platform/rtos/posix/src/mender-rtos.c | 22 ++++++++++++++++++++++ platform/rtos/zephyr/src/mender-rtos.c | 15 +++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/include/mender-rtos.h b/include/mender-rtos.h index 46893f6..2ad0314 100755 --- a/include/mender-rtos.h +++ b/include/mender-rtos.h @@ -64,6 +64,14 @@ mender_err_t mender_rtos_work_create(mender_rtos_work_params_t *work_params, voi */ mender_err_t mender_rtos_work_activate(void *handle); +/** + * @brief Function used to set work period + * @param handle Work handle + * @param period Work period (seconds) + * @return MENDER_OK if the function succeeds, error code otherwise + */ +mender_err_t mender_rtos_work_set_period(void *handle, uint32_t period); + /** * @brief Function used to deactivate a work * @param handle Work handle diff --git a/platform/rtos/freertos/src/mender-rtos.c b/platform/rtos/freertos/src/mender-rtos.c index 8d5004f..0a553ae 100755 --- a/platform/rtos/freertos/src/mender-rtos.c +++ b/platform/rtos/freertos/src/mender-rtos.c @@ -196,6 +196,24 @@ mender_rtos_work_activate(void *handle) { return MENDER_OK; } +mender_err_t +mender_rtos_work_set_period(void *handle, uint32_t period) { + + assert(NULL != handle); + + /* Get work context */ + mender_rtos_work_context_t *work_context = (mender_rtos_work_context_t *)handle; + + /* Set timer period */ + work_context->params.period = period; + if (pdPASS != xTimerChangePeriod(work_context->timer_handle, (1000 * work_context->params.period) / portTICK_PERIOD_MS, portMAX_DELAY)) { + mender_log_error("Unable to change timer period"); + return MENDER_FAIL; + } + + return MENDER_OK; +} + mender_err_t mender_rtos_work_deactivate(void *handle) { diff --git a/platform/rtos/posix/src/mender-rtos.c b/platform/rtos/posix/src/mender-rtos.c index f94700e..aaecbc7 100644 --- a/platform/rtos/posix/src/mender-rtos.c +++ b/platform/rtos/posix/src/mender-rtos.c @@ -226,6 +226,28 @@ mender_rtos_work_activate(void *handle) { return MENDER_OK; } +mender_err_t +mender_rtos_work_set_period(void *handle, uint32_t period) { + + assert(NULL != handle); + + /* Get work context */ + mender_rtos_work_context_t *work_context = (mender_rtos_work_context_t *)handle; + + /* Set timer period */ + work_context->params.period = period; + struct itimerspec its; + memset(&its, 0, sizeof(struct itimerspec)); + its.it_value.tv_sec = work_context->params.period; + its.it_interval.tv_sec = work_context->params.period; + if (0 != timer_settime(work_context->timer_handle, 0, &its, NULL)) { + mender_log_error("Unable to set timer period"); + return MENDER_FAIL; + } + + return MENDER_OK; +} + mender_err_t mender_rtos_work_deactivate(void *handle) { diff --git a/platform/rtos/zephyr/src/mender-rtos.c b/platform/rtos/zephyr/src/mender-rtos.c index 6d79c0c..d903777 100644 --- a/platform/rtos/zephyr/src/mender-rtos.c +++ b/platform/rtos/zephyr/src/mender-rtos.c @@ -162,6 +162,21 @@ mender_rtos_work_activate(void *handle) { return MENDER_OK; } +mender_err_t +mender_rtos_work_set_period(void *handle, uint32_t period) { + + assert(NULL != handle); + + /* Get work context */ + mender_rtos_work_context_t *work_context = (mender_rtos_work_context_t *)handle; + + /* Set timer period */ + work_context->params.period = period; + k_timer_start(&work_context->timer_handle, K_NO_WAIT, K_MSEC(1000 * work_context->params.period)); + + return MENDER_OK; +} + mender_err_t mender_rtos_work_deactivate(void *handle) { From 0af81e3c102b32fb4f3d3ff306732d74ac5a5131 Mon Sep 17 00:00:00 2001 From: Joel Guittet Date: Mon, 25 Sep 2023 23:43:16 +0200 Subject: [PATCH 2/3] client: introduce state machine, remove unused works --- core/src/mender-client.c | 123 +++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/core/src/mender-client.c b/core/src/mender-client.c index e8f9050..83988ec 100644 --- a/core/src/mender-client.c +++ b/core/src/mender-client.c @@ -70,6 +70,20 @@ static mender_client_config_t mender_client_config; */ static mender_client_callbacks_t mender_client_callbacks; +/** + * @brief Mender client states + */ +typedef enum { + MENDER_CLIENT_STATE_INITIALIZATION, /**< Perform initialization */ + MENDER_CLIENT_STATE_AUTHENTICATION, /**< Perform authentication with the server */ + MENDER_CLIENT_STATE_AUTHENTICATED, /**< Perform updates */ +} mender_client_state_t; + +/** + * @brief Mender client state + */ +static mender_client_state_t mender_client_state = MENDER_CLIENT_STATE_INITIALIZATION; + /** * @brief Authentication keys */ @@ -85,17 +99,21 @@ static char *mender_client_ota_id = NULL; static char *mender_client_ota_artifact_name = NULL; /** - * @brief Mender client work handles + * @brief Mender client work handle */ -static void *mender_client_initialization_work_handle = NULL; -static void *mender_client_authentication_work_handle = NULL; -static void *mender_client_update_work_handle = NULL; +static void *mender_client_work_handle = NULL; /** * @brief OTA handle used to store temporary reference to write OTA data */ static void *mender_client_ota_handle = NULL; +/** + * @brief Mender client work function + * @return MENDER_OK if the function succeeds, error code otherwise + */ +static mender_err_t mender_client_work_function(void); + /** * @brief Mender client initialization work function * @return MENDER_OK if the function succeeds, error code otherwise @@ -210,35 +228,19 @@ mender_client_init(mender_client_config_t *config, mender_client_callbacks_t *ca return ret; } - /* Create mender client works */ - mender_rtos_work_params_t initialization_work_params; - initialization_work_params.function = mender_client_initialization_work_function; - initialization_work_params.period = mender_client_config.authentication_poll_interval; - initialization_work_params.name = "mender_client_initialization"; - if (MENDER_OK != (ret = mender_rtos_work_create(&initialization_work_params, &mender_client_initialization_work_handle))) { - mender_log_error("Unable to create initialization work"); - return ret; - } - mender_rtos_work_params_t authentication_work_params; - authentication_work_params.function = mender_client_authentication_work_function; - authentication_work_params.period = mender_client_config.authentication_poll_interval; - authentication_work_params.name = "mender_client_authentication"; - if (MENDER_OK != (ret = mender_rtos_work_create(&authentication_work_params, &mender_client_authentication_work_handle))) { - mender_log_error("Unable to create authentication work"); - return ret; - } + /* Create mender client work */ mender_rtos_work_params_t update_work_params; - update_work_params.function = mender_client_update_work_function; - update_work_params.period = mender_client_config.update_poll_interval; + update_work_params.function = mender_client_work_function; + update_work_params.period = mender_client_config.authentication_poll_interval; update_work_params.name = "mender_client_update"; - if (MENDER_OK != (ret = mender_rtos_work_create(&update_work_params, &mender_client_update_work_handle))) { + if (MENDER_OK != (ret = mender_rtos_work_create(&update_work_params, &mender_client_work_handle))) { mender_log_error("Unable to create update work"); return ret; } - /* Activate initialization work */ - if (MENDER_OK != (ret = mender_rtos_work_activate(mender_client_initialization_work_handle))) { - mender_log_error("Unable to activate initialization work"); + /* Activate update work */ + if (MENDER_OK != (ret = mender_rtos_work_activate(mender_client_work_handle))) { + mender_log_error("Unable to activate update work"); return ret; } @@ -248,18 +250,12 @@ mender_client_init(mender_client_config_t *config, mender_client_callbacks_t *ca mender_err_t mender_client_exit(void) { - /* Deactivate mender client works */ - mender_rtos_work_deactivate(mender_client_initialization_work_handle); - mender_rtos_work_deactivate(mender_client_authentication_work_handle); - mender_rtos_work_deactivate(mender_client_update_work_handle); + /* Deactivate mender client work */ + mender_rtos_work_deactivate(mender_client_work_handle); - /* Delete mender client works */ - mender_rtos_work_delete(mender_client_initialization_work_handle); - mender_client_initialization_work_handle = NULL; - mender_rtos_work_delete(mender_client_authentication_work_handle); - mender_client_authentication_work_handle = NULL; - mender_rtos_work_delete(mender_client_update_work_handle); - mender_client_update_work_handle = NULL; + /* Delete mender client work */ + mender_rtos_work_delete(mender_client_work_handle); + mender_client_work_handle = NULL; /* Release all modules */ mender_api_exit(); @@ -298,6 +294,45 @@ mender_client_exit(void) { return MENDER_OK; } +static mender_err_t +mender_client_work_function(void) { + + mender_err_t ret = MENDER_OK; + + /* Work depending of the client state */ + if (MENDER_CLIENT_STATE_INITIALIZATION == mender_client_state) { + /* Perform initialization of the client */ + if (MENDER_DONE != (ret = mender_client_initialization_work_function())) { + goto END; + } + /* Update client state */ + mender_client_state = MENDER_CLIENT_STATE_AUTHENTICATION; + } + /* Intentional pass-through */ + if (MENDER_CLIENT_STATE_AUTHENTICATION == mender_client_state) { + /* Perform authentication with the server */ + if (MENDER_DONE != (ret = mender_client_authentication_work_function())) { + goto END; + } + /* Update work period */ + if (MENDER_OK != (ret = mender_rtos_work_set_period(mender_client_work_handle, mender_client_config.update_poll_interval))) { + mender_log_error("Unable to set work period"); + goto END; + } + /* Update client state */ + mender_client_state = MENDER_CLIENT_STATE_AUTHENTICATED; + } + /* Intentional pass-through */ + if (MENDER_CLIENT_STATE_AUTHENTICATED == mender_client_state) { + /* Perform updates */ + ret = mender_client_update_work_function(); + } + +END: + + return ret; +} + static mender_err_t mender_client_initialization_work_function(void) { @@ -344,12 +379,6 @@ mender_client_initialization_work_function(void) { } } - /* Activate authentication work */ - if (MENDER_OK != (ret = mender_rtos_work_activate(mender_client_authentication_work_handle))) { - mender_log_error("Unable to activate authentication work"); - return ret; - } - return MENDER_DONE; } @@ -413,12 +442,6 @@ mender_client_authentication_work_function(void) { mender_storage_delete_ota_deployment(); } - /* Activate update work */ - if (MENDER_OK != (ret = mender_rtos_work_activate(mender_client_update_work_handle))) { - mender_log_error("Unable to activate update work"); - return ret; - } - return MENDER_DONE; REBOOT: From d35633ea3eec94e06984d0b19f9cd3bd21add29d Mon Sep 17 00:00:00 2001 From: Joel Guittet Date: Tue, 26 Sep 2023 00:00:33 +0200 Subject: [PATCH 3/3] client: fix typo --- include/mender-client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mender-client.h b/include/mender-client.h index fa7cad9..4852927 100755 --- a/include/mender-client.h +++ b/include/mender-client.h @@ -60,7 +60,7 @@ typedef struct { mender_err_t (*ota_abort)(void *); /**< Invoked to abort current OTA */ mender_err_t (*ota_end)(void *); /**< Invoked to indicate the end of the artifact */ mender_err_t (*ota_set_boot_partition)(void *); /**< Invoked to set the new boot parition to be used on the next restart */ - mender_err_t (*restart)(void); /**< Invoked to restart the devide */ + mender_err_t (*restart)(void); /**< Invoked to restart the device */ } mender_client_callbacks_t; /**