/* * Copyright (c) 2018-2021 mcumgr authors * Copyright (c) 2022-2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #ifndef H_IMG_MGMT_ #define H_IMG_MGMT_ #include #include #include #include #include /** * @brief MCUmgr img_mgmt API * @defgroup mcumgr_img_mgmt MCUmgr img_mgmt API * @ingroup mcumgr * @{ */ #ifdef __cplusplus extern "C" { #endif #define IMG_MGMT_DATA_SHA_LEN 32 /* SHA256 */ /** * Image state flags */ #define IMG_MGMT_STATE_F_PENDING 0x01 #define IMG_MGMT_STATE_F_CONFIRMED 0x02 #define IMG_MGMT_STATE_F_ACTIVE 0x04 #define IMG_MGMT_STATE_F_PERMANENT 0x08 /* 255.255.65535.4294967295\0 */ #define IMG_MGMT_VER_MAX_STR_LEN (sizeof("255.255.65535.4294967295")) /** * Swap Types for image management state machine */ #define IMG_MGMT_SWAP_TYPE_NONE 0 #define IMG_MGMT_SWAP_TYPE_TEST 1 #define IMG_MGMT_SWAP_TYPE_PERM 2 #define IMG_MGMT_SWAP_TYPE_REVERT 3 #define IMG_MGMT_SWAP_TYPE_UNKNOWN 255 /** * Command IDs for image management group. */ #define IMG_MGMT_ID_STATE 0 #define IMG_MGMT_ID_UPLOAD 1 #define IMG_MGMT_ID_FILE 2 #define IMG_MGMT_ID_CORELIST 3 #define IMG_MGMT_ID_CORELOAD 4 #define IMG_MGMT_ID_ERASE 5 #define IMG_MGMT_ID_SLOT_INFO 6 /** * Command result codes for image management group. */ enum img_mgmt_err_code_t { /** No error, this is implied if there is no ret value in the response */ IMG_MGMT_ERR_OK = 0, /** Unknown error occurred. */ IMG_MGMT_ERR_UNKNOWN, /** Failed to query flash area configuration. */ IMG_MGMT_ERR_FLASH_CONFIG_QUERY_FAIL, /** There is no image in the slot. */ IMG_MGMT_ERR_NO_IMAGE, /** The image in the slot has no TLVs (tag, length, value). */ IMG_MGMT_ERR_NO_TLVS, /** The image in the slot has an invalid TLV type and/or length. */ IMG_MGMT_ERR_INVALID_TLV, /** The image in the slot has multiple hash TLVs, which is invalid. */ IMG_MGMT_ERR_TLV_MULTIPLE_HASHES_FOUND, /** The image in the slot has an invalid TLV size. */ IMG_MGMT_ERR_TLV_INVALID_SIZE, /** The image in the slot does not have a hash TLV, which is required. */ IMG_MGMT_ERR_HASH_NOT_FOUND, /** There is no free slot to place the image. */ IMG_MGMT_ERR_NO_FREE_SLOT, /** Flash area opening failed. */ IMG_MGMT_ERR_FLASH_OPEN_FAILED, /** Flash area reading failed. */ IMG_MGMT_ERR_FLASH_READ_FAILED, /** Flash area writing failed. */ IMG_MGMT_ERR_FLASH_WRITE_FAILED, /** Flash area erase failed. */ IMG_MGMT_ERR_FLASH_ERASE_FAILED, /** The provided slot is not valid. */ IMG_MGMT_ERR_INVALID_SLOT, /** Insufficient heap memory (malloc failed). */ IMG_MGMT_ERR_NO_FREE_MEMORY, /** The flash context is already set. */ IMG_MGMT_ERR_FLASH_CONTEXT_ALREADY_SET, /** The flash context is not set. */ IMG_MGMT_ERR_FLASH_CONTEXT_NOT_SET, /** The device for the flash area is NULL. */ IMG_MGMT_ERR_FLASH_AREA_DEVICE_NULL, /** The offset for a page number is invalid. */ IMG_MGMT_ERR_INVALID_PAGE_OFFSET, /** The offset parameter was not provided and is required. */ IMG_MGMT_ERR_INVALID_OFFSET, /** The length parameter was not provided and is required. */ IMG_MGMT_ERR_INVALID_LENGTH, /** The image length is smaller than the size of an image header. */ IMG_MGMT_ERR_INVALID_IMAGE_HEADER, /** The image header magic value does not match the expected value. */ IMG_MGMT_ERR_INVALID_IMAGE_HEADER_MAGIC, /** The hash parameter provided is not valid. */ IMG_MGMT_ERR_INVALID_HASH, /** The image load address does not match the address of the flash area. */ IMG_MGMT_ERR_INVALID_FLASH_ADDRESS, /** Failed to get version of currently running application. */ IMG_MGMT_ERR_VERSION_GET_FAILED, /** The currently running application is newer than the version being uploaded. */ IMG_MGMT_ERR_CURRENT_VERSION_IS_NEWER, /** There is already an image operating pending. */ IMG_MGMT_ERR_IMAGE_ALREADY_PENDING, /** The image vector table is invalid. */ IMG_MGMT_ERR_INVALID_IMAGE_VECTOR_TABLE, /** The image it too large to fit. */ IMG_MGMT_ERR_INVALID_IMAGE_TOO_LARGE, /** The amount of data sent is larger than the provided image size. */ IMG_MGMT_ERR_INVALID_IMAGE_DATA_OVERRUN, /** Confirmation of image has been denied */ IMG_MGMT_ERR_IMAGE_CONFIRMATION_DENIED, /** Setting test to active slot is not allowed */ IMG_MGMT_ERR_IMAGE_SETTING_TEST_TO_ACTIVE_DENIED, /** Current active slot for image cannot be determined */ IMG_MGMT_ERR_ACTIVE_SLOT_NOT_KNOWN, }; /** * IMG_MGMT_ID_UPLOAD statuses. */ enum img_mgmt_id_upload_t { IMG_MGMT_ID_UPLOAD_STATUS_START = 0, IMG_MGMT_ID_UPLOAD_STATUS_ONGOING, IMG_MGMT_ID_UPLOAD_STATUS_COMPLETE, }; extern int boot_current_slot; extern struct img_mgmt_state g_img_mgmt_state; /** Represents an individual upload request. */ struct img_mgmt_upload_req { uint32_t image; /* 0 by default */ size_t off; /* SIZE_MAX if unspecified */ size_t size; /* SIZE_MAX if unspecified */ struct zcbor_string img_data; struct zcbor_string data_sha; bool upgrade; /* Only allow greater version numbers. */ }; /** Global state for upload in progress. */ struct img_mgmt_state { /** Flash area being written; -1 if no upload in progress. */ int area_id; /** Flash offset of next chunk. */ size_t off; /** Total size of image data. */ size_t size; /** Hash of image data; used for resumption of a partial upload. */ uint8_t data_sha_len; uint8_t data_sha[IMG_MGMT_DATA_SHA_LEN]; }; /** Describes what to do during processing of an upload request. */ struct img_mgmt_upload_action { /** The total size of the image. */ unsigned long long size; /** The number of image bytes to write to flash. */ int write_bytes; /** The flash area to write to. */ int area_id; /** Whether to process the request; false if offset is wrong. */ bool proceed; /** Whether to erase the destination flash area. */ bool erase; #ifdef CONFIG_MCUMGR_GRP_IMG_VERBOSE_ERR /** "rsn" string to be sent as explanation for "rc" code */ const char *rc_rsn; #endif }; /* * @brief Read info of an image at the specified slot number * * @param image_slot image slot number * @param ver output buffer for image version * @param hash output buffer for image hash * @param flags output buffer for image flags * * @return 0 on success, non-zero on failure. */ int img_mgmt_read_info(int image_slot, struct image_version *ver, uint8_t *hash, uint32_t *flags); /** * @brief Get the image version of the currently running application. * * @param ver output buffer for an image version information object. * * @return 0 on success, non-zero on failure. */ int img_mgmt_my_version(struct image_version *ver); /** * @brief Format version string from struct image_version * * @param ver pointer to image_version object * @param dst output buffer for image version string * * @return Non-negative on success, negative value on error. */ int img_mgmt_ver_str(const struct image_version *ver, char *dst); /** * @brief Get active, running application slot number for an image * * @param image image number to get active slot for. * * @return Non-negative slot number */ int img_mgmt_active_slot(int image); /** * @brief Get active image number * * Gets 0 based number for running application. * * @return Non-negative image number. */ int img_mgmt_active_image(void); /** * @brief Check if the image slot is in use. * * The check is based on MCUboot flags, not image contents. This means that * slot with image in it, but no bootable flags set, is considered empty. * Active slot is always in use. * * @param slot slot number * * @return 0 if slot is not used, non-0 otherwise. */ int img_mgmt_slot_in_use(int slot); /** * @brief Check if any slot is in MCUboot pending state. * * Function returns 1 if slot 0 or slot 1 is in MCUboot pending state, * which means that it has been either marked for test or confirmed. * * @return 1 if there's pending DFU otherwise 0. */ int img_mgmt_state_any_pending(void); /** * @brief Returns state flags set to slot. * * Flags are translated from MCUboot image state flags. * Returned value is zero if no flags are set or a combination of: * IMG_MGMT_STATE_F_PENDING * IMG_MGMT_STATE_F_CONFIRMED * IMG_MGMT_STATE_F_ACTIVE * IMG_MGMT_STATE_F_PERMANENT * * @param query_slot slot number * * @return return the state flags. * */ uint8_t img_mgmt_state_flags(int query_slot); /** * @brief Sets the pending flag for the specified image slot. * * Sets specified image slot to be used as active slot during next boot, * either for test or permanently. Non-permanent image will be reverted * unless image confirms itself during next boot. * * @param slot slot number * @param permanent permanent or test only * * @return 0 on success, non-zero on failure */ int img_mgmt_state_set_pending(int slot, int permanent); /** * @brief Confirms the current image state. * * Prevents a fallback from occurring on the next reboot if the active image * is currently being tested. * * @return 0 on success, non-zero on failure */ int img_mgmt_state_confirm(void); /** * Compares two image version numbers in a semver-compatible way. * * @param a The first version to compare * @param b The second version to compare * * @return -1 if a < b * @return 0 if a = b * @return 1 if a > b */ int img_mgmt_vercmp(const struct image_version *a, const struct image_version *b); #if defined(CONFIG_MCUMGR_GRP_IMG_MUTEX) /* * @brief Will reset the image management state back to default (no ongoing upload), * requires that CONFIG_MCUMGR_GRP_IMG_MUTEX be enabled to allow for mutex * locking of the image management state object. */ void img_mgmt_reset_upload(void); #endif #ifdef CONFIG_MCUMGR_GRP_IMG_VERBOSE_ERR #define IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, rsn) ((action)->rc_rsn = (rsn)) #define IMG_MGMT_UPLOAD_ACTION_RC_RSN(action) ((action)->rc_rsn) int img_mgmt_error_rsp(struct smp_streamer *ctxt, int rc, const char *rsn); extern const char *img_mgmt_err_str_app_reject; extern const char *img_mgmt_err_str_hdr_malformed; extern const char *img_mgmt_err_str_magic_mismatch; extern const char *img_mgmt_err_str_no_slot; extern const char *img_mgmt_err_str_flash_open_failed; extern const char *img_mgmt_err_str_flash_erase_failed; extern const char *img_mgmt_err_str_flash_write_failed; extern const char *img_mgmt_err_str_downgrade; extern const char *img_mgmt_err_str_image_bad_flash_addr; extern const char *img_mgmt_err_str_image_too_large; extern const char *img_mgmt_err_str_data_overrun; #else #define IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, rsn) #define IMG_MGMT_UPLOAD_ACTION_RC_RSN(action) NULL #endif /** * @} */ #ifdef __cplusplus } #endif #endif /* H_IMG_MGMT_ */