blob: 763dedbfc910babf2a6d352c7d6fd51311eced19 [file] [log] [blame]
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <drivers/flash.h>
#include <mgmt/mcumgr/zephyr_groups.h>
#include <flash_map_backend/flash_map_backend.h>
#include <sysflash/sysflash.h>
#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;
}