blob: d3dafee87a71108e673977818130d28a568a413b [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
7#include <zephyr.h>
8#include <drivers/flash.h>
9#include <mgmt/mcumgr/zephyr_groups.h>
10
11#include <flash_map_backend/flash_map_backend.h>
12#include <sysflash/sysflash.h>
13
14#include "bootutil/bootutil_log.h"
15#include "../boot_serial/src/boot_serial_priv.h"
16#include "../boot_serial/src/cbor_encode.h"
17
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020018#include "bootutil/image.h"
19
Dominik Ermel3d51e432021-06-25 17:29:50 +000020MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
21
Dominik Ermel0435d5d2021-08-16 15:58:15 +000022#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020023static int bs_custom_storage_erase(cbor_state_t *cs)
Dominik Ermel3d51e432021-06-25 17:29:50 +000024{
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020025 int rc;
Dominik Ermel3d51e432021-06-25 17:29:50 +000026
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020027 const struct flash_area *fa;
Dominik Ermel97b4c792021-06-25 17:32:38 +000028
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020029 rc = flash_area_open(FLASH_AREA_ID(storage), &fa);
Dominik Ermel97b4c792021-06-25 17:32:38 +000030
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020031 if (rc < 0) {
32 LOG_ERR("failed to open flash area");
33 } else {
34 rc = flash_area_erase(fa, 0, FLASH_AREA_SIZE(storage));
Dominik Ermel97b4c792021-06-25 17:32:38 +000035 if (rc < 0) {
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020036 LOG_ERR("failed to erase flash area");
Dominik Ermel97b4c792021-06-25 17:32:38 +000037 }
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020038 flash_area_close(fa);
39 }
40 if (rc == 0) {
41 rc = MGMT_ERR_OK;
42 } else {
43 rc = MGMT_ERR_EUNKNOWN;
Dominik Ermel3d51e432021-06-25 17:29:50 +000044 }
45
46 map_start_encode(cs, 10);
47 tstrx_put(cs, "rc");
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020048 uintx32_put(cs, rc);
Dominik Ermel3d51e432021-06-25 17:29:50 +000049 map_end_encode(cs, 10);
50
51 return rc;
52}
Dominik Ermel0435d5d2021-08-16 15:58:15 +000053#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020054
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +020055#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020056static int custom_img_status(int image_index, uint32_t slot,char *buffer,
57 ssize_t len)
58{
59 uint32_t area_id;
60 struct flash_area const *fap;
61 struct image_header hdr;
62 int rc;
63 int img_install_stat = 0;
64
65 area_id = flash_area_id_from_multi_image_slot(image_index, slot);
66
67 rc = flash_area_open(area_id, &fap);
68 if (rc) {
69 return rc;
70 }
71
72 rc = flash_area_read(fap, 0, &hdr, sizeof(hdr));
73 if (rc) {
74 goto func_end;
75 }
76
77 if (hdr.ih_magic == IMAGE_MAGIC) {
78 snprintf(buffer, len, "ver=%d.%d.%d.%d,install_stat=%d",
79 hdr.ih_ver.iv_major,
80 hdr.ih_ver.iv_minor,
81 hdr.ih_ver.iv_revision,
82 hdr.ih_ver.iv_build_num,
83 img_install_stat);
84 } else {
85 rc = 1;
86 }
87
88func_end:
89 flash_area_close(fap);
90 return rc;
91}
92
93static int bs_custom_img_list(cbor_state_t *cs)
94{
95 int rc = 0;
96 char tmpbuf[64]; /* Buffer should fit version and flags */
97
98 map_start_encode(cs, 10);
99
100 for (int img = 0; img < MCUBOOT_IMAGE_NUMBER; img++) {
101 for (int slot = 0; slot < 2; slot++) {
102 rc = custom_img_status(img, slot, tmpbuf, sizeof(tmpbuf));
103
104 intx32_put(cs, img * 2 + slot + 1);
105 if (rc == 0) {
106 tstrx_put_term(cs, tmpbuf);
107 } else {
108 tstrx_put_term(cs, "");
109 }
110 }
111 }
112
113 tstrx_put(cs, "rc");
114 uintx32_put(cs, MGMT_ERR_OK);
115 map_end_encode(cs, 10);
116
117 return rc;
118}
119
120#ifndef ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST
121 #define ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST 1
122#endif
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200123#endif /*MCUBOOT_MGMT_CUSTOM_IMG_LIST*/
124
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200125int bs_peruser_system_specific(const struct nmgr_hdr *hdr, const char *buffer,
126 int len, cbor_state_t *cs)
127{
128 int mgmt_rc = MGMT_ERR_ENOTSUP;
129
130 if (hdr->nh_group == ZEPHYR_MGMT_GRP_BASE) {
131 if (hdr->nh_op == NMGR_OP_WRITE) {
Dominik Ermel0435d5d2021-08-16 15:58:15 +0000132#ifdef CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200133 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) {
134 mgmt_rc = bs_custom_storage_erase(cs);
135 }
Dominik Ermel0435d5d2021-08-16 15:58:15 +0000136#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200137 } else if (hdr->nh_op == NMGR_OP_READ) {
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200138#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200139 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST) {
140 mgmt_rc = bs_custom_img_list(cs);
141 }
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200142#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200143 }
144 }
145
146 if (mgmt_rc == MGMT_ERR_ENOTSUP) {
147 map_start_encode(cs, 10);
148 tstrx_put(cs, "rc");
149 uintx32_put(cs, mgmt_rc);
150 map_end_encode(cs, 10);
151 }
152
153 return MGMT_ERR_OK;
154}