diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index 80023be74eea..f9b975dc0149 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -77,3 +77,4 @@ add_subdirectory(suit) add_subdirectory_ifdef(CONFIG_MGMT_SUITFU mgmt/suitfu) add_subdirectory_ifdef(CONFIG_DULT dult) add_subdirectory_ifdef(CONFIG_NRF_COMPRESS nrf_compress) +add_subdirectory(mgmt/mcumgr) diff --git a/subsys/Kconfig b/subsys/Kconfig index 37be60487f97..05bda2f953c8 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -28,6 +28,7 @@ rsource "nrf_rpc/Kconfig" rsource "zigbee/Kconfig" rsource "mgmt/fmfu/Kconfig" rsource "mgmt/suitfu/Kconfig" +rsource "mgmt/mcumgr/Kconfig" rsource "caf/Kconfig" rsource "ieee802154/Kconfig" rsource "dm/Kconfig" diff --git a/subsys/mgmt/mcumgr/CMakeLists.txt b/subsys/mgmt/mcumgr/CMakeLists.txt new file mode 100644 index 000000000000..88b201618140 --- /dev/null +++ b/subsys/mgmt/mcumgr/CMakeLists.txt @@ -0,0 +1,7 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +add_subdirectory(grp) diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig new file mode 100644 index 000000000000..f5f49074cda4 --- /dev/null +++ b/subsys/mgmt/mcumgr/Kconfig @@ -0,0 +1,11 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +menu "Additional MCUmgr configuration" + +rsource "grp/Kconfig" + +endmenu diff --git a/subsys/mgmt/mcumgr/grp/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/CMakeLists.txt new file mode 100644 index 000000000000..eb102c86b017 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/CMakeLists.txt @@ -0,0 +1,7 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_OS os_mgmt) diff --git a/subsys/mgmt/mcumgr/grp/Kconfig b/subsys/mgmt/mcumgr/grp/Kconfig new file mode 100644 index 000000000000..d2eed051f4b5 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/Kconfig @@ -0,0 +1,11 @@ +# +# Copyright (c) 2024 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +menu "Additional MCUmgr group configuration" + +rsource "os_mgmt/Kconfig" + +endmenu diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt new file mode 100644 index 000000000000..81ea1db57a66 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +if(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO_B0_ACTIVE_SLOT) + zephyr_library_amend() + zephyr_library_sources(src/os_mgmt_b0_active_slot.c) +endif() diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig new file mode 100644 index 000000000000..7ac1c2da2893 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig @@ -0,0 +1,22 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +menu "Additional MCUmgr OS group management functionality" + +config MCUMGR_GRP_OS_BOOTLOADER_INFO_B0_ACTIVE_SLOT + bool "Bootloader info query for active b0 slot" + depends on MCUMGR_GRP_OS_BOOTLOADER_INFO + depends on BOOTLOADER_MCUBOOT + depends on MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 + depends on FW_INFO + depends on FW_INFO_API + select MCUMGR_MGMT_NOTIFICATION_HOOKS + select MCUMGR_GRP_OS_BOOTLOADER_INFO_HOOK + help + Enables a bootloader info command for `active_b0_slot` which will return the active b0 + image slot number, and can be used to determine which update image should be loaded. + +endmenu diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt_b0_active_slot.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt_b0_active_slot.c new file mode 100644 index 000000000000..43af72f89191 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt_b0_active_slot.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include +#include + +static enum mgmt_cb_return bootloader_info_hook(uint32_t event, enum mgmt_cb_return prev_status, + int32_t *rc, uint16_t *group, bool *abort_more, + void *data, size_t data_size) +{ + struct os_mgmt_bootloader_info_data *bootloader_info_data = + (struct os_mgmt_bootloader_info_data *)data; + + if (event != MGMT_EVT_OP_OS_MGMT_BOOTLOADER_INFO || data_size != + sizeof(*bootloader_info_data)) { + *rc = MGMT_ERR_EUNKNOWN; + return MGMT_CB_ERROR_RC; + } + + /* If no parameter is recognized then just introduce the bootloader. */ + if (*(bootloader_info_data->decoded) >= 1 && (sizeof("active_b0_slot") - 1) == + bootloader_info_data->query->len && memcmp("active_b0_slot", + bootloader_info_data->query->value, + bootloader_info_data->query->len) == 0) { + const struct fw_info *s0_info = fw_info_find(PM_S0_ADDRESS); + const struct fw_info *s1_info = fw_info_find(PM_S1_ADDRESS); + + if (s0_info || s1_info) { + int active_slot; + bool ok; + + if (!s1_info || (s0_info && s0_info->version >= s1_info->version)) { + active_slot = 0; + } else if (!s0_info || (s1_info && s1_info->version > s0_info->version)) { + active_slot = 1; + } + + ok = zcbor_tstr_put_lit(bootloader_info_data->zse, "active") && + zcbor_int32_put(bootloader_info_data->zse, active_slot); + *rc = (ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE); + return MGMT_CB_ERROR_RC; + } + + /* Return reponse not valid error when active slot cannot be determined */ + *group = MGMT_GROUP_ID_OS; + *rc = OS_MGMT_ERR_QUERY_RESPONSE_VALUE_NOT_VALID; + return MGMT_CB_ERROR_ERR; + } + + return MGMT_CB_OK; +} + +static struct mgmt_callback cmd_bootloader_info_cb = { + .callback = bootloader_info_hook, + .event_id = MGMT_EVT_OP_OS_MGMT_BOOTLOADER_INFO, +}; + +static int os_mgmt_register_bootloader_info_hook_b0_active_slot(void) +{ + mgmt_callback_register(&cmd_bootloader_info_cb); + return 0; +} + +SYS_INIT(os_mgmt_register_bootloader_info_hook_b0_active_slot, APPLICATION, 0);