From 742ce56031de1e0a4665eb83ed84a6f022025f80 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 16 Jul 2025 14:41:46 +0100 Subject: [PATCH 1/5] settings: Add bluetooth name subsystem Adds a settings subsystem file to add a bluetooth name setting Signed-off-by: Jamie McCrae --- include/settings/bluetooth_name.h | 14 +++++ subsys/CMakeLists.txt | 1 + subsys/Kconfig | 1 + subsys/settings/CMakeLists.txt | 7 +++ subsys/settings/Kconfig | 13 ++++ subsys/settings/src/bluetooth_name.c | 92 ++++++++++++++++++++++++++++ 6 files changed, 128 insertions(+) create mode 100644 include/settings/bluetooth_name.h create mode 100644 subsys/settings/CMakeLists.txt create mode 100644 subsys/settings/Kconfig create mode 100644 subsys/settings/src/bluetooth_name.c diff --git a/include/settings/bluetooth_name.h b/include/settings/bluetooth_name.h new file mode 100644 index 0000000000..e552b354dc --- /dev/null +++ b/include/settings/bluetooth_name.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include + +/** + * @brief Retrieve the variable which holds the desired device advertising name. + * + * @retval Address of device name setting. + */ +const char *bluetooth_name_value_get(void); diff --git a/subsys/CMakeLists.txt b/subsys/CMakeLists.txt index 0602761c04..60a1ec6679 100644 --- a/subsys/CMakeLists.txt +++ b/subsys/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(bm_installs) add_subdirectory(logging) add_subdirectory_ifdef(CONFIG_NCS_BM_MCUMGR mgmt/mcumgr) add_subdirectory_ifdef(CONFIG_NRF_SDH softdevice_handler) +add_subdirectory_ifdef(CONFIG_SETTINGS settings) add_subdirectory_ifdef(CONFIG_SOFTDEVICE softdevice) add_subdirectory_ifdef(CONFIG_FLASH_MAP storage/flash_map) # zephyr-keep-sorted-stop diff --git a/subsys/Kconfig b/subsys/Kconfig index 3b1ff6e7b0..dfabb36bd3 100644 --- a/subsys/Kconfig +++ b/subsys/Kconfig @@ -13,6 +13,7 @@ rsource "logging/Kconfig" rsource "mgmt/mcumgr/Kconfig" rsource "softdevice/Kconfig" rsource "softdevice_handler/Kconfig" +rsource "settings/Kconfig" rsource "storage/flash_map/Kconfig" # zephyr-keep-sorted-stop diff --git a/subsys/settings/CMakeLists.txt b/subsys/settings/CMakeLists.txt new file mode 100644 index 0000000000..c62c68f62e --- /dev/null +++ b/subsys/settings/CMakeLists.txt @@ -0,0 +1,7 @@ +# +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +zephyr_sources_ifdef(CONFIG_NCS_BM_SETTINGS_BLUETOOTH_NAME src/bluetooth_name.c) diff --git a/subsys/settings/Kconfig b/subsys/settings/Kconfig new file mode 100644 index 0000000000..15852a4d79 --- /dev/null +++ b/subsys/settings/Kconfig @@ -0,0 +1,13 @@ +# +# Copyright (c) 2025 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +menu "Settings" + depends on SETTINGS + +menuconfig NCS_BM_SETTINGS_BLUETOOTH_NAME + bool "Bluetooth name" + +endmenu diff --git a/subsys/settings/src/bluetooth_name.c b/subsys/settings/src/bluetooth_name.c new file mode 100644 index 0000000000..59f3d81ce9 --- /dev/null +++ b/subsys/settings/src/bluetooth_name.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include + +LOG_MODULE_REGISTER(settings_bluetooth_name, CONFIG_SETTINGS_LOG_LEVEL); + +static char bluetooth_name_val[32] = ""; + +static int bluetooth_name_handle_set(const char *name, size_t len, settings_read_cb read_cb, + void *cb_arg); +static int bluetooth_name_handle_export(int (*cb)(const char *name, const void *value, + size_t val_len)); +static int bluetooth_name_handle_commit(void); +static int bluetooth_name_handle_get(const char *name, char *val, int val_len_max); + +SETTINGS_STATIC_HANDLER_DEFINE(bluetooth_name, "bluetooth_name", bluetooth_name_handle_get, + bluetooth_name_handle_set, bluetooth_name_handle_commit, + bluetooth_name_handle_export); + +static int bluetooth_name_handle_set(const char *name, size_t len, settings_read_cb read_cb, + void *cb_arg) +{ + const char *next; + size_t name_len; + int rc; + + name_len = settings_name_next(name, &next); + + if (!next) { + if (!strncmp(name, "name", name_len)) { + if (len > (sizeof(bluetooth_name_val) - 1)) { + LOG_ERR("Invalid settings value for bluetooth_name/name"); + return -EINVAL; + } + + rc = read_cb(cb_arg, bluetooth_name_val, sizeof(bluetooth_name_val)); + + if (rc < 0) { + return rc; + } else if (rc > 0) { + LOG_ERR("Config set to %s", bluetooth_name_val); + } + + return 0; + } + } + + return -ENOENT; +} + +static int bluetooth_name_handle_export(int (*cb)(const char *name, const void *value, + size_t val_len)) +{ + (void)cb("bluetooth_name/name", bluetooth_name_val, strlen(bluetooth_name_val) + 1); + LOG_ERR("export_done"); + return 0; +} + +static int bluetooth_name_handle_commit(void) +{ + LOG_ERR("loading_done"); + return 0; +} + +static int bluetooth_name_handle_get(const char *name, char *val, int val_len_max) +{ + const char *next; + + if (name == NULL || val == NULL) { + return -EINVAL; + } + + if (settings_name_steq(name, "name", &next) && !next) { + val_len_max = MIN(val_len_max, strlen(bluetooth_name_val)); + memcpy(val, bluetooth_name_val, val_len_max); + return val_len_max; + } + + return -ENOENT; +} + +const char *bluetooth_name_value_get(void) +{ + return bluetooth_name_val; +} From 2273dc67286eb233a8e24668cb5b00fd243ee3f4 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 16 Jul 2025 14:42:51 +0100 Subject: [PATCH 2/5] mgmt: mcumgr: grp: Add settings management group Allows usage of this from BM applications Files taken from zephyr commit: 0fe59bf1e4b96122c3467295b09a034e399c5ee6 Signed-off-by: Jamie McCrae --- scripts/ci/license_allow_list.yaml | 2 + subsys/mgmt/mcumgr/grp/CMakeLists.txt | 1 + subsys/mgmt/mcumgr/grp/Kconfig | 2 + .../mcumgr/grp/settings_mgmt/CMakeLists.txt | 18 +++++ subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig | 68 +++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt create mode 100644 subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig diff --git a/scripts/ci/license_allow_list.yaml b/scripts/ci/license_allow_list.yaml index 651c906d55..b193971d13 100644 --- a/scripts/ci/license_allow_list.yaml +++ b/scripts/ci/license_allow_list.yaml @@ -45,6 +45,8 @@ Apache-2.0: | ^nrf-bm/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig ^nrf-bm/subsys/mgmt/mcumgr/grp/os_mgmt/CMakeLists.txt ^nrf-bm/subsys/mgmt/mcumgr/grp/os_mgmt/Kconfig + ^nrf-bm/subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt + ^nrf-bm/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig ^nrf-bm/subsys/mgmt/mcumgr/mgmt/CMakeLists.txt ^nrf-bm/subsys/mgmt/mcumgr/mgmt/Kconfig ^nrf-bm/subsys/mgmt/mcumgr/smp/CMakeLists.txt diff --git a/subsys/mgmt/mcumgr/grp/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/CMakeLists.txt index 5d152f19a3..d0be33c66c 100644 --- a/subsys/mgmt/mcumgr/grp/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_IMG img_mgmt) add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_OS os_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_SETTINGS settings_mgmt) diff --git a/subsys/mgmt/mcumgr/grp/Kconfig b/subsys/mgmt/mcumgr/grp/Kconfig index f9b660b5fa..9b2b08dfe2 100644 --- a/subsys/mgmt/mcumgr/grp/Kconfig +++ b/subsys/mgmt/mcumgr/grp/Kconfig @@ -5,3 +5,5 @@ rsource "img_mgmt/Kconfig" rsource "os_mgmt/Kconfig" + +rsource "settings_mgmt/Kconfig" diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt new file mode 100644 index 0000000000..0ab82a75e2 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/CMakeLists.txt @@ -0,0 +1,18 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Settings management group public API is exposed by MCUmgr API +# interface, when settings management is enabled. +zephyr_library() +zephyr_library_sources(${ZEPHYR_BASE}/subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c) + +if(CONFIG_MCUMGR_GRP_SETTINGS AND NOT CONFIG_MCUMGR_GRP_SETTINGS_ACCESS_HOOK) + message(WARNING "Note: MCUmgr settings management is enabled but settings access hooks are " + "disabled, this is an insecure configuration and not recommended for production " + "use, as all settings on the device can be manipulated by a remote device. See " + "https://docs.zephyrproject.org/latest/services/device_mgmt/mcumgr_callbacks.html " + "for details on enabling and using MCUmgr hooks.") +endif() diff --git a/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig new file mode 100644 index 0000000000..ed61f4d7c5 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/settings_mgmt/Kconfig @@ -0,0 +1,68 @@ +# Copyright Nordic Semiconductor ASA 2023. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig MCUMGR_GRP_SETTINGS + bool "MCUmgr handlers for settings management" + depends on SETTINGS + depends on SETTINGS_RUNTIME + select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 + select MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_2 if ZCBOR_CANONICAL + select MCUMGR_SMP_CBOR_MIN_ENCODING_LEVEL_1 + help + Enables MCUmgr handlers for settings manipulation. + +if MCUMGR_GRP_SETTINGS + +choice MCUMGR_GRP_SETTINGS_BUFFER_TYPE + prompt "Buffer type" + default MCUMGR_GRP_SETTINGS_BUFFER_TYPE_STACK + help + Selects if the stack or heap will be used for variables that are + needed when processing requests. + +config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_STACK + bool "Stack (fixed size)" + help + Use a fixed size stack buffer, any user-supplied values longer than + this will be rejected. + + Note that stack usage for parameter storage alone will be + MCUMGR_GRP_SETTINGS_NAME_LEN + MCUMGR_GRP_SETTINGS_VALUE_LEN, + therefore the MCUmgr stack should be appropriately sized. + +config MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP + bool "Heap (dynamic size)" + depends on COMMON_LIBC_MALLOC_ARENA_SIZE > 0 + help + Use dynamic heap memory allocation through malloc, if there is + insufficient heap memory for the allocation then the request will be + rejected. + +endchoice + +config MCUMGR_GRP_SETTINGS_NAME_LEN + int "Maximum setting name length" + default 32 + help + Maximum length of a key to lookup, this will be the size of the + variable if placed on the stack or the maximum allocated size of the + variable if placed on the heap. + +config MCUMGR_GRP_SETTINGS_VALUE_LEN + int "Maximum setting value length" + default 32 + help + Maximum length of a value to read, this will be the size of the + variable if placed on the stack or the allocated size of the + variable if placed on the heap (settings does not support getting + the size of a value prior to looking it up). + +config MCUMGR_GRP_SETTINGS_ACCESS_HOOK + bool "Settings access hook" + depends on MCUMGR_MGMT_NOTIFICATION_HOOKS + help + Allows applications to control settings management access by + registering for a callback which is then triggered whenever a + settings read or write attempt is made. + +endif From 414e80c5aac726127ce80c04c705d06c242c29fb Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 16 Jul 2025 14:45:42 +0100 Subject: [PATCH 3/5] samples: mcumgr: ble_mcumgr: Add settings test code Adds code to get bluetooth name from retention settings Signed-off-by: Jamie McCrae --- samples/mcumgr/ble_mcumgr/prj.conf | 7 +++++ samples/mcumgr/ble_mcumgr/src/main.c | 38 +++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/samples/mcumgr/ble_mcumgr/prj.conf b/samples/mcumgr/ble_mcumgr/prj.conf index ec2f9c3e78..62becb3002 100644 --- a/samples/mcumgr/ble_mcumgr/prj.conf +++ b/samples/mcumgr/ble_mcumgr/prj.conf @@ -46,3 +46,10 @@ CONFIG_BLE_MCUMGR=y CONFIG_LOG=y CONFIG_LOG_MODE_MINIMAL=y + +CONFIG_RETAINED_MEM=y +CONFIG_RETENTION=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_RETENTION=y +#CONFIG_SETTINGS_RUNTIME=y +CONFIG_NCS_BM_SETTINGS_BLUETOOTH_NAME=y diff --git a/samples/mcumgr/ble_mcumgr/src/main.c b/samples/mcumgr/ble_mcumgr/src/main.c index e4d8347849..beff2aa94b 100644 --- a/samples/mcumgr/ble_mcumgr/src/main.c +++ b/samples/mcumgr/ble_mcumgr/src/main.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include LOG_MODULE_REGISTER(app, CONFIG_APP_LOG_LEVEL); @@ -175,6 +177,9 @@ static int ble_change_address(void) int main(void) { int err; + const char *custom_advertising_name; + uint8_t custom_advertising_name_size; + ble_gap_conn_sec_mode_t sec_mode = {0}; struct ble_adv_config ble_adv_cfg = { .conn_cfg_tag = CONFIG_NRF_SDH_BLE_CONN_TAG, .evt_handler = ble_adv_evt_handler, @@ -210,6 +215,13 @@ int main(void) LOG_INF("Bluetooth enabled"); + err = settings_subsys_init(); + + if (err) { + LOG_ERR("Failed to enable settings, err %d", err); + } + + settings_load(); err = ble_mcumgr_init(); if (err) { @@ -237,6 +249,29 @@ int main(void) return 0; } + custom_advertising_name = bluetooth_name_value_get(); + custom_advertising_name_size = strlen(custom_advertising_name); + + if (custom_advertising_name_size > 0) { + /* Change advertising name to one from application */ + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + err = sd_ble_gap_device_name_set(&sec_mode, custom_advertising_name, + custom_advertising_name_size); + + if (err) { + LOG_ERR("Failed to change advertising name, err %d", err); + return 0; + } + + err = ble_adv_data_encode(&ble_adv_cfg.adv_data, ble_adv.enc_adv_data[0], + &ble_adv.adv_data.adv_data.len); + + if (err) { + LOG_ERR("Failed to update advertising data, err %d", err); + return 0; + } + } + err = ble_adv_start(&ble_adv, BLE_ADV_MODE_FAST); if (err) { @@ -244,7 +279,8 @@ int main(void) return 0; } - LOG_INF("Advertising as %s", CONFIG_BLE_ADV_NAME); + LOG_INF("Advertising as %s", (custom_advertising_name_size > 0 ? custom_advertising_name : + CONFIG_BLE_ADV_NAME)); while (notification_sent == false && device_disconnected == false) { while (LOG_PROCESS()) { From 93fffd69717b3f35fccc4148c7f1a2281fed41c5 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 15 Aug 2025 14:43:48 +0100 Subject: [PATCH 4/5] samples: boot: mcuboot_recovery_entry: Add settings test code Adds code to set bluetooth name to retention settings Signed-off-by: Jamie McCrae --- samples/boot/mcuboot_recovery_entry/prj.conf | 6 ++++++ samples/boot/mcuboot_recovery_entry/src/main.c | 9 +++++++++ samples/mcumgr/ble_mcumgr/src/main.c | 9 +++++++++ 3 files changed, 24 insertions(+) diff --git a/samples/boot/mcuboot_recovery_entry/prj.conf b/samples/boot/mcuboot_recovery_entry/prj.conf index ac910524c4..7e4de16646 100644 --- a/samples/boot/mcuboot_recovery_entry/prj.conf +++ b/samples/boot/mcuboot_recovery_entry/prj.conf @@ -47,3 +47,9 @@ CONFIG_NRF_SDH_BLE_GATT_MAX_MTU_SIZE=498 CONFIG_BLE_CONN_PARAMS_MAX_CONN_INTERVAL=24 CONFIG_BLE_CONN_PARAMS_SUP_TIMEOUT=20 CONFIG_BLE_CONN_PARAMS_MAX_SUP_TIMEOUT_DEVIATION=20 + +CONFIG_SETTINGS=y +CONFIG_SETTINGS_RETENTION=y +CONFIG_SETTINGS_RUNTIME=y +CONFIG_MCUMGR_GRP_SETTINGS=y +CONFIG_NCS_BM_SETTINGS_BLUETOOTH_NAME=y diff --git a/samples/boot/mcuboot_recovery_entry/src/main.c b/samples/boot/mcuboot_recovery_entry/src/main.c index 378f9c65f1..6437efbc81 100644 --- a/samples/boot/mcuboot_recovery_entry/src/main.c +++ b/samples/boot/mcuboot_recovery_entry/src/main.c @@ -13,6 +13,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(app, CONFIG_APP_LOG_LEVEL); @@ -180,6 +181,14 @@ int main(void) return 0; } + err = settings_subsys_init(); + + if (err) { + LOG_ERR("Failed to enable settings: %d", err); + } + +/* settings_load(); */ + LOG_INF("Bluetooth enabled"); err = ble_mcumgr_init(); diff --git a/samples/mcumgr/ble_mcumgr/src/main.c b/samples/mcumgr/ble_mcumgr/src/main.c index beff2aa94b..c0b77df707 100644 --- a/samples/mcumgr/ble_mcumgr/src/main.c +++ b/samples/mcumgr/ble_mcumgr/src/main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(app, CONFIG_APP_LOG_LEVEL); @@ -270,6 +271,14 @@ int main(void) LOG_ERR("Failed to update advertising data, err %d", err); return 0; } + + /* Clear settings after device name has been set so it does not persist */ + err = retention_clear(DEVICE_DT_GET(DT_CHOSEN(zephyr_settings_partition))); + + if (err) { + LOG_ERR("Failed to clear retention area, err %d", err); + return 0; + } } err = ble_adv_start(&ble_adv, BLE_ADV_MODE_FAST); From 7c4f06cee8b54034cf1ed06262115b0ccde7afab Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 18 Aug 2025 14:19:42 +0100 Subject: [PATCH 5/5] codeowners: Add entry for settings Assigns this to pluto Signed-off-by: Jamie McCrae --- CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CODEOWNERS b/CODEOWNERS index c5f72620f9..1beb2344d1 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -41,6 +41,7 @@ # Include /include/*.h @nrfconnect/ncs-bm /include/bluetooth/ @nrfconnect/ncs-bm +/include/settings/ @nrfconnect/ncs-pluto # Libraries /lib/ble_adv/ @nrfconnect/ncs-bm @@ -75,6 +76,7 @@ /subsys/bm_installs/ @nrfconnect/ncs-pluto /subsys/logging/ @nrfconnect/ncs-bm /subsys/mgmt/mcumgr/ @nrfconnect/ncs-pluto +/subsys/settings/ @nrfconnect/ncs-pluto /subsys/softdevice/ @nrfconnect/ncs-bm /subsys/softdevice_handler/ @nrfconnect/ncs-bm /subsys/storage/flash_map/ @nrfconnect/ncs-pluto