/* * Copyright (c) 2021 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include "bootutil/bootutil_log.h" #include "../boot_serial/src/boot_serial_priv.h" #include "../boot_serial/src/cbor_encode.h" #include "bootutil/image.h" #include "bootutil/bootutil_public.h" #include "bootutil/boot_hooks.h" BOOT_LOG_MODULE_DECLARE(mcuboot); #ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE static int bs_custom_storage_erase(cbor_state_t *cs) { int rc; const struct flash_area *fa; rc = flash_area_open(FLASH_AREA_ID(storage), &fa); if (rc < 0) { BOOT_LOG_ERR("failed to open flash area"); } else { rc = flash_area_erase(fa, 0, FLASH_AREA_SIZE(storage)); if (rc < 0) { BOOT_LOG_ERR("failed to erase flash area"); } flash_area_close(fa); } if (rc == 0) { rc = MGMT_ERR_OK; } else { rc = MGMT_ERR_EUNKNOWN; } map_start_encode(cs, 10); tstrx_put(cs, "rc"); uintx32_put(cs, rc); map_end_encode(cs, 10); return rc; } #endif #ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST static int custom_img_status(int image_index, uint32_t slot,char *buffer, ssize_t len) { uint32_t area_id; struct flash_area const *fap; struct image_header hdr; int rc; int img_install_stat; rc = BOOT_HOOK_CALL(boot_img_install_stat_hook, BOOT_HOOK_REGULAR, image_index, slot, &img_install_stat); if (rc == BOOT_HOOK_REGULAR) { img_install_stat = 0; } rc = BOOT_HOOK_CALL(boot_read_image_header_hook, BOOT_HOOK_REGULAR, image_index, slot, &hdr); if (rc == BOOT_HOOK_REGULAR) { area_id = flash_area_id_from_multi_image_slot(image_index, slot); rc = flash_area_open(area_id, &fap); if (rc) { return rc; } rc = flash_area_read(fap, 0, &hdr, sizeof(hdr)); flash_area_close(fap); } if (rc == 0) { if (hdr.ih_magic == IMAGE_MAGIC) { snprintf(buffer, len, "ver=%d.%d.%d.%d,install_stat=%d", hdr.ih_ver.iv_major, hdr.ih_ver.iv_minor, hdr.ih_ver.iv_revision, hdr.ih_ver.iv_build_num, img_install_stat); } else { rc = 1; } } return rc; } static int bs_custom_img_list(cbor_state_t *cs) { int rc = 0; char tmpbuf[64]; /* Buffer should fit version and flags */ map_start_encode(cs, 10); for (int img = 0; img < MCUBOOT_IMAGE_NUMBER; img++) { for (int slot = 0; slot < 2; slot++) { rc = custom_img_status(img, slot, tmpbuf, sizeof(tmpbuf)); intx32_put(cs, img * 2 + slot + 1); if (rc == 0) { tstrx_put_term(cs, tmpbuf); } else { tstrx_put_term(cs, ""); } } } tstrx_put(cs, "rc"); uintx32_put(cs, MGMT_ERR_OK); map_end_encode(cs, 10); return rc; } #ifndef ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST #define ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST 1 #endif #endif /*MCUBOOT_MGMT_CUSTOM_IMG_LIST*/ int bs_peruser_system_specific(const struct nmgr_hdr *hdr, const char *buffer, int len, cbor_state_t *cs) { int mgmt_rc = MGMT_ERR_ENOTSUP; if (hdr->nh_group == ZEPHYR_MGMT_GRP_BASE) { if (hdr->nh_op == NMGR_OP_WRITE) { #ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) { mgmt_rc = bs_custom_storage_erase(cs); } #endif } else if (hdr->nh_op == NMGR_OP_READ) { #ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST) { mgmt_rc = bs_custom_img_list(cs); } #endif } } if (mgmt_rc == MGMT_ERR_ENOTSUP) { map_start_encode(cs, 10); tstrx_put(cs, "rc"); uintx32_put(cs, mgmt_rc); map_end_encode(cs, 10); } return MGMT_ERR_OK; }