Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
# Copyright (c) 2024-2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
Expand All @@ -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()
11 changes: 10 additions & 1 deletion subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
# Copyright (c) 2024-2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
Expand All @@ -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
84 changes: 84 additions & 0 deletions subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt_reboot_bt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zcbor_common.h>
#include <zcbor_encode.h>
#include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
#include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt.h>
#include <zephyr/logging/log.h>

#ifdef CONFIG_BT
#include <zephyr/bluetooth/bluetooth.h>
#endif
#ifdef CONFIG_MPSL
#include <mpsl.h>
#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
#if defined(CONFIG_MPSL) && !defined(CONFIG_BT_UNINIT_MPSL_ON_DISABLE)
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. */
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number division by 2 lacks explanation. Add a comment explaining why half the reset timeout is used for scheduling Bluetooth disable, or define it as a named constant like CONFIG_MCUMGR_GRP_OS_RESET_MS_HALF to improve code clarity.

Suggested change
/* disable bluetooth from the system workqueue thread. */
/* disable bluetooth from the system workqueue thread. */
/*
* Schedule Bluetooth disable at half the reset timeout.
* This ensures Bluetooth is disabled well before the actual reset occurs,
* allowing time for clean shutdown and resource release.
*/

Copilot uses AI. Check for mistakes.
k_work_schedule(&bt_disable_work, K_MSEC(CONFIG_MCUMGR_GRP_OS_RESET_MS/2));
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add parentheses around the division operation: K_MSEC((CONFIG_MCUMGR_GRP_OS_RESET_MS/2)). This improves readability and prevents potential issues with macro expansion.

Suggested change
k_work_schedule(&bt_disable_work, K_MSEC(CONFIG_MCUMGR_GRP_OS_RESET_MS/2));
k_work_schedule(&bt_disable_work, K_MSEC((CONFIG_MCUMGR_GRP_OS_RESET_MS/2)));

Copilot uses AI. Check for mistakes.
#else
#ifdef CONFIG_BT
int err_rc = bt_disable();

if (err_rc) {
LOG_ERR("BT disable failed before reboot: %d", err_rc);
}
#endif
#if defined(CONFIG_MPSL) && !defined(CONFIG_BT_UNINIT_MPSL_ON_DISABLE)
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);
Comment on lines +73 to +80
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The variable name cmd_reboot_bt_info_cb is misleading as it suggests an info callback, but this handles the reboot hook. Consider renaming to reboot_bt_hook_cb or os_mgmt_reboot_bt_cb for clarity.

Suggested change
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);
static struct mgmt_callback reboot_bt_hook_cb = {
.callback = reboot_bt_hook,
.event_id = MGMT_EVT_OP_OS_MGMT_RESET,
};
static int os_mgmt_register_reboot_bt(void)
{
mgmt_callback_register(&reboot_bt_hook_cb);

Copilot uses AI. Check for mistakes.
return 0;
}

SYS_INIT(os_mgmt_register_reboot_bt, APPLICATION, 0);