diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h index 9c541e11c29..e1ac45e6389 100644 --- a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h @@ -24,6 +24,7 @@ extern "C" { #define OS_MGMT_ID_RESET 5 #define OS_MGMT_ID_MCUMGR_PARAMS 6 #define OS_MGMT_ID_INFO 7 +#define OS_MGMT_ID_BOOTLOADER_INFO 8 /** * Command result codes for OS management group. @@ -37,6 +38,9 @@ enum os_mgmt_err_code_t { /** The provided format value is not valid. */ OS_MGMT_ERR_INVALID_FORMAT, + + /** Query was not recognized. */ + OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER, }; /* Bitmask values used by the os info command handler. Note that the width of this variable is diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt index e712acf6e94..35123fa1159 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt @@ -1,6 +1,6 @@ # # Copyright (c) 2018-2021 mcumgr authors -# Copyright (c) 2022 Nordic Semiconductor ASA +# Copyright (c) 2022-2023 Nordic Semiconductor ASA # # SPDX-License-Identifier: Apache-2.0 # @@ -12,6 +12,12 @@ zephyr_library_sources(src/os_mgmt.c) zephyr_library_include_directories(include) +if (CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) + zephyr_include_directories( + ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/bootutil/include + ) +endif() + if(DEFINED CONFIG_MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME) set(MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME_DIR ${PROJECT_BINARY_DIR}/os_mgmt_auto) file(MAKE_DIRECTORY ${MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME_DIR}) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig index 897db735982..fa743b53caf 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig @@ -173,6 +173,16 @@ config MCUMGR_GRP_OS_INFO_BUILD_DATE_TIME endif +if BOOTLOADER_MCUBOOT + +config MCUMGR_GRP_OS_BOOTLOADER_INFO + bool "Bootloader information" + help + Allows to query MCUmgr about bootloader used by device and various bootloader + parameters. + +endif # BOOTLOADER_MCUBOOT + module = MCUMGR_GRP_OS module-str = mcumgr_grp_os source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c index 55a6fa81564..a42e2f4022f 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -33,10 +33,15 @@ #include #endif -#ifdef CONFIG_MCUMGR_GRP_OS_INFO +#if defined(CONFIG_MCUMGR_GRP_OS_INFO) || defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) #include #include +#if defined(CONFIG_MCUMGR_GRP_OS_INFO) #include +#endif +#if defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) +#include +#endif #include #if defined(CONFIG_NET_HOSTNAME_ENABLE) #include @@ -370,6 +375,64 @@ os_mgmt_mcumgr_params(struct smp_streamer *ctxt) } #endif +#if defined(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO) + +#if IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SINGLE_APP) +#define BOOTLOADER_MODE MCUBOOT_MODE_SINGLE_SLOT +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH) +#define BOOTLOADER_MODE MCUBOOT_MODE_SWAP_USING_SCRATCH +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY) +#define BOOTLOADER_MODE MCUBOOT_MODE_UPGRADE_ONLY +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH) +#define BOOTLOADER_MODE MCUBOOT_MODE_SWAP_USING_MOVE +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) +#define BOOTLOADER_MODE MCUBOOT_MODE_DIRECT_XIP +#elif IS_ENABLED(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT) +#define BOOTLOADER_MODE MCUBOOT_MODE_DIRECT_XIP_WITH_REVERT +#else +#define BOOTLOADER_MODE -1 +#endif + +static int +os_mgmt_bootloader_info(struct smp_streamer *ctxt) +{ + zcbor_state_t *zse = ctxt->writer->zs; + zcbor_state_t *zsd = ctxt->reader->zs; + struct zcbor_string query = { 0 }; + size_t decoded; + bool ok; + + struct zcbor_map_decode_key_val bootloader_info[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("query", zcbor_tstr_decode, &query), + }; + + if (zcbor_map_decode_bulk(zsd, bootloader_info, ARRAY_SIZE(bootloader_info), &decoded)) { + return MGMT_ERR_EINVAL; + } + + /* If no parameter is recognized then just introduce the bootloader. */ + if (decoded == 0) { + ok = zcbor_tstr_put_lit(zse, "bootloader") && + zcbor_tstr_put_lit(zse, "MCUboot"); + } else if (zcbor_map_decode_bulk_key_found(bootloader_info, ARRAY_SIZE(bootloader_info), + "query") && + (sizeof("mode") - 1) == query.len && + memcmp("mode", query.value, query.len) == 0) { + + ok = zcbor_tstr_put_lit(zse, "mode") && + zcbor_int32_put(zse, BOOTLOADER_MODE); +#if IS_ENABLED(MCUBOOT_BOOTLOADER_NO_DOWNGRADE) + ok = zcbor_tstr_put_lit(zse, "no-downgrade") && + zcbor_bool_encode(zse, true); +#endif + } else { + return OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER; + } + + return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; +} +#endif + #ifdef CONFIG_MCUMGR_GRP_OS_INFO /** * Command handler: os info @@ -733,6 +796,11 @@ static const struct mgmt_handler os_mgmt_group_handlers[] = { os_mgmt_info, NULL }, #endif +#ifdef CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO + [OS_MGMT_ID_BOOTLOADER_INFO] = { + os_mgmt_bootloader_info, NULL + }, +#endif }; #define OS_MGMT_GROUP_SZ ARRAY_SIZE(os_mgmt_group_handlers)