Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
#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. */
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
#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);
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);