diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt index 81ea1db57a66..811029182f1d 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2024 Nordic Semiconductor ASA +# Copyright (c) 2024-2025 Nordic Semiconductor ASA # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # @@ -8,3 +8,8 @@ if(CONFIG_MCUMGR_GRP_OS_BOOTLOADER_INFO_B0_ACTIVE_SLOT) zephyr_library_amend() zephyr_library_sources(src/os_mgmt_b0_active_slot.c) endif() + +if(CONFIG_MCUMGR_GRP_OS_REBOOT_BT) + zephyr_library_amend() + zephyr_library_sources(src/os_mgmt_reboot_bt.c) +endif() diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig index 94ecd3970b9c..7bfb8979273c 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig @@ -1,5 +1,5 @@ # -# Copyright (c) 2024 Nordic Semiconductor ASA +# Copyright (c) 2024-2025 Nordic Semiconductor ASA # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # @@ -19,4 +19,13 @@ config MCUMGR_GRP_OS_BOOTLOADER_INFO_B0_ACTIVE_SLOT 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. +config MCUMGR_GRP_OS_REBOOT_BT + bool + default y + depends on MCUMGR_GRP_OS + depends on (BT || MPSL) + depends on SOC_SERIES_NRF54LX + select MCUMGR_MGMT_NOTIFICATION_HOOKS + select MCUMGR_GRP_OS_RESET_HOOK + endmenu diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt_reboot_bt.c b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt_reboot_bt.c new file mode 100644 index 000000000000..36bd899420d7 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt_reboot_bt.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_BT +#include +#endif +#ifdef CONFIG_MPSL +#include +#endif + +LOG_MODULE_REGISTER(os_mgmt_reboot_bt, CONFIG_MCUMGR_GRP_OS_LOG_LEVEL); + +#ifdef CONFIG_MULTITHREADING +static void bt_disable_work_handler(struct k_work *work); + +static K_WORK_DELAYABLE_DEFINE(bt_disable_work, bt_disable_work_handler); + +static void bt_disable_work_handler(struct k_work *work) +{ + ARG_UNUSED(work); + +#ifdef CONFIG_BT + int err_rc = bt_disable(); + + if (err_rc) { + LOG_ERR("BT disable failed before reboot: %d", err_rc); + } +#endif +#ifdef CONFIG_MPSL + mpsl_uninit(); +#endif +} +#endif + +static enum mgmt_cb_return reboot_bt_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_reset_data *reboot_data = (struct os_mgmt_reset_data *)data; + + if (event != MGMT_EVT_OP_OS_MGMT_RESET || data_size != sizeof(*reboot_data)) { + *rc = MGMT_ERR_EUNKNOWN; + return MGMT_CB_ERROR_RC; + } +#ifdef CONFIG_MULTITHREADING + /* disable bluetooth from the system workqueue thread. */ + k_work_schedule(&bt_disable_work, K_MSEC(CONFIG_MCUMGR_GRP_OS_RESET_MS/2)); +#else +#ifdef CONFIG_BT + int err_rc = bt_disable(); + + if (err_rc) { + LOG_ERR("BT disable failed before reboot: %d", err_rc); + } +#endif +#ifdef CONFIG_MPSL + mpsl_uninit(); +#endif +#endif + + return MGMT_CB_OK; +} + +static struct mgmt_callback cmd_reboot_bt_info_cb = { + .callback = reboot_bt_hook, + .event_id = MGMT_EVT_OP_OS_MGMT_RESET, +}; + +static int os_mgmt_register_reboot_bt(void) +{ + mgmt_callback_register(&cmd_reboot_bt_info_cb); + return 0; +} + +SYS_INIT(os_mgmt_register_reboot_bt, APPLICATION, 0);