blob: 35a129b6ad37c40b7d07ca76e679b92ea726d71e [file] [log] [blame]
/*
* Copyright (c) 2018-2021 mcumgr authors
* Copyright (c) 2022-2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef H_IMG_MGMT_
#define H_IMG_MGMT_
#include <inttypes.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zephyr/mgmt/mcumgr/smp/smp.h>
#include <zephyr/mgmt/mcumgr/grp/img_mgmt/image.h>
#include <zcbor_common.h>
/**
* @brief MCUmgr img_mgmt API
* @defgroup mcumgr_img_mgmt MCUmgr img_mgmt API
* @ingroup mcumgr
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
#define IMG_MGMT_HASH_STR 48
#define IMG_MGMT_HASH_LEN 32
#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
/**
* Command result codes for image management group.
*/
enum img_mgmt_ret_code_t {
/** No error, this is implied if there is no ret value in the response */
IMG_MGMT_RET_RC_OK = 0,
/** Unknown error occurred. */
IMG_MGMT_RET_RC_UNKNOWN,
/** Failed to query flash area configuration. */
IMG_MGMT_RET_RC_FLASH_CONFIG_QUERY_FAIL,
/** There is no image in the slot. */
IMG_MGMT_RET_RC_NO_IMAGE,
/** The image in the slot has no TLVs (tag, length, value). */
IMG_MGMT_RET_RC_NO_TLVS,
/** The image in the slot has an invalid TLV type and/or length. */
IMG_MGMT_RET_RC_INVALID_TLV,
/** The image in the slot has multiple hash TLVs, which is invalid. */
IMG_MGMT_RET_RC_TLV_MULTIPLE_HASHES_FOUND,
/** The image in the slot has an invalid TLV size. */
IMG_MGMT_RET_RC_TLV_INVALID_SIZE,
/** The image in the slot does not have a hash TLV, which is required. */
IMG_MGMT_RET_RC_HASH_NOT_FOUND,
/** There is no free slot to place the image. */
IMG_MGMT_RET_RC_NO_FREE_SLOT,
/** Flash area opening failed. */
IMG_MGMT_RET_RC_FLASH_OPEN_FAILED,
/** Flash area reading failed. */
IMG_MGMT_RET_RC_FLASH_READ_FAILED,
/** Flash area writing failed. */
IMG_MGMT_RET_RC_FLASH_WRITE_FAILED,
/** Flash area erase failed. */
IMG_MGMT_RET_RC_FLASH_ERASE_FAILED,
/** The provided slot is not valid. */
IMG_MGMT_RET_RC_INVALID_SLOT,
/** Insufficient heap memory (malloc failed). */
IMG_MGMT_RET_RC_NO_FREE_MEMORY,
/** The flash context is already set. */
IMG_MGMT_RET_RC_FLASH_CONTEXT_ALREADY_SET,
/** The flash context is not set. */
IMG_MGMT_RET_RC_FLASH_CONTEXT_NOT_SET,
/** The device for the flash area is NULL. */
IMG_MGMT_RET_RC_FLASH_AREA_DEVICE_NULL,
/** The offset for a page number is invalid. */
IMG_MGMT_RET_RC_INVALID_PAGE_OFFSET,
/** The offset parameter was not provided and is required. */
IMG_MGMT_RET_RC_INVALID_OFFSET,
/** The length parameter was not provided and is required. */
IMG_MGMT_RET_RC_INVALID_LENGTH,
/** The image length is smaller than the size of an image header. */
IMG_MGMT_RET_RC_INVALID_IMAGE_HEADER,
/** The image header magic value does not match the expected value. */
IMG_MGMT_RET_RC_INVALID_IMAGE_HEADER_MAGIC,
/** The hash parameter provided is not valid. */
IMG_MGMT_RET_RC_INVALID_HASH,
/** The image load address does not match the address of the flash area. */
IMG_MGMT_RET_RC_INVALID_FLASH_ADDRESS,
/** Failed to get version of currently running application. */
IMG_MGMT_RET_RC_VERSION_GET_FAILED,
/** The currently running application is newer than the version being uploaded. */
IMG_MGMT_RET_RC_CURRENT_VERSION_IS_NEWER,
/** There is already an image operating pending. */
IMG_MGMT_RET_RC_IMAGE_ALREADY_PENDING,
/** The image vector table is invalid. */
IMG_MGMT_RET_RC_INVALID_IMAGE_VECTOR_TABLE,
};
/**
* 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);
#ifdef CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL
/*
* @brief Translate IMG mgmt group error code into MCUmgr error code
*
* @param ret #img_mgmt_ret_code_t error code
*
* @return #mcumgr_err_t error code
*/
int img_mgmt_translate_error_code(uint16_t ret);
#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;
#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_ */