1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/init.h>
9 #include <zephyr/logging/log.h>
10 #include <zephyr/storage/flash_map.h>
11 
12 #include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
13 #include <zephyr/mgmt/mcumgr/mgmt/handlers.h>
14 #include <zephyr/mgmt/mcumgr/grp/zephyr/zephyr_basic.h>
15 
16 LOG_MODULE_REGISTER(mcumgr_zbasic_grp, CONFIG_MCUMGR_GRP_ZBASIC_LOG_LEVEL);
17 
18 #define ERASE_TARGET		storage_partition
19 #define ERASE_TARGET_ID		FIXED_PARTITION_ID(ERASE_TARGET)
20 
storage_erase(void)21 static int storage_erase(void)
22 {
23 	const struct flash_area *fa;
24 	int rc = flash_area_open(ERASE_TARGET_ID, &fa);
25 
26 	if (rc < 0) {
27 		LOG_ERR("Failed to open flash area");
28 		rc = ZEPHYRBASIC_MGMT_ERR_FLASH_OPEN_FAILED;
29 	} else {
30 		if (flash_area_get_device(fa) == NULL) {
31 			LOG_ERR("Failed to get flash area device");
32 			rc = ZEPHYRBASIC_MGMT_ERR_FLASH_CONFIG_QUERY_FAIL;
33 		} else {
34 			rc = flash_area_flatten(fa, 0, fa->fa_size);
35 
36 			if (rc < 0) {
37 				LOG_ERR("Failed to erase flash area");
38 				rc = ZEPHYRBASIC_MGMT_ERR_FLASH_ERASE_FAILED;
39 			}
40 		}
41 
42 		flash_area_close(fa);
43 	}
44 
45 	return rc;
46 }
47 
storage_erase_handler(struct smp_streamer * ctxt)48 static int storage_erase_handler(struct smp_streamer *ctxt)
49 {
50 	zcbor_state_t *zse = ctxt->writer->zs;
51 	int rc;
52 	bool ok = true;
53 
54 	rc = storage_erase();
55 
56 	if (rc != ZEPHYRBASIC_MGMT_ERR_OK) {
57 		ok = smp_add_cmd_err(zse, ZEPHYR_MGMT_GRP_BASIC, rc);
58 	}
59 
60 	if (!ok) {
61 		return MGMT_ERR_EMSGSIZE;
62 	}
63 
64 	return MGMT_ERR_EOK;
65 }
66 
67 #ifdef CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL
68 /*
69  * @brief	Translate zephyr basic group error code into MCUmgr error code
70  *
71  * @param ret	#zephyr_basic_group_err_code_t error code
72  *
73  * @return	#mcumgr_err_t error code
74  */
zephyr_basic_group_translate_error_code(uint16_t ret)75 static int zephyr_basic_group_translate_error_code(uint16_t ret)
76 {
77 	int rc;
78 
79 	switch (ret) {
80 	case ZEPHYRBASIC_MGMT_ERR_FLASH_OPEN_FAILED:
81 		rc = MGMT_ERR_ENOENT;
82 		break;
83 
84 	case ZEPHYRBASIC_MGMT_ERR_FLASH_CONFIG_QUERY_FAIL:
85 	case ZEPHYRBASIC_MGMT_ERR_FLASH_ERASE_FAILED:
86 		rc = MGMT_ERR_EOK;
87 		break;
88 
89 	default:
90 		rc = MGMT_ERR_EUNKNOWN;
91 	}
92 
93 	return rc;
94 }
95 #endif
96 
97 static const struct mgmt_handler zephyr_mgmt_basic_handlers[] = {
98 	[ZEPHYR_MGMT_GRP_BASIC_CMD_ERASE_STORAGE] = {
99 		.mh_read  = NULL,
100 		.mh_write = storage_erase_handler,
101 	},
102 };
103 
104 static struct mgmt_group zephyr_basic_mgmt_group = {
105 	.mg_handlers = (struct mgmt_handler *)zephyr_mgmt_basic_handlers,
106 	.mg_handlers_count = ARRAY_SIZE(zephyr_mgmt_basic_handlers),
107 	.mg_group_id = (ZEPHYR_MGMT_GRP_BASIC),
108 #ifdef CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL
109 	.mg_translate_error = zephyr_basic_group_translate_error_code,
110 #endif
111 #ifdef CONFIG_MCUMGR_GRP_ENUM_DETAILS_NAME
112 	.mg_group_name = "zephyr basic mgmt",
113 #endif
114 };
115 
zephyr_basic_mgmt_init(void)116 static void zephyr_basic_mgmt_init(void)
117 {
118 	mgmt_register_group(&zephyr_basic_mgmt_group);
119 }
120 
121 MCUMGR_HANDLER_DEFINE(zephyr_basic_mgmt, zephyr_basic_mgmt_init);
122