blob: 88f84adf9dfb27a7ee22f3b66545ccbec0372d02 [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
53static int custom_img_status(int image_index, uint32_t slot,char *buffer,
54 ssize_t len)
55{
56 uint32_t area_id;
57 struct flash_area const *fap;
58 struct image_header hdr;
59 int rc;
60 int img_install_stat = 0;
61
62 area_id = flash_area_id_from_multi_image_slot(image_index, slot);
63
64 rc = flash_area_open(area_id, &fap);
65 if (rc) {
66 return rc;
67 }
68
69 rc = flash_area_read(fap, 0, &hdr, sizeof(hdr));
70 if (rc) {
71 goto func_end;
72 }
73
74 if (hdr.ih_magic == IMAGE_MAGIC) {
75 snprintf(buffer, len, "ver=%d.%d.%d.%d,install_stat=%d",
76 hdr.ih_ver.iv_major,
77 hdr.ih_ver.iv_minor,
78 hdr.ih_ver.iv_revision,
79 hdr.ih_ver.iv_build_num,
80 img_install_stat);
81 } else {
82 rc = 1;
83 }
84
85func_end:
86 flash_area_close(fap);
87 return rc;
88}
89
90static int bs_custom_img_list(cbor_state_t *cs)
91{
92 int rc = 0;
93 char tmpbuf[64]; /* Buffer should fit version and flags */
94
95 map_start_encode(cs, 10);
96
97 for (int img = 0; img < MCUBOOT_IMAGE_NUMBER; img++) {
98 for (int slot = 0; slot < 2; slot++) {
99 rc = custom_img_status(img, slot, tmpbuf, sizeof(tmpbuf));
100
101 intx32_put(cs, img * 2 + slot + 1);
102 if (rc == 0) {
103 tstrx_put_term(cs, tmpbuf);
104 } else {
105 tstrx_put_term(cs, "");
106 }
107 }
108 }
109
110 tstrx_put(cs, "rc");
111 uintx32_put(cs, MGMT_ERR_OK);
112 map_end_encode(cs, 10);
113
114 return rc;
115}
116
117#ifndef ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST
118 #define ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST 1
119#endif
120int bs_peruser_system_specific(const struct nmgr_hdr *hdr, const char *buffer,
121 int len, cbor_state_t *cs)
122{
123 int mgmt_rc = MGMT_ERR_ENOTSUP;
124
125 if (hdr->nh_group == ZEPHYR_MGMT_GRP_BASE) {
126 if (hdr->nh_op == NMGR_OP_WRITE) {
127 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE) {
128 mgmt_rc = bs_custom_storage_erase(cs);
129 }
130 } else if (hdr->nh_op == NMGR_OP_READ) {
131 if (hdr->nh_id == ZEPHYR_MGMT_GRP_BASIC_CMD_IMAGE_LIST) {
132 mgmt_rc = bs_custom_img_list(cs);
133 }
134 }
135 }
136
137 if (mgmt_rc == MGMT_ERR_ENOTSUP) {
138 map_start_encode(cs, 10);
139 tstrx_put(cs, "rc");
140 uintx32_put(cs, mgmt_rc);
141 map_end_encode(cs, 10);
142 }
143
144 return MGMT_ERR_OK;
145}