blob: 3cd801c16cd809d71f57cb58c27bbc496b345cd6 [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
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020022static int bs_custom_storage_erase(cbor_state_t *cs)
Dominik Ermel3d51e432021-06-25 17:29:50 +000023{
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020024 int rc;
Dominik Ermel3d51e432021-06-25 17:29:50 +000025
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020026 const struct flash_area *fa;
Dominik Ermel97b4c792021-06-25 17:32:38 +000027
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020028 rc = flash_area_open(FLASH_AREA_ID(storage), &fa);
Dominik Ermel97b4c792021-06-25 17:32:38 +000029
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020030 if (rc < 0) {
31 LOG_ERR("failed to open flash area");
32 } else {
33 rc = flash_area_erase(fa, 0, FLASH_AREA_SIZE(storage));
Dominik Ermel97b4c792021-06-25 17:32:38 +000034 if (rc < 0) {
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020035 LOG_ERR("failed to erase flash area");
Dominik Ermel97b4c792021-06-25 17:32:38 +000036 }
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020037 flash_area_close(fa);
38 }
39 if (rc == 0) {
40 rc = MGMT_ERR_OK;
41 } else {
42 rc = MGMT_ERR_EUNKNOWN;
Dominik Ermel3d51e432021-06-25 17:29:50 +000043 }
44
45 map_start_encode(cs, 10);
46 tstrx_put(cs, "rc");
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020047 uintx32_put(cs, rc);
Dominik Ermel3d51e432021-06-25 17:29:50 +000048 map_end_encode(cs, 10);
49
50 return rc;
51}
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020052
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +020053#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +020054static int custom_img_status(int image_index, uint32_t slot,char *buffer,
55 ssize_t len)
56{
57 uint32_t area_id;
58 struct flash_area const *fap;
59 struct image_header hdr;
60 int rc;
61 int img_install_stat = 0;
62
63 area_id = flash_area_id_from_multi_image_slot(image_index, slot);
64
65 rc = flash_area_open(area_id, &fap);
66 if (rc) {
67 return rc;
68 }
69
70 rc = flash_area_read(fap, 0, &hdr, sizeof(hdr));
71 if (rc) {
72 goto func_end;
73 }
74
75 if (hdr.ih_magic == IMAGE_MAGIC) {
76 snprintf(buffer, len, "ver=%d.%d.%d.%d,install_stat=%d",
77 hdr.ih_ver.iv_major,
78 hdr.ih_ver.iv_minor,
79 hdr.ih_ver.iv_revision,
80 hdr.ih_ver.iv_build_num,
81 img_install_stat);
82 } else {
83 rc = 1;
84 }
85
86func_end:
87 flash_area_close(fap);
88 return rc;
89}
90
91static int bs_custom_img_list(cbor_state_t *cs)
92{
93 int rc = 0;
94 char tmpbuf[64]; /* Buffer should fit version and flags */
95
96 map_start_encode(cs, 10);
97
98 for (int img = 0; img < MCUBOOT_IMAGE_NUMBER; img++) {
99 for (int slot = 0; slot < 2; slot++) {
100 rc = custom_img_status(img, slot, tmpbuf, sizeof(tmpbuf));
101
102 intx32_put(cs, img * 2 + slot + 1);
103 if (rc == 0) {
104 tstrx_put_term(cs, tmpbuf);
105 } else {
106 tstrx_put_term(cs, "");
107 }
108 }
109 }
110
111 tstrx_put(cs, "rc");
112 uintx32_put(cs, MGMT_ERR_OK);
113 map_end_encode(cs, 10);
114
115 return rc;
116}
117
118#ifndef ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST
119 #define ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST 1
120#endif
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200121#endif /*MCUBOOT_MGMT_CUSTOM_IMG_LIST*/
122
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200123int bs_peruser_system_specific(const struct nmgr_hdr *hdr, const char *buffer,
124 int len, cbor_state_t *cs)
125{
126 int mgmt_rc = MGMT_ERR_ENOTSUP;
127
128 if (hdr->nh_group == ZEPHYR_MGMT_GRP_BASE) {
129 if (hdr->nh_op == NMGR_OP_WRITE) {
130 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) {
131 mgmt_rc = bs_custom_storage_erase(cs);
132 }
133 } else if (hdr->nh_op == NMGR_OP_READ) {
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200134#ifdef MCUBOOT_MGMT_CUSTOM_IMG_LIST
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200135 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST) {
136 mgmt_rc = bs_custom_img_list(cs);
137 }
Andrzej Puzdrowski420ad9a2021-07-29 16:22:52 +0200138#endif
Andrzej Puzdrowski1b62cf22021-07-28 17:21:19 +0200139 }
140 }
141
142 if (mgmt_rc == MGMT_ERR_ENOTSUP) {
143 map_start_encode(cs, 10);
144 tstrx_put(cs, "rc");
145 uintx32_put(cs, mgmt_rc);
146 map_end_encode(cs, 10);
147 }
148
149 return MGMT_ERR_OK;
150}