blob: b8bcd3e952919b91bef545f0a7114647a144d50a [file] [log] [blame]
Dominik Ermel3d51e432021-06-25 17:29:50 +00001/*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
Jamie McCraee188dbb2023-08-29 07:43:16 +01007#include <stdio.h>
Gerard Marull-Paretas34dd9e72022-05-09 12:13:12 +02008#include <zephyr/kernel.h>
Gerard Marull-Paretas3cd2cec2022-05-09 12:10:05 +02009#include <zephyr/drivers/flash.h>
Jamie McCraee188dbb2023-08-29 07:43:16 +010010#include <zephyr/mgmt/mcumgr/mgmt/mgmt_defines.h>
11#include <zephyr/mgmt/mcumgr/grp/zephyr/zephyr_basic.h>
12#include <../subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h>
Dominik Ermel3d51e432021-06-25 17:29:50 +000013
14#include <flash_map_backend/flash_map_backend.h>
15#include <sysflash/sysflash.h>
16
17#include "bootutil/bootutil_log.h"
18#include "../boot_serial/src/boot_serial_priv.h"
Dominik Ermele6e48012023-06-19 11:37:20 +000019#include <zcbor_encode.h>
Dominik Ermel3d51e432021-06-25 17:29:50 +000020
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020021#include "bootutil/image.h"
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020022#include "bootutil/bootutil_public.h"
23#include "bootutil/boot_hooks.h"
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020024
Andrzej Puzdrowskid16598f2022-01-10 10:49:09 +010025BOOT_LOG_MODULE_DECLARE(mcuboot);
Dominik Ermel3d51e432021-06-25 17:29:50 +000026
Dominik Ermel0435d5d2021-08-16 15:58:15 +000027#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
Dominik Ermel864d1042022-07-12 12:41:39 +000028static int bs_custom_storage_erase(zcbor_state_t *cs)
Dominik Ermel3d51e432021-06-25 17:29:50 +000029{
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020030 int rc;
Dominik Ermel3d51e432021-06-25 17:29:50 +000031
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020032 const struct flash_area *fa;
Dominik Ermel97b4c792021-06-25 17:32:38 +000033
Dominik Ermel2c539342022-08-24 14:37:11 +000034 rc = flash_area_open(FIXED_PARTITION_ID(storage_partition), &fa);
Dominik Ermel97b4c792021-06-25 17:32:38 +000035
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020036 if (rc < 0) {
Andrzej Puzdrowskid16598f2022-01-10 10:49:09 +010037 BOOT_LOG_ERR("failed to open flash area");
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020038 } else {
Dominik Ermel2c539342022-08-24 14:37:11 +000039 rc = flash_area_erase(fa, 0, flash_area_get_size(fa));
Dominik Ermel97b4c792021-06-25 17:32:38 +000040 if (rc < 0) {
Andrzej Puzdrowskid16598f2022-01-10 10:49:09 +010041 BOOT_LOG_ERR("failed to erase flash area");
Dominik Ermel97b4c792021-06-25 17:32:38 +000042 }
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020043 flash_area_close(fa);
44 }
45 if (rc == 0) {
46 rc = MGMT_ERR_OK;
47 } else {
48 rc = MGMT_ERR_EUNKNOWN;
Dominik Ermel3d51e432021-06-25 17:29:50 +000049 }
50
Dominik Ermel864d1042022-07-12 12:41:39 +000051 zcbor_map_start_encode(cs, 10);
52 zcbor_tstr_put_lit(cs, "rc");
53 zcbor_uint32_put(cs, rc);
54 zcbor_map_end_encode(cs, 10);
Dominik Ermel3d51e432021-06-25 17:29:50 +000055
56 return rc;
57}
Dominik Ermel0435d5d2021-08-16 15:58:15 +000058#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020059
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +020060#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020061static int custom_img_status(int image_index, uint32_t slot,char *buffer,
62 ssize_t len)
63{
64 uint32_t area_id;
65 struct flash_area const *fap;
66 struct image_header hdr;
67 int rc;
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020068 int img_install_stat;
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020069
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020070 rc = BOOT_HOOK_CALL(boot_img_install_stat_hook, BOOT_HOOK_REGULAR,
71 image_index, slot, &img_install_stat);
72 if (rc == BOOT_HOOK_REGULAR)
73 {
74 img_install_stat = 0;
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020075 }
76
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020077 rc = BOOT_HOOK_CALL(boot_read_image_header_hook, BOOT_HOOK_REGULAR,
78 image_index, slot, &hdr);
79 if (rc == BOOT_HOOK_REGULAR)
80 {
81 area_id = flash_area_id_from_multi_image_slot(image_index, slot);
82
83 rc = flash_area_open(area_id, &fap);
84 if (rc) {
85 return rc;
86 }
87
88 rc = flash_area_read(fap, 0, &hdr, sizeof(hdr));
89
90 flash_area_close(fap);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020091 }
92
Andrzej Puzdrowski2a29f5d2021-07-30 16:22:22 +020093 if (rc == 0) {
94 if (hdr.ih_magic == IMAGE_MAGIC) {
95 snprintf(buffer, len, "ver=%d.%d.%d.%d,install_stat=%d",
96 hdr.ih_ver.iv_major,
97 hdr.ih_ver.iv_minor,
98 hdr.ih_ver.iv_revision,
99 hdr.ih_ver.iv_build_num,
100 img_install_stat);
101 } else {
102 rc = 1;
103 }
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200104 }
105
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200106 return rc;
107}
108
Dominik Ermel864d1042022-07-12 12:41:39 +0000109static int bs_custom_img_list(zcbor_state_t *cs)
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200110{
111 int rc = 0;
112 char tmpbuf[64]; /* Buffer should fit version and flags */
113
Dominik Ermel864d1042022-07-12 12:41:39 +0000114 zcbor_map_start_encode(cs, 10);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200115
116 for (int img = 0; img < MCUBOOT_IMAGE_NUMBER; img++) {
117 for (int slot = 0; slot < 2; slot++) {
118 rc = custom_img_status(img, slot, tmpbuf, sizeof(tmpbuf));
119
Dominik Ermel864d1042022-07-12 12:41:39 +0000120 zcbor_int32_put(cs, img * 2 + slot + 1);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200121 if (rc == 0) {
Dominik Ermel864d1042022-07-12 12:41:39 +0000122 zcbor_tstr_put_term(cs, tmpbuf);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200123 } else {
Dominik Ermel864d1042022-07-12 12:41:39 +0000124 zcbor_tstr_put_lit(cs, "");
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200125 }
126 }
127 }
128
Dominik Ermel864d1042022-07-12 12:41:39 +0000129 zcbor_tstr_put_lit(cs, "rc");
130 zcbor_uint32_put(cs, MGMT_ERR_OK);
131 zcbor_map_end_encode(cs, 10);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200132
133 return rc;
134}
135
136#ifndef ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST
137 #define ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST 1
138#endif
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200139#endif /*MCUBOOT_MGMT_CUSTOM_IMG_LIST*/
140
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200141int bs_peruser_system_specific(const struct nmgr_hdr *hdr, const char *buffer,
Dominik Ermel864d1042022-07-12 12:41:39 +0000142 int len, zcbor_state_t *cs)
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200143{
144 int mgmt_rc = MGMT_ERR_ENOTSUP;
145
Jamie McCraee188dbb2023-08-29 07:43:16 +0100146 if (hdr->nh_group == ZEPHYR_MGMT_GRP_BASIC) {
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200147 if (hdr->nh_op == NMGR_OP_WRITE) {
Dominik Ermel0435d5d2021-08-16 15:58:15 +0000148#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200149 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) {
150 mgmt_rc = bs_custom_storage_erase(cs);
151 }
Dominik Ermel0435d5d2021-08-16 15:58:15 +0000152#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200153 } else if (hdr->nh_op == NMGR_OP_READ) {
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200154#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200155 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST) {
156 mgmt_rc = bs_custom_img_list(cs);
157 }
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200158#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200159 }
160 }
161
162 if (mgmt_rc == MGMT_ERR_ENOTSUP) {
Dominik Ermel864d1042022-07-12 12:41:39 +0000163 zcbor_map_start_encode(cs, 10);
164 zcbor_tstr_put_lit(cs, "rc");
165 zcbor_uint32_put(cs, mgmt_rc);
166 zcbor_map_end_encode(cs, 10);
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200167 }
168
169 return MGMT_ERR_OK;
170}