From 6d54560543214e05b7b762ae24421add68110c03 Mon Sep 17 00:00:00 2001 From: Zhijie Zhong Date: Wed, 29 Oct 2025 11:31:01 +0800 Subject: [PATCH 01/10] [nrf fromtree] bluetooth: host: Add bt_gatt_cb_unregister() to unregister GATT callbacks New API bt_gatt_cb_unregister, use _SAFE iteration for callback list. Signed-off-by: Zhijie Zhong (cherry picked from commit c222dcff8c35539d62a8a901b09ea4329877d023) --- doc/releases/release-notes-4.4.rst | 6 ++++++ include/zephyr/bluetooth/gatt.h | 11 +++++++++++ subsys/bluetooth/host/gatt.c | 17 +++++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index d6277acc7161..9622d9c5bd38 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -65,6 +65,12 @@ Deprecated APIs and options New APIs and options ==================== +* Bluetooth + + * Host + + * :c:func:`bt_gatt_cb_unregister` Added an API to unregister GATT callback handlers. + .. Link to new APIs here, in a group if you think it's necessary, no need to get fancy just list the link, that should contain the documentation. If you feel diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index 17b125d602c5..8023e3a0d9ee 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -622,6 +622,17 @@ static inline const char *bt_gatt_err_to_str(int gatt_err) */ void bt_gatt_cb_register(struct bt_gatt_cb *cb); +/** @brief Unregister GATT callbacks. + * + * Unregister callbacks for monitoring the state of GATT. The callback + * struct should be one that was previously registered. + * + * @param cb Callback struct. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_cb_unregister(struct bt_gatt_cb *cb); + /** @brief Register GATT authorization callbacks. * * Register callbacks to perform application-specific authorization of GATT diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index ea1dc73e158a..4e8b7c78244c 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -1628,6 +1628,19 @@ void bt_gatt_cb_register(struct bt_gatt_cb *cb) sys_slist_append(&callback_list, &cb->node); } +int bt_gatt_cb_unregister(struct bt_gatt_cb *cb) +{ + if (cb == NULL) { + return -EINVAL; + } + + if (!sys_slist_find_and_remove(&callback_list, &cb->node)) { + return -ENOENT; + } + + return 0; +} + #if defined(CONFIG_BT_GATT_DYNAMIC_DB) static void db_changed(void) { @@ -6023,9 +6036,9 @@ void bt_gatt_connected(struct bt_conn *conn) void bt_gatt_att_max_mtu_changed(struct bt_conn *conn, uint16_t tx, uint16_t rx) { - struct bt_gatt_cb *cb; + struct bt_gatt_cb *cb, *tmp; - SYS_SLIST_FOR_EACH_CONTAINER(&callback_list, cb, node) { + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&callback_list, cb, tmp, node) { if (cb->att_mtu_updated) { cb->att_mtu_updated(conn, tx, rx); } From daf04601d8ccfd13cd6a762c5e87f0f7befe42b7 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 11 Nov 2025 14:18:16 +0100 Subject: [PATCH 02/10] [nrf fromtree] bluetooth: host: Deprecate CONFIG_BT_SIGNING This commit deprecates: - the `CONFIG_BT_SIGNING` Kconfig option - `BT_GATT_CHRC_AUTH` property IOW, this commit deprecates the LE Security mode 2 support. Explanation: Erratum ES-26047 introduced in Bluetooth Core Specification v6.2 requires SingCounter to be persistently stored to prevent replay attacks. Currently, the Host doesn't store SignCounter, therefore the device is vulnerable to replay attacks after reboot. Additionally, the current implementation doesn't assume that SignCounter of a received message can be incremented by more than one and thus may not validate correct message. The Bluetooth Security and Privacy Best Practices Guide recommends to not using Data signing and recommends to use LE Security mode 1 levels 2, 3 or 4 instead. The Signed Write Without Response sub-procedure, which is the only user of Data signing, is optional (see Vol 3, Part G, Table 4.1). See also ES-18901. The aforementioned reasons make no sense to keep this feature. Signed-off-by: Pavel Vasilyev (cherry picked from commit b7b35b89edb571be60fce832cb61fdc293e3ca2a) --- doc/releases/migration-guide-4.4.rst | 6 ++++ include/zephyr/bluetooth/gatt.h | 4 ++- samples/bluetooth/direct_adv/prj.conf | 1 - samples/bluetooth/direct_adv/src/main.c | 23 +++++++------ samples/bluetooth/peripheral/prj.conf | 1 - samples/bluetooth/peripheral/src/main.c | 33 ------------------- .../bluetooth/peripheral_accept_list/prj.conf | 1 - .../peripheral_accept_list/src/main.c | 18 +++++----- subsys/bluetooth/host/Kconfig | 1 + subsys/bluetooth/host/shell/gatt.c | 4 --- tests/bluetooth/init/prj_10.conf | 1 - tests/bluetooth/init/prj_11.conf | 1 - tests/bluetooth/init/prj_12.conf | 1 - tests/bluetooth/init/prj_13.conf | 1 - tests/bluetooth/init/prj_14.conf | 1 - tests/bluetooth/init/prj_17.conf | 1 - tests/bluetooth/init/prj_20.conf | 1 - tests/bluetooth/init/prj_21.conf | 1 - tests/bluetooth/init/prj_7.conf | 1 - tests/bluetooth/init/prj_8.conf | 1 - tests/bluetooth/init/prj_9.conf | 1 - tests/bluetooth/init/prj_ctlr.conf | 1 - tests/bluetooth/init/prj_ctlr_4_0.conf | 1 - tests/bluetooth/init/prj_ctlr_4_0_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_5_x_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_dbg.conf | 1 - tests/bluetooth/init/prj_ctlr_ticker.conf | 1 - tests/bluetooth/init/prj_ctlr_tiny.conf | 1 - tests/bluetooth/init/prj_llcp.conf | 1 - tests/bluetooth/shell/audio.conf | 1 - tests/bluetooth/shell/log.conf | 1 - tests/bluetooth/shell/mesh.conf | 1 - tests/bluetooth/shell/prj.conf | 1 - tests/bluetooth/shell/prj_br.conf | 1 - tests/bluetooth/tester/prj.conf | 1 - tests/bluetooth/tester/src/btp/btp_gatt.h | 8 ----- tests/bluetooth/tester/src/btp_gatt.c | 33 ------------------- tests/bsim/bluetooth/ll/conn/prj_split.conf | 1 - .../bsim/bluetooth/ll/conn/prj_split_1ms.conf | 1 - .../bluetooth/ll/conn/prj_split_hci_uart.conf | 1 - .../bluetooth/ll/conn/prj_split_low_lat.conf | 1 - .../bluetooth/ll/conn/prj_split_privacy.conf | 1 - .../ll/conn/prj_split_single_timer.conf | 1 - .../bluetooth/ll/conn/prj_split_tx_defer.conf | 1 - .../edtt/gatt_test_app/src/gatt/service_f_1.c | 3 +- .../ll/edtt/tests_scripts/gatt.llcp.test_list | 8 ++--- tests/bsim/bluetooth/tester/src/bsim_btp.c | 2 -- 47 files changed, 36 insertions(+), 142 deletions(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index b10c86e9f23b..7966cd0f25e3 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -35,6 +35,12 @@ Device Drivers and Devicetree Bluetooth ********* +Bluetooth Host +============== + +* :kconfig:option:`CONFIG_BT_SIGNING` has been deprecated. +* :c:macro:`BT_GATT_CHRC_AUTH` has been deprecated. + Networking ********** diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index 8023e3a0d9ee..353f8b248edd 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -462,9 +462,11 @@ struct bt_gatt_authorization_cb { /** * @brief Characteristic Authenticated Signed Writes property. * + * @deprecated This API is deprecated. + * * If set, permits signed writes to the Characteristic Value. */ -#define BT_GATT_CHRC_AUTH 0x40 +#define BT_GATT_CHRC_AUTH 0x40 __DEPRECATED_MACRO /** * @brief Characteristic Extended Properties property. * diff --git a/samples/bluetooth/direct_adv/prj.conf b/samples/bluetooth/direct_adv/prj.conf index 2af54670b51c..410ed9166302 100644 --- a/samples/bluetooth/direct_adv/prj.conf +++ b/samples/bluetooth/direct_adv/prj.conf @@ -4,7 +4,6 @@ CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_BT=y CONFIG_LOG=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DIS=y CONFIG_BT_ATT_PREPARE_COUNT=1 diff --git a/samples/bluetooth/direct_adv/src/main.c b/samples/bluetooth/direct_adv/src/main.c index 992c6e46059c..24c3a53940c1 100644 --- a/samples/bluetooth/direct_adv/src/main.c +++ b/samples/bluetooth/direct_adv/src/main.c @@ -32,26 +32,25 @@ static const struct bt_uuid_128 read_characteristic_uuid = BT_UUID_INIT_128( static const struct bt_uuid_128 write_characteristic_uuid = BT_UUID_INIT_128( BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef2)); -static int signed_value; +static int stored_value; static struct bt_le_adv_param adv_param; static bt_addr_le_t bond_addr; -static ssize_t read_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr, - void *buf, uint16_t len, uint16_t offset) +static ssize_t read_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) { - int *value = &signed_value; + int *value = &stored_value; return bt_gatt_attr_read(conn, attr, buf, len, offset, value, - sizeof(signed_value)); + sizeof(stored_value)); } -static ssize_t write_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr, - const void *buf, uint16_t len, uint16_t offset, - uint8_t flags) +static ssize_t write_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, + uint16_t len, uint16_t offset, uint8_t flags) { - int *value = &signed_value; + int *value = &stored_value; - if (offset + len > sizeof(signed_value)) { + if (offset + len > sizeof(stored_value)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); } @@ -66,11 +65,11 @@ BT_GATT_SERVICE_DEFINE(primary_service, BT_GATT_CHARACTERISTIC(&read_characteristic_uuid.uuid, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, - read_signed, NULL, NULL), + read_cb, NULL, NULL), BT_GATT_CHARACTERISTIC(&write_characteristic_uuid.uuid, BT_GATT_CHRC_WRITE, BT_GATT_PERM_WRITE_ENCRYPT, - NULL, write_signed, NULL), + NULL, write_cb, NULL), ); static const struct bt_data ad[] = { diff --git a/samples/bluetooth/peripheral/prj.conf b/samples/bluetooth/peripheral/prj.conf index f788fa670aa3..493660afa339 100644 --- a/samples/bluetooth/peripheral/prj.conf +++ b/samples/bluetooth/peripheral/prj.conf @@ -4,7 +4,6 @@ CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_BT=y CONFIG_LOG=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DIS=y CONFIG_BT_ATT_PREPARE_COUNT=5 diff --git a/samples/bluetooth/peripheral/src/main.c b/samples/bluetooth/peripheral/src/main.c index db77691db613..3f15aee100af 100644 --- a/samples/bluetooth/peripheral/src/main.c +++ b/samples/bluetooth/peripheral/src/main.c @@ -130,35 +130,6 @@ static struct bt_gatt_cep vnd_long_cep = { .properties = BT_GATT_CEP_RELIABLE_WRITE, }; -static int signed_value; - -static ssize_t read_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr, - void *buf, uint16_t len, uint16_t offset) -{ - const char *value = attr->user_data; - - return bt_gatt_attr_read(conn, attr, buf, len, offset, value, - sizeof(signed_value)); -} - -static ssize_t write_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr, - const void *buf, uint16_t len, uint16_t offset, - uint8_t flags) -{ - uint8_t *value = attr->user_data; - - if (offset + len > sizeof(signed_value)) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); - } - - memcpy(value + offset, buf, len); - - return len; -} - -static const struct bt_uuid_128 vnd_signed_uuid = BT_UUID_INIT_128( - BT_UUID_128_ENCODE(0x13345678, 0x1234, 0x5678, 0x1334, 0x56789abcdef3)); - static const struct bt_uuid_128 vnd_write_cmd_uuid = BT_UUID_INIT_128( BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef4)); @@ -208,10 +179,6 @@ BT_GATT_SERVICE_DEFINE(vnd_svc, BT_GATT_PERM_PREPARE_WRITE, read_vnd, write_long_vnd, &vnd_long_value), BT_GATT_CEP(&vnd_long_cep), - BT_GATT_CHARACTERISTIC(&vnd_signed_uuid.uuid, BT_GATT_CHRC_READ | - BT_GATT_CHRC_WRITE | BT_GATT_CHRC_AUTH, - BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, - read_signed, write_signed, &signed_value), BT_GATT_CHARACTERISTIC(&vnd_write_cmd_uuid.uuid, BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE, NULL, diff --git a/samples/bluetooth/peripheral_accept_list/prj.conf b/samples/bluetooth/peripheral_accept_list/prj.conf index 563ee758d2ec..a9a0e6ecedc8 100644 --- a/samples/bluetooth/peripheral_accept_list/prj.conf +++ b/samples/bluetooth/peripheral_accept_list/prj.conf @@ -4,7 +4,6 @@ CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_BT=y CONFIG_LOG=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DIS=y CONFIG_BT_ATT_PREPARE_COUNT=1 diff --git a/samples/bluetooth/peripheral_accept_list/src/main.c b/samples/bluetooth/peripheral_accept_list/src/main.c index e14ea8dd9977..fcb930bdca55 100644 --- a/samples/bluetooth/peripheral_accept_list/src/main.c +++ b/samples/bluetooth/peripheral_accept_list/src/main.c @@ -29,26 +29,26 @@ static const struct bt_uuid_128 read_characteristic_uuid = BT_UUID_INIT_128( static const struct bt_uuid_128 write_characteristic_uuid = BT_UUID_INIT_128( BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef2)); -static int signed_value; +static int stored_value; static struct bt_le_adv_param adv_param; static int bond_count; -static ssize_t read_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr, +static ssize_t read_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - int *value = &signed_value; + int *value = &stored_value; return bt_gatt_attr_read(conn, attr, buf, len, offset, value, - sizeof(signed_value)); + sizeof(stored_value)); } -static ssize_t write_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr, +static ssize_t write_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) { - int *value = &signed_value; + int *value = &stored_value; - if (offset + len > sizeof(signed_value)) { + if (offset + len > sizeof(stored_value)) { return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); } @@ -63,11 +63,11 @@ BT_GATT_SERVICE_DEFINE(primary_service, BT_GATT_CHARACTERISTIC(&read_characteristic_uuid.uuid, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, - read_signed, NULL, NULL), + read_cb, NULL, NULL), BT_GATT_CHARACTERISTIC(&write_characteristic_uuid.uuid, BT_GATT_CHRC_WRITE, BT_GATT_PERM_WRITE_ENCRYPT, - NULL, write_signed, NULL), + NULL, write_cb, NULL), ); static const struct bt_data ad[] = { diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 0d0bfd20a883..9eba33273066 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -562,6 +562,7 @@ config BT_RPA_SHARING config BT_SIGNING bool "Data signing support" + select DEPRECATED help This option enables data signing which is used for transferring authenticated data in an unencrypted connection. diff --git a/subsys/bluetooth/host/shell/gatt.c b/subsys/bluetooth/host/shell/gatt.c index 00dbd8dc8e26..013b878a6af3 100644 --- a/subsys/bluetooth/host/shell/gatt.c +++ b/subsys/bluetooth/host/shell/gatt.c @@ -172,10 +172,6 @@ static void print_chrc_props(uint8_t properties) bt_shell_print("[indicate]"); } - if (properties & BT_GATT_CHRC_AUTH) { - bt_shell_print("[auth]"); - } - if (properties & BT_GATT_CHRC_EXT_PROP) { bt_shell_print("[ext prop]"); } diff --git a/tests/bluetooth/init/prj_10.conf b/tests/bluetooth/init/prj_10.conf index 81503cadb9a1..a44edf5f7b64 100644 --- a/tests/bluetooth/init/prj_10.conf +++ b/tests/bluetooth/init/prj_10.conf @@ -2,7 +2,6 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/prj_11.conf b/tests/bluetooth/init/prj_11.conf index a5492c5c1eb4..84510c4b8c86 100644 --- a/tests/bluetooth/init/prj_11.conf +++ b/tests/bluetooth/init/prj_11.conf @@ -2,7 +2,6 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_12.conf b/tests/bluetooth/init/prj_12.conf index 16fc86e8f823..3bf4b202d62e 100644 --- a/tests/bluetooth/init/prj_12.conf +++ b/tests/bluetooth/init/prj_12.conf @@ -1,7 +1,6 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_13.conf b/tests/bluetooth/init/prj_13.conf index aa8cc1220837..426b3d6aed5f 100644 --- a/tests/bluetooth/init/prj_13.conf +++ b/tests/bluetooth/init/prj_13.conf @@ -1,7 +1,6 @@ CONFIG_BT=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_14.conf b/tests/bluetooth/init/prj_14.conf index 93423f647420..2a8566b9b467 100644 --- a/tests/bluetooth/init/prj_14.conf +++ b/tests/bluetooth/init/prj_14.conf @@ -2,5 +2,4 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/prj_17.conf b/tests/bluetooth/init/prj_17.conf index 5e504b9ead15..e179900c641b 100644 --- a/tests/bluetooth/init/prj_17.conf +++ b/tests/bluetooth/init/prj_17.conf @@ -2,7 +2,6 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_20.conf b/tests/bluetooth/init/prj_20.conf index 4b80a6b44271..80c0ad4657d4 100644 --- a/tests/bluetooth/init/prj_20.conf +++ b/tests/bluetooth/init/prj_20.conf @@ -2,7 +2,6 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_21.conf b/tests/bluetooth/init/prj_21.conf index 49c4c6eb452b..d796dcbdfc4a 100644 --- a/tests/bluetooth/init/prj_21.conf +++ b/tests/bluetooth/init/prj_21.conf @@ -2,7 +2,6 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_7.conf b/tests/bluetooth/init/prj_7.conf index 93423f647420..2a8566b9b467 100644 --- a/tests/bluetooth/init/prj_7.conf +++ b/tests/bluetooth/init/prj_7.conf @@ -2,5 +2,4 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/prj_8.conf b/tests/bluetooth/init/prj_8.conf index 2fdd77730098..6dfcf4d7f59c 100644 --- a/tests/bluetooth/init/prj_8.conf +++ b/tests/bluetooth/init/prj_8.conf @@ -2,6 +2,5 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/prj_9.conf b/tests/bluetooth/init/prj_9.conf index 2fdd77730098..6dfcf4d7f59c 100644 --- a/tests/bluetooth/init/prj_9.conf +++ b/tests/bluetooth/init/prj_9.conf @@ -2,6 +2,5 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/prj_ctlr.conf b/tests/bluetooth/init/prj_ctlr.conf index c733ef4ad3fc..67a638b1e078 100644 --- a/tests/bluetooth/init/prj_ctlr.conf +++ b/tests/bluetooth/init/prj_ctlr.conf @@ -3,7 +3,6 @@ CONFIG_BT_HCI_ACL_FLOW_CONTROL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y diff --git a/tests/bluetooth/init/prj_ctlr_4_0.conf b/tests/bluetooth/init/prj_ctlr_4_0.conf index 98dcaaa746c8..da51ab380e86 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0.conf @@ -27,7 +27,6 @@ CONFIG_BT_HCI_VS=n CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y diff --git a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf index 476213c82731..bc4125363d60 100644 --- a/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_4_0_dbg.conf @@ -31,7 +31,6 @@ CONFIG_BT_CTLR_VS_SCAN_REQ_RX=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y diff --git a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf index 828b486b88fc..0793716a8674 100644 --- a/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_5_x_dbg.conf @@ -55,7 +55,6 @@ CONFIG_BT_ISO_SYNC_RECEIVER=y CONFIG_BT_ISO_CENTRAL=y CONFIG_BT_ISO_PERIPHERAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_ctlr_dbg.conf b/tests/bluetooth/init/prj_ctlr_dbg.conf index 956c562c5aa0..497d684c9e29 100644 --- a/tests/bluetooth/init/prj_ctlr_dbg.conf +++ b/tests/bluetooth/init/prj_ctlr_dbg.conf @@ -39,7 +39,6 @@ CONFIG_BT_HCI_MESH_EXT=n CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_ctlr_ticker.conf b/tests/bluetooth/init/prj_ctlr_ticker.conf index ac15e8662a6b..bf5f351c72a2 100644 --- a/tests/bluetooth/init/prj_ctlr_ticker.conf +++ b/tests/bluetooth/init/prj_ctlr_ticker.conf @@ -37,7 +37,6 @@ CONFIG_BT_HCI_MESH_EXT=n CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_USE_DEBUG_KEYS=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/init/prj_ctlr_tiny.conf b/tests/bluetooth/init/prj_ctlr_tiny.conf index e3413d68e981..b625ea9918bb 100644 --- a/tests/bluetooth/init/prj_ctlr_tiny.conf +++ b/tests/bluetooth/init/prj_ctlr_tiny.conf @@ -31,7 +31,6 @@ CONFIG_BT_HCI_VS=n CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y diff --git a/tests/bluetooth/init/prj_llcp.conf b/tests/bluetooth/init/prj_llcp.conf index 2bbcfb83834a..2baa0f1e158e 100644 --- a/tests/bluetooth/init/prj_llcp.conf +++ b/tests/bluetooth/init/prj_llcp.conf @@ -3,7 +3,6 @@ CONFIG_BT_HCI_ACL_FLOW_CONTROL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_SMP_SC_ONLY=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BT_GATT_CLIENT=y diff --git a/tests/bluetooth/shell/audio.conf b/tests/bluetooth/shell/audio.conf index 45236a49afae..a7f19336e777 100644 --- a/tests/bluetooth/shell/audio.conf +++ b/tests/bluetooth/shell/audio.conf @@ -21,7 +21,6 @@ CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y CONFIG_BT_GATT_AUTO_UPDATE_MTU=y CONFIG_BT_L2CAP_ECRED=y -CONFIG_BT_SIGNING=y CONFIG_BT_APP_PASSKEY=y CONFIG_BT_ATT_PREPARE_COUNT=5 CONFIG_BT_SHELL=y diff --git a/tests/bluetooth/shell/log.conf b/tests/bluetooth/shell/log.conf index 2da43186e19f..7cb83fb87644 100644 --- a/tests/bluetooth/shell/log.conf +++ b/tests/bluetooth/shell/log.conf @@ -8,7 +8,6 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_APP_PASSKEY=y CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_GATT_CLIENT=y diff --git a/tests/bluetooth/shell/mesh.conf b/tests/bluetooth/shell/mesh.conf index 0336d417fb51..1e11b5ae75ca 100644 --- a/tests/bluetooth/shell/mesh.conf +++ b/tests/bluetooth/shell/mesh.conf @@ -9,7 +9,6 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_GATT_CLIENT=y CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y diff --git a/tests/bluetooth/shell/prj.conf b/tests/bluetooth/shell/prj.conf index 2c84d55bd69a..8a9fb1c0ee9e 100644 --- a/tests/bluetooth/shell/prj.conf +++ b/tests/bluetooth/shell/prj.conf @@ -10,7 +10,6 @@ CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y CONFIG_BT_PASSKEY_KEYPRESS=y -CONFIG_BT_SIGNING=y CONFIG_BT_APP_PASSKEY=y CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_GATT_CLIENT=y diff --git a/tests/bluetooth/shell/prj_br.conf b/tests/bluetooth/shell/prj_br.conf index 3f27954ca230..e9afa4026a34 100644 --- a/tests/bluetooth/shell/prj_br.conf +++ b/tests/bluetooth/shell/prj_br.conf @@ -11,7 +11,6 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_ATT_PREPARE_COUNT=2 CONFIG_BT_GATT_CLIENT=y CONFIG_BT_HRS=y diff --git a/tests/bluetooth/tester/prj.conf b/tests/bluetooth/tester/prj.conf index 382ed5eb6cdc..901042287ce9 100644 --- a/tests/bluetooth/tester/prj.conf +++ b/tests/bluetooth/tester/prj.conf @@ -14,7 +14,6 @@ CONFIG_BT_SMP_MIN_ENC_KEY_SIZE=7 CONFIG_BT_SMP_ENFORCE_MITM=n CONFIG_BT_SMP_ALLOW_UNAUTH_OVERWRITE=y CONFIG_BT_SMP_APP_PAIRING_ACCEPT=y -CONFIG_BT_SIGNING=y CONFIG_BT_BONDABLE=y CONFIG_BT_ATT_PREPARE_COUNT=12 CONFIG_BT_GATT_CLIENT=y diff --git a/tests/bluetooth/tester/src/btp/btp_gatt.h b/tests/bluetooth/tester/src/btp/btp_gatt.h index e26b3767b6a9..1eef848aa30e 100644 --- a/tests/bluetooth/tester/src/btp/btp_gatt.h +++ b/tests/bluetooth/tester/src/btp/btp_gatt.h @@ -240,14 +240,6 @@ struct btp_gatt_write_without_rsp_cmd { uint8_t data[]; } __packed; -#define BTP_GATT_SIGNED_WRITE_WITHOUT_RSP 0x16 -struct btp_gatt_signed_write_without_rsp_cmd { - bt_addr_le_t address; - uint16_t handle; - uint16_t data_length; - uint8_t data[]; -} __packed; - #define BTP_GATT_WRITE 0x17 struct btp_gatt_write_cmd { bt_addr_le_t address; diff --git a/tests/bluetooth/tester/src/btp_gatt.c b/tests/bluetooth/tester/src/btp_gatt.c index e5f4b9584937..e487dd2884d1 100644 --- a/tests/bluetooth/tester/src/btp_gatt.c +++ b/tests/bluetooth/tester/src/btp_gatt.c @@ -1757,34 +1757,6 @@ static uint8_t write_without_rsp(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } -static uint8_t write_signed_without_rsp(const void *cmd, uint16_t cmd_len, - void *rsp, uint16_t *rsp_len) -{ - const struct btp_gatt_signed_write_without_rsp_cmd *cp = cmd; - struct bt_conn *conn; - - if (cmd_len < sizeof(*cp) || - cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) { - return BTP_STATUS_FAILED; - } - - conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address); - if (!conn) { - return BTP_STATUS_FAILED; - } - - if (bt_gatt_write_without_response(conn, sys_le16_to_cpu(cp->handle), - cp->data, - sys_le16_to_cpu(cp->data_length), - true) < 0) { - bt_conn_unref(conn); - return BTP_STATUS_FAILED; - } - - bt_conn_unref(conn); - return BTP_STATUS_SUCCESS; -} - static void write_rsp(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params) { @@ -2533,11 +2505,6 @@ static const struct btp_handler handlers[] = { .expect_len = BTP_HANDLER_LENGTH_VARIABLE, .func = write_without_rsp, }, - { - .opcode = BTP_GATT_SIGNED_WRITE_WITHOUT_RSP, - .expect_len = BTP_HANDLER_LENGTH_VARIABLE, - .func = write_signed_without_rsp, - }, { .opcode = BTP_GATT_WRITE, .expect_len = BTP_HANDLER_LENGTH_VARIABLE, diff --git a/tests/bsim/bluetooth/ll/conn/prj_split.conf b/tests/bsim/bluetooth/ll/conn/prj_split.conf index 94eae38bf62e..c888d586e4b3 100644 --- a/tests/bsim/bluetooth/ll/conn/prj_split.conf +++ b/tests/bsim/bluetooth/ll/conn/prj_split.conf @@ -4,7 +4,6 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_BAS=y CONFIG_BT_HRS=y CONFIG_BT_ATT_PREPARE_COUNT=2 diff --git a/tests/bsim/bluetooth/ll/conn/prj_split_1ms.conf b/tests/bsim/bluetooth/ll/conn/prj_split_1ms.conf index 58276bd991e6..def3752f0167 100644 --- a/tests/bsim/bluetooth/ll/conn/prj_split_1ms.conf +++ b/tests/bsim/bluetooth/ll/conn/prj_split_1ms.conf @@ -4,7 +4,6 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_BAS=y CONFIG_BT_HRS=y CONFIG_BT_ATT_PREPARE_COUNT=2 diff --git a/tests/bsim/bluetooth/ll/conn/prj_split_hci_uart.conf b/tests/bsim/bluetooth/ll/conn/prj_split_hci_uart.conf index f97b14c88a7b..0ef6b9fb783d 100644 --- a/tests/bsim/bluetooth/ll/conn/prj_split_hci_uart.conf +++ b/tests/bsim/bluetooth/ll/conn/prj_split_hci_uart.conf @@ -5,7 +5,6 @@ CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y CONFIG_BT_SMP_SC_PAIR_ONLY=n -CONFIG_BT_SIGNING=y CONFIG_BT_BAS=y CONFIG_BT_HRS=y CONFIG_BT_ATT_PREPARE_COUNT=2 diff --git a/tests/bsim/bluetooth/ll/conn/prj_split_low_lat.conf b/tests/bsim/bluetooth/ll/conn/prj_split_low_lat.conf index b00b6c74b934..b07055f8dba6 100644 --- a/tests/bsim/bluetooth/ll/conn/prj_split_low_lat.conf +++ b/tests/bsim/bluetooth/ll/conn/prj_split_low_lat.conf @@ -4,7 +4,6 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_BAS=y CONFIG_BT_HRS=y CONFIG_BT_ATT_PREPARE_COUNT=2 diff --git a/tests/bsim/bluetooth/ll/conn/prj_split_privacy.conf b/tests/bsim/bluetooth/ll/conn/prj_split_privacy.conf index 1147e89ada69..02e83a4351f7 100644 --- a/tests/bsim/bluetooth/ll/conn/prj_split_privacy.conf +++ b/tests/bsim/bluetooth/ll/conn/prj_split_privacy.conf @@ -5,7 +5,6 @@ CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y CONFIG_BT_SMP_SC_PAIR_ONLY=n -CONFIG_BT_SIGNING=y CONFIG_BT_BAS=y CONFIG_BT_HRS=y CONFIG_BT_ATT_PREPARE_COUNT=2 diff --git a/tests/bsim/bluetooth/ll/conn/prj_split_single_timer.conf b/tests/bsim/bluetooth/ll/conn/prj_split_single_timer.conf index 9d446e0149f8..461b5e800958 100644 --- a/tests/bsim/bluetooth/ll/conn/prj_split_single_timer.conf +++ b/tests/bsim/bluetooth/ll/conn/prj_split_single_timer.conf @@ -4,7 +4,6 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_BAS=y CONFIG_BT_HRS=y CONFIG_BT_ATT_PREPARE_COUNT=2 diff --git a/tests/bsim/bluetooth/ll/conn/prj_split_tx_defer.conf b/tests/bsim/bluetooth/ll/conn/prj_split_tx_defer.conf index 22dc32be4c42..147a8f7598bb 100644 --- a/tests/bsim/bluetooth/ll/conn/prj_split_tx_defer.conf +++ b/tests/bsim/bluetooth/ll/conn/prj_split_tx_defer.conf @@ -4,7 +4,6 @@ CONFIG_BT_CENTRAL=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_PRIVACY=y CONFIG_BT_SMP=y -CONFIG_BT_SIGNING=y CONFIG_BT_BAS=y CONFIG_BT_HRS=y CONFIG_BT_ATT_PREPARE_COUNT=2 diff --git a/tests/bsim/bluetooth/ll/edtt/gatt_test_app/src/gatt/service_f_1.c b/tests/bsim/bluetooth/ll/edtt/gatt_test_app/src/gatt/service_f_1.c index 374e639862af..04ea7f4b7c5d 100644 --- a/tests/bsim/bluetooth/ll/edtt/gatt_test_app/src/gatt/service_f_1.c +++ b/tests/bsim/bluetooth/ll/edtt/gatt_test_app/src/gatt/service_f_1.c @@ -1,5 +1,6 @@ /** * Copyright (c) 2019 Oticon A/S + * Copyright (c) 2025 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -381,7 +382,7 @@ static struct bt_gatt_attr service_f_1_attrs[] = { BT_GATT_PERM_READ, read_agg_format, NULL, &agg_format_value, 0xAF), BT_GATT_H_CHARACTERISTIC(BT_UUID_VALUE_V17, - BT_GATT_CHRC_READ | BT_GATT_CHRC_AUTH, + BT_GATT_CHRC_READ, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, read_value_v17, NULL, &value_v17_value, 0xB0) }; diff --git a/tests/bsim/bluetooth/ll/edtt/tests_scripts/gatt.llcp.test_list b/tests/bsim/bluetooth/ll/edtt/tests_scripts/gatt.llcp.test_list index d606038298ce..d8ccaee301ef 100644 --- a/tests/bsim/bluetooth/ll/edtt/tests_scripts/gatt.llcp.test_list +++ b/tests/bsim/bluetooth/ll/edtt/tests_scripts/gatt.llcp.test_list @@ -8,8 +8,8 @@ GATT/SR/GAC/BV-01-C GATT/SR/GAD/BV-01-C GATT/SR/GAD/BV-02-C GATT/SR/GAD/BV-03-C -GATT/SR/GAD/BV-04-C -GATT/SR/GAD/BV-05-C +# GATT/SR/GAD/BV-04-C https://github.com/EDTTool/EDTT/issues/89 +# GATT/SR/GAD/BV-05-C https://github.com/EDTTool/EDTT/issues/89 GATT/SR/GAD/BV-06-C GATT/SR/GAR/BV-01-C GATT/SR/GAR/BI-01-C @@ -22,7 +22,7 @@ GATT/SR/GAR/BI-07-C GATT/SR/GAR/BI-09-C GATT/SR/GAR/BI-10-C #GATT/SR/GAR/BI-11-C https://github.com/EDTTool/EDTT/issues/82 -GATT/SR/GAR/BV-04-C +# GATT/SR/GAR/BV-04-C https://github.com/EDTTool/EDTT/issues/89 GATT/SR/GAR/BI-12-C GATT/SR/GAR/BI-13-C GATT/SR/GAR/BI-14-C @@ -64,7 +64,7 @@ GATT/SR/UNS/BI-02-C GATT/SR/GPA/BV-01-C GATT/SR/GPA/BV-02-C GATT/SR/GPA/BV-03-C -GATT/SR/GPA/BV-04-C +# GATT/SR/GPA/BV-04-C https://github.com/EDTTool/EDTT/issues/89 GATT/SR/GPA/BV-05-C GATT/SR/GPA/BV-06-C GATT/SR/GPA/BV-07-C diff --git a/tests/bsim/bluetooth/tester/src/bsim_btp.c b/tests/bsim/bluetooth/tester/src/bsim_btp.c index 2e24514b6606..19b196d1fe62 100644 --- a/tests/bsim/bluetooth/tester/src/bsim_btp.c +++ b/tests/bsim/bluetooth/tester/src/bsim_btp.c @@ -410,8 +410,6 @@ static bool is_valid_gatt_packet_len(const struct btp_hdr *hdr, struct net_buf_s } case BTP_GATT_WRITE_WITHOUT_RSP: return buf_simple->len == 0U; - case BTP_GATT_SIGNED_WRITE_WITHOUT_RSP: - return buf_simple->len == 0U; case BTP_GATT_WRITE: return buf_simple->len == sizeof(struct btp_gatt_write_rp); case BTP_GATT_WRITE_LONG: From 1e262422120411bf71f894d8fd4bea2d3a5e977d Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Tue, 11 Nov 2025 14:32:46 +0100 Subject: [PATCH 03/10] [nrf fromtree] tests: bluetooth: init: Remove duplicate prj_.conf files Remove duplicated prj.conf file. prj_6, prj_7, prj_14 are identicall. Since prj_6.conf is unchanged, keeping it. prj_8, prj_9, prj_15 are identicall. Since prj_15.conf is unchanged, keeping it. Signed-off-by: Pavel Vasilyev (cherry picked from commit 66679c1886513e8e1c41da3e47ece2195a783ed8) --- tests/bluetooth/init/prj_14.conf | 5 ----- tests/bluetooth/init/prj_7.conf | 5 ----- tests/bluetooth/init/prj_8.conf | 6 ------ tests/bluetooth/init/prj_9.conf | 6 ------ tests/bluetooth/init/testcase.yaml | 12 ------------ 5 files changed, 34 deletions(-) delete mode 100644 tests/bluetooth/init/prj_14.conf delete mode 100644 tests/bluetooth/init/prj_7.conf delete mode 100644 tests/bluetooth/init/prj_8.conf delete mode 100644 tests/bluetooth/init/prj_9.conf diff --git a/tests/bluetooth/init/prj_14.conf b/tests/bluetooth/init/prj_14.conf deleted file mode 100644 index 2a8566b9b467..000000000000 --- a/tests/bluetooth/init/prj_14.conf +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_CENTRAL=y -CONFIG_BT_SMP=y -CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/prj_7.conf b/tests/bluetooth/init/prj_7.conf deleted file mode 100644 index 2a8566b9b467..000000000000 --- a/tests/bluetooth/init/prj_7.conf +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_CENTRAL=y -CONFIG_BT_SMP=y -CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/prj_8.conf b/tests/bluetooth/init/prj_8.conf deleted file mode 100644 index 6dfcf4d7f59c..000000000000 --- a/tests/bluetooth/init/prj_8.conf +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_CENTRAL=y -CONFIG_BT_SMP=y -CONFIG_BT_SMP_SC_ONLY=y -CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/prj_9.conf b/tests/bluetooth/init/prj_9.conf deleted file mode 100644 index 6dfcf4d7f59c..000000000000 --- a/tests/bluetooth/init/prj_9.conf +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_CENTRAL=y -CONFIG_BT_SMP=y -CONFIG_BT_SMP_SC_ONLY=y -CONFIG_ZTEST=y diff --git a/tests/bluetooth/init/testcase.yaml b/tests/bluetooth/init/testcase.yaml index a5cc40cd39e7..bbefd93265c1 100644 --- a/tests/bluetooth/init/testcase.yaml +++ b/tests/bluetooth/init/testcase.yaml @@ -22,9 +22,6 @@ tests: bluetooth.init.test_13: extra_args: CONF_FILE=prj_13.conf platform_allow: qemu_cortex_m3 - bluetooth.init.test_14: - extra_args: CONF_FILE=prj_14.conf - platform_allow: qemu_cortex_m3 bluetooth.init.test_15: extra_args: CONF_FILE=prj_15.conf platform_allow: qemu_cortex_m3 @@ -64,15 +61,6 @@ tests: bluetooth.init.test_6: extra_args: CONF_FILE=prj_6.conf platform_allow: qemu_cortex_m3 - bluetooth.init.test_7: - extra_args: CONF_FILE=prj_7.conf - platform_allow: qemu_cortex_m3 - bluetooth.init.test_8: - extra_args: CONF_FILE=prj_8.conf - platform_allow: qemu_cortex_m3 - bluetooth.init.test_9: - extra_args: CONF_FILE=prj_9.conf - platform_allow: qemu_cortex_m3 bluetooth.init.test_ctlr: extra_args: - CONF_FILE=prj_ctlr.conf From 7b07f7904939a6aa14da0dca2bd7442b44b78e48 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 12 Nov 2025 23:20:14 +0100 Subject: [PATCH 04/10] [nrf fromtree] tests: bluetooth: qualification: Remove data signing related ICS This commit removes data signing related ICS. Removed ICS: - SM 6/1: Signing Algorithm Generation - SM 6/2: Signing Algorithm Resolving - GATT 3/13: Signed Write Without Response - GATT 9/10: Signed Write Command - GATT 7/3: LE Security mode 2 - GAP 25/2: LE Security mode 2 - GAP 35/2: LE Security mode 2 - GAP 25/5: Connection data signing procedure - GAP 35/5: Connection data signing procedure - GAP 25/6: Authenticate signed data procedure - GAP 35/6: Authenticate signed data procedure - GAP 27b/8: Connection Signature Resolving Key (CSRK) - GAP 37b/8: Connection Signature Resolving Key (CSRK) The following tests are not supported any longer: - GAP/SEC/CSIGN/BI-01-C - GAP/SEC/CSIGN/BI-02-C - GAP/SEC/CSIGN/BI-03-C - GAP/SEC/CSIGN/BI-04-C - GAP/SEC/CSIGN/BV-01-C - GAP/SEC/CSIGN/BV-02-C - GATT/CL/GAW/BV-02-C - SM/CEN/SIGN/BV-01-C Signed-off-by: Pavel Vasilyev (cherry picked from commit 116d4ddb89e909ea7c61d914e206a89dba2a3b22) --- .../ICS_Zephyr_Bluetooth_Host.bqw | 19 ++----- .../ICS_Zephyr_Bluetooth_Host.pts | 50 +------------------ 2 files changed, 4 insertions(+), 65 deletions(-) diff --git a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw index 399f6eb0ed6b..1f0b30081209 100644 --- a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw +++ b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.bqw @@ -1,8 +1,8 @@ - + - + @@ -54,7 +54,6 @@ GAP 31/10 GAP 32/1 GAP 32/2 - GAP 35/2 GAP 37/1 GAP 5/4 GAP 8a/1 @@ -84,7 +83,6 @@ GAP 21/5 GAP 23/2 GAP 25/1 - GAP 25/6 GAP 27/7 GAP 28/2 GAP 33/4 @@ -150,7 +148,6 @@ GAP 20A/19 GAP 30a/16 GAP 14a/10 - GAP 27b/8 GAP 27b/3 GAP 27b/6 GAP 25/11 @@ -217,7 +214,6 @@ GAP 33/5 GAP 34/3 GAP 35/3 - GAP 35/5 GAP 35/8 GAP 36/2 GAP 36/5 @@ -240,7 +236,6 @@ GAP 30a/6 GAP 27c/2 GAP 14a/6 - GAP 37b/8 GAP 25/14 GAP 14a/3 GAP 27c/3 @@ -252,14 +247,11 @@ GAP 20/5 GAP 20A/7 GAP 23/3 - GAP 25/2 - GAP 25/5 GAP 26/3 GAP 27/5 GAP 27a/1 GAP 27a/3 GAP 31/3 - GAP 35/6 GAP 37a/2 GAP 6/1 GAP 8a/11 @@ -369,7 +361,6 @@ GATT 9/7 GATT 10/8 GATT 3/30 - GATT 3/13 GATT 3/17 GATT 4/16 GATT 4/2 @@ -393,7 +384,6 @@ GATT 4/13 GATT 4/18 GATT 4/3 - GATT 7/3 GATT 4a/1 GATT 1/1 GATT 3/29 @@ -428,7 +418,6 @@ GATT 4/20 GATT 4/23 GATT 4/26 - GATT 9/10 GATT 3a/1 GATT 9/12 GATT 1a/1 @@ -448,12 +437,10 @@ SM 2/2 SM 5/1 SM 5/4 - SM 6/2 SM 1/1 SM 2/1 SM 4/1 SM 5/3 - SM 6/1 SM 7b/1 SM 4/3 SM 7b/3 @@ -3292,4 +3279,4 @@ - \ No newline at end of file + diff --git a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts index 6f31ef84404c..38a5a2dfa67c 100644 --- a/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts +++ b/tests/bluetooth/qualification/ICS_Zephyr_Bluetooth_Host.pts @@ -1,6 +1,6 @@  - 347313 + 376799 Zephyr Host @@ -317,10 +317,6 @@ 14a
14 - - 37b
- 8 -
30a
16 @@ -381,10 +377,6 @@ 14a
10
- - 27b
- 8 -
27b
3 @@ -749,10 +741,6 @@ 25
10
- - 25
- 2 -
25
3 @@ -761,14 +749,6 @@ 25
4
- - 25
- 5 -
- - 25
- 6 -
25
7 @@ -969,14 +949,6 @@ 35
4
- - 35
- 5 -
- - 35
- 6 -
35
7 @@ -1311,10 +1283,6 @@ 2
3a
- - 9
- 10 -
10
6 @@ -1491,10 +1459,6 @@ 3
12
- - 3
- 13 -
3
14 @@ -1679,10 +1643,6 @@ 7
2
- - 7
- 3 -
7
4 @@ -1782,14 +1742,6 @@ 5
4
- - 6
- 1 -
- - 6
- 2 -
ATT From 1c5ba1a0091799020d7a7bf438bee1e6ab1e288e Mon Sep 17 00:00:00 2001 From: Xiang Liu Date: Tue, 14 Oct 2025 10:49:53 +0800 Subject: [PATCH 05/10] [nrf fromtree] bluetooth: remove blocking operation in bt_conn_get_info bt_conn_get_info API is used to retrieve connection-related information. However, bt_conn_get_info sends the HCI command BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE to retrieve current key_size, causing excessive blocking time. Signed-off-by: Xiang Liu (cherry picked from commit 8e9fa6a2734314a433e6a0f8580cc90182ae0ab0) --- subsys/bluetooth/host/classic/br.c | 4 ++++ subsys/bluetooth/host/conn.c | 32 ++++-------------------------- subsys/bluetooth/host/hci_core.c | 13 +++++++++--- subsys/bluetooth/host/keys.h | 1 + 4 files changed, 19 insertions(+), 31 deletions(-) diff --git a/subsys/bluetooth/host/classic/br.c b/subsys/bluetooth/host/classic/br.c index 23a43a01959b..4e9902747381 100644 --- a/subsys/bluetooth/host/classic/br.c +++ b/subsys/bluetooth/host/classic/br.c @@ -143,6 +143,10 @@ static bool br_sufficient_key_size(struct bt_conn *conn) key_size = rp->key_size; net_buf_unref(rsp); + if (conn->br.link_key) { + conn->br.link_key->enc_key_size = key_size; + } + LOG_DBG("Encryption key size is %u", key_size); if (conn->sec_level == BT_SECURITY_L4) { diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index e706fd3fb934..2b2ce061bd92 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2507,35 +2507,11 @@ uint8_t bt_conn_enc_key_size(const struct bt_conn *conn) return 0; } - if (IS_ENABLED(CONFIG_BT_CLASSIC) && - conn->type == BT_CONN_TYPE_BR) { - struct bt_hci_cp_read_encryption_key_size *cp; - struct bt_hci_rp_read_encryption_key_size *rp; - struct net_buf *buf; - struct net_buf *rsp; - uint8_t key_size; - - buf = bt_hci_cmd_alloc(K_FOREVER); - if (!buf) { - return 0; - } - - cp = net_buf_add(buf, sizeof(*cp)); - cp->handle = sys_cpu_to_le16(conn->handle); - - if (bt_hci_cmd_send_sync(BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE, - buf, &rsp)) { - return 0; - } - - rp = (void *)rsp->data; - - key_size = rp->status ? 0 : rp->key_size; - - net_buf_unref(rsp); - - return key_size; +#if defined(CONFIG_BT_CLASSIC) + if (conn->type == BT_CONN_TYPE_BR) { + return conn->br.link_key ? conn->br.link_key->enc_key_size : 0; } +#endif /* CONFIG_BT_CLASSIC */ if (IS_ENABLED(CONFIG_BT_SMP)) { return conn->le.keys ? conn->le.keys->enc_size : 0; diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index d2a8d6d1202b..ee16fea31064 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1077,9 +1077,16 @@ static void hci_disconn_complete(struct net_buf *buf) * If only for one connection session bond was set, clear keys * database row for this connection. */ - if (conn->type == BT_CONN_TYPE_BR && conn->br.link_key != NULL && - atomic_test_and_clear_bit(conn->flags, BT_CONN_BR_NOBOND)) { - bt_keys_link_key_clear(conn->br.link_key); + if (conn->type == BT_CONN_TYPE_BR && conn->br.link_key != NULL) { + /* + * If the connection link is paired but not bond, remove + * the link key upon disconnection. + */ + if (atomic_test_and_clear_bit(conn->flags, BT_CONN_BR_NOBOND)) { + bt_keys_link_key_clear(conn->br.link_key); + } + + conn->br.link_key->enc_key_size = 0; } #endif bt_conn_unref(conn); diff --git a/subsys/bluetooth/host/keys.h b/subsys/bluetooth/host/keys.h index 185fd610e779..90c0c92e9de0 100644 --- a/subsys/bluetooth/host/keys.h +++ b/subsys/bluetooth/host/keys.h @@ -223,6 +223,7 @@ enum { struct bt_keys_link_key { bt_addr_t addr; + uint8_t enc_key_size; uint8_t storage_start[0] __aligned(sizeof(void *)); uint8_t flags; uint8_t val[16]; From a3906594ba6b025bae7df5145e1525e1de6217f7 Mon Sep 17 00:00:00 2001 From: Kai Cheng Date: Wed, 22 Oct 2025 21:26:25 +0800 Subject: [PATCH 06/10] [nrf fromtree] Bluetooth: Conn: add connection type helper functions Introduce dedicated helper functions for connection type checking: - bt_conn_is_br() for BR/EDR connections - bt_conn_is_le() for LE connections - bt_conn_is_iso() for ISO connections - bt_conn_is_sco() for SCO connections Replace direct conn->type comparisons with these new helper functions throughout the connection management code. This improves code readability, maintainability, and provides proper configuration checks for each connection type. Signed-off-by: Kai Cheng (cherry picked from commit 038523c63b0c2f615b180167fc171844b3e21b0b) --- subsys/bluetooth/host/conn.c | 144 ++++++++++++-------------- subsys/bluetooth/host/conn_internal.h | 35 ++++++- 2 files changed, 97 insertions(+), 82 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 2b2ce061bd92..d310ff1de5fe 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -217,7 +217,7 @@ int bt_conn_iso_init(void) struct k_sem *bt_conn_get_pkts(struct bt_conn *conn) { #if defined(CONFIG_BT_CLASSIC) - if (conn->type == BT_CONN_TYPE_BR || !bt_dev.le.acl_mtu) { + if (bt_conn_is_br(conn) || !bt_dev.le.acl_mtu) { return &bt_dev.br.pkts; } #endif /* CONFIG_BT_CLASSIC */ @@ -226,7 +226,7 @@ struct k_sem *bt_conn_get_pkts(struct bt_conn *conn) /* Use ISO pkts semaphore if LE Read Buffer Size command returned * dedicated ISO buffers. */ - if (conn->type == BT_CONN_TYPE_ISO) { + if (bt_conn_is_iso(conn)) { if (bt_dev.le.iso_mtu && bt_dev.le.iso_limit != 0) { return &bt_dev.le.iso_pkts; } @@ -470,7 +470,7 @@ static void bt_acl_recv(struct bt_conn *conn, struct net_buf *buf, return; } - if ((conn->type != BT_CONN_TYPE_BR) && (conn->rx->len > acl_total_len)) { + if (!bt_conn_is_br(conn) && (conn->rx->len > acl_total_len)) { LOG_ERR("ACL len mismatch (%u > %u)", conn->rx->len, acl_total_len); bt_conn_reset_rx_state(conn); return; @@ -481,7 +481,7 @@ static void bt_acl_recv(struct bt_conn *conn, struct net_buf *buf, conn->rx = NULL; LOG_DBG("Successfully parsed %u byte L2CAP packet", buf->len); - if (IS_ENABLED(CONFIG_BT_CLASSIC) && (conn->type == BT_CONN_TYPE_BR)) { + if (bt_conn_is_br(conn)) { bt_br_acl_recv(conn, buf, true); } else { bt_l2cap_recv(conn, buf, true); @@ -500,7 +500,7 @@ void bt_conn_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags) LOG_DBG("handle %u len %u flags %02x", conn->handle, buf->len, flags); - if (IS_ENABLED(CONFIG_BT_ISO_RX) && conn->type == BT_CONN_TYPE_ISO) { + if (IS_ENABLED(CONFIG_BT_ISO_RX) && bt_conn_is_iso(conn)) { bt_iso_recv(conn, buf, flags); return; } else if (IS_ENABLED(CONFIG_BT_CONN)) { @@ -618,13 +618,12 @@ static int send_iso(struct bt_conn *conn, struct net_buf *buf, uint8_t flags) static inline uint16_t conn_mtu(struct bt_conn *conn) { #if defined(CONFIG_BT_CLASSIC) - if (conn->type == BT_CONN_TYPE_BR || - (conn->type != BT_CONN_TYPE_ISO && !bt_dev.le.acl_mtu)) { + if (bt_conn_is_br(conn) || (!bt_conn_is_iso(conn) && !bt_dev.le.acl_mtu)) { return bt_dev.br.mtu; } #endif /* CONFIG_BT_CLASSIC */ #if defined(CONFIG_BT_ISO) - if (conn->type == BT_CONN_TYPE_ISO) { + if (bt_conn_is_iso(conn)) { return bt_dev.le.iso_mtu; } #endif /* CONFIG_BT_ISO */ @@ -635,26 +634,14 @@ static inline uint16_t conn_mtu(struct bt_conn *conn) #endif /* CONFIG_BT_CONN */ } -static bool is_classic_conn(struct bt_conn *conn) -{ - return (IS_ENABLED(CONFIG_BT_CLASSIC) && - conn->type == BT_CONN_TYPE_BR); -} - static bool is_iso_tx_conn(struct bt_conn *conn) { - return IS_ENABLED(CONFIG_BT_ISO_TX) && - conn->type == BT_CONN_TYPE_ISO; -} - -static bool is_le_conn(struct bt_conn *conn) -{ - return IS_ENABLED(CONFIG_BT_CONN) && conn->type == BT_CONN_TYPE_LE; + return IS_ENABLED(CONFIG_BT_ISO_TX) && bt_conn_is_iso(conn); } static bool is_acl_conn(struct bt_conn *conn) { - return is_le_conn(conn) || is_classic_conn(conn); + return bt_conn_is_le(conn) || bt_conn_is_br(conn); } static int send_buf(struct bt_conn *conn, struct net_buf *buf, @@ -1192,13 +1179,12 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) * bt_conn_add_le() and keep it until reaching DISCONNECTED * again. */ - if (conn->type != BT_CONN_TYPE_ISO) { + if (!bt_conn_is_iso(conn)) { bt_conn_ref(conn); } break; case BT_CONN_INITIATING: - if (IS_ENABLED(CONFIG_BT_CENTRAL) && - conn->type == BT_CONN_TYPE_LE) { + if (IS_ENABLED(CONFIG_BT_CENTRAL) && bt_conn_is_le(conn)) { k_work_cancel_delayable(&conn->deferred_work); } break; @@ -1209,7 +1195,7 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) /* Actions needed for entering the new state */ switch (conn->state) { case BT_CONN_CONNECTED: - if (conn->type == BT_CONN_TYPE_SCO) { + if (bt_conn_is_sco(conn)) { if (IS_ENABLED(CONFIG_BT_CLASSIC)) { bt_sco_connected(conn); } @@ -1217,8 +1203,7 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) } k_poll_signal_raise(&conn_change, 0); - if (IS_ENABLED(CONFIG_BT_ISO) && - conn->type == BT_CONN_TYPE_ISO) { + if (bt_conn_is_iso(conn)) { bt_iso_connected(conn); break; } @@ -1230,7 +1215,7 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) conn->role == BT_CONN_ROLE_PERIPHERAL) { #if defined(CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS) - if (conn->type == BT_CONN_TYPE_LE) { + if (bt_conn_is_le(conn)) { conn->le.conn_param_retry_countdown = CONFIG_BT_CONN_PARAM_RETRY_COUNT; } @@ -1244,7 +1229,7 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) break; case BT_CONN_DISCONNECTED: #if defined(CONFIG_BT_CONN) - if (conn->type == BT_CONN_TYPE_SCO) { + if (bt_conn_is_sco(conn)) { if (IS_ENABLED(CONFIG_BT_CLASSIC)) { bt_sco_disconnected(conn); } @@ -1341,15 +1326,14 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) case BT_CONN_ADV_DIR_CONNECTABLE: break; case BT_CONN_INITIATING: - if (conn->type == BT_CONN_TYPE_SCO) { + if (bt_conn_is_sco(conn)) { break; } /* * Timer is needed only for LE. For other link types controller * will handle connection timeout. */ - if (IS_ENABLED(CONFIG_BT_CENTRAL) && - conn->type == BT_CONN_TYPE_LE && + if (IS_ENABLED(CONFIG_BT_CENTRAL) && bt_conn_is_le(conn) && bt_dev.create_param.timeout != 0) { k_work_schedule(&conn->deferred_work, K_MSEC(10 * bt_dev.create_param.timeout)); @@ -1884,21 +1868,21 @@ int bt_conn_disconnect(struct bt_conn *conn, uint8_t reason) } return 0; case BT_CONN_INITIATING: - if (conn->type == BT_CONN_TYPE_LE) { + if (bt_conn_is_le(conn)) { if (IS_ENABLED(CONFIG_BT_CENTRAL)) { k_work_cancel_delayable(&conn->deferred_work); return bt_le_create_conn_cancel(); } } #if defined(CONFIG_BT_ISO) - else if (conn->type == BT_CONN_TYPE_ISO) { + else if (bt_conn_is_iso(conn)) { return conn_disconnect(conn, reason); } #endif /* CONFIG_BT_ISO */ #if defined(CONFIG_BT_CLASSIC) - else if (conn->type == BT_CONN_TYPE_BR) { + else if (bt_conn_is_br(conn)) { return bt_hci_connect_br_cancel(conn); - } else if (conn->type == BT_CONN_TYPE_SCO) { + } else if (bt_conn_is_sco(conn)) { /* There is no HCI cmd to cancel SCO connecting from spec */ return -EPROTONOSUPPORT; } @@ -2179,7 +2163,7 @@ static void deferred_work(struct k_work *work) #if defined(CONFIG_BT_ISO_UNICAST) struct bt_conn *iso; - if (conn->type == BT_CONN_TYPE_ISO) { + if (bt_conn_is_iso(conn)) { /* bt_iso_disconnected is responsible for unref'ing the * connection pointer, as it is conditional on whether * the connection is a central or peripheral. @@ -2239,7 +2223,7 @@ static void deferred_work(struct k_work *work) return; } - if (conn->type != BT_CONN_TYPE_LE) { + if (!bt_conn_is_le(conn)) { return; } @@ -2323,7 +2307,7 @@ struct bt_conn *bt_conn_lookup_addr_sco(const bt_addr_t *peer) continue; } - if (conn->type != BT_CONN_TYPE_SCO) { + if (!bt_conn_is_sco(conn)) { bt_conn_unref(conn); continue; } @@ -2355,7 +2339,7 @@ struct bt_conn *bt_conn_lookup_addr_br(const bt_addr_t *peer) continue; } - if (conn->type != BT_CONN_TYPE_BR) { + if (!bt_conn_is_br(conn)) { bt_conn_unref(conn); continue; } @@ -2498,7 +2482,7 @@ int bt_conn_le_start_encryption(struct bt_conn *conn, uint8_t rand[8], #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_CLASSIC) uint8_t bt_conn_enc_key_size(const struct bt_conn *conn) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return 0; } @@ -2508,7 +2492,7 @@ uint8_t bt_conn_enc_key_size(const struct bt_conn *conn) } #if defined(CONFIG_BT_CLASSIC) - if (conn->type == BT_CONN_TYPE_BR) { + if (bt_conn_is_br(conn)) { return conn->br.link_key ? conn->br.link_key->enc_key_size : 0; } #endif /* CONFIG_BT_CLASSIC */ @@ -2523,7 +2507,7 @@ uint8_t bt_conn_enc_key_size(const struct bt_conn *conn) static void reset_pairing(struct bt_conn *conn) { #if defined(CONFIG_BT_CLASSIC) - if (conn->type == BT_CONN_TYPE_BR) { + if (bt_conn_is_br(conn)) { atomic_clear_bit(conn->flags, BT_CONN_BR_PAIRING); atomic_clear_bit(conn->flags, BT_CONN_BR_PAIRED); atomic_clear_bit(conn->flags, BT_CONN_BR_PAIRING_INITIATOR); @@ -2559,12 +2543,12 @@ void bt_conn_security_changed(struct bt_conn *conn, uint8_t hci_err, #if defined(CONFIG_BT_KEYS_OVERWRITE_OLDEST) if (!err && conn->sec_level >= BT_SECURITY_L2) { - if (conn->type == BT_CONN_TYPE_LE) { + if (bt_conn_is_le(conn)) { bt_keys_update_usage(conn->id, bt_conn_get_dst(conn)); } #if defined(CONFIG_BT_CLASSIC) - if (conn->type == BT_CONN_TYPE_BR) { + if (bt_conn_is_br(conn)) { bt_keys_link_key_update_usage(&conn->br.dst); } #endif /* CONFIG_BT_CLASSIC */ @@ -2575,7 +2559,7 @@ void bt_conn_security_changed(struct bt_conn *conn, uint8_t hci_err, static int start_security(struct bt_conn *conn) { - if (IS_ENABLED(CONFIG_BT_CLASSIC) && conn->type == BT_CONN_TYPE_BR) { + if (bt_conn_is_br(conn)) { return bt_ssp_start_security(conn); } @@ -2591,7 +2575,7 @@ int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec) bool force_pair; int err; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -2631,7 +2615,7 @@ int bt_conn_set_security(struct bt_conn *conn, bt_security_t sec) bt_security_t bt_conn_get_security(const struct bt_conn *conn) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return BT_SECURITY_L0; } @@ -2749,7 +2733,7 @@ struct bt_conn *bt_conn_lookup_addr_le(uint8_t id, const bt_addr_le_t *peer) continue; } - if (conn->type != BT_CONN_TYPE_LE) { + if (!bt_conn_is_le(conn)) { bt_conn_unref(conn); continue; } @@ -2777,7 +2761,7 @@ struct bt_conn *bt_conn_lookup_state_le(uint8_t id, const bt_addr_le_t *peer, continue; } - if (conn->type != BT_CONN_TYPE_LE) { + if (!bt_conn_is_le(conn)) { bt_conn_unref(conn); continue; } @@ -2800,7 +2784,7 @@ struct bt_conn *bt_conn_lookup_state_le(uint8_t id, const bt_addr_le_t *peer, const bt_addr_le_t *bt_conn_get_dst(const struct bt_conn *conn) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return NULL; } @@ -2915,7 +2899,7 @@ bool bt_conn_is_type(const struct bt_conn *conn, enum bt_conn_type type) int bt_conn_get_remote_info(const struct bt_conn *conn, struct bt_conn_remote_info *remote_info) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3010,7 +2994,7 @@ int bt_conn_le_enhanced_get_tx_power_level(struct bt_conn *conn, struct bt_hci_cp_le_read_tx_power_level *cp; struct net_buf *buf; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3048,7 +3032,7 @@ int bt_conn_le_get_remote_tx_power_level(struct bt_conn *conn, struct bt_hci_cp_le_read_tx_power_level *cp; struct net_buf *buf; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3076,7 +3060,7 @@ int bt_conn_le_set_tx_power_report_enable(struct bt_conn *conn, struct bt_hci_cp_le_set_tx_power_report_enable *cp; struct net_buf *buf; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3102,7 +3086,7 @@ int bt_conn_le_get_tx_power_level(struct bt_conn *conn, { int err; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3150,7 +3134,7 @@ int bt_conn_le_set_path_loss_mon_param(struct bt_conn *conn, struct bt_hci_cp_le_set_path_loss_reporting_parameters *cp; struct net_buf *buf; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3176,7 +3160,7 @@ int bt_conn_le_set_path_loss_mon_enable(struct bt_conn *conn, bool reporting_ena struct bt_hci_cp_le_set_path_loss_reporting_enable *cp; struct net_buf *buf; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3275,7 +3259,7 @@ int bt_conn_le_subrate_request(struct bt_conn *conn, struct bt_hci_cp_le_subrate_request *cp; struct net_buf *buf; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3324,7 +3308,7 @@ int bt_conn_le_read_all_remote_features(struct bt_conn *conn, uint8_t pages_requ struct bt_hci_cp_le_read_all_remote_features *cp; struct net_buf *buf; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3393,7 +3377,7 @@ int bt_conn_le_frame_space_update(struct bt_conn *conn, struct bt_hci_cp_le_frame_space_update *cp; struct net_buf *buf; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3535,7 +3519,7 @@ void bt_conn_notify_cs_subevent_result(struct bt_conn *conn, int bt_conn_le_param_update(struct bt_conn *conn, const struct bt_le_conn_param *param) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3569,7 +3553,7 @@ int bt_conn_le_param_update(struct bt_conn *conn, int bt_conn_le_data_len_update(struct bt_conn *conn, const struct bt_conn_le_data_len_param *param) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -3589,7 +3573,7 @@ int bt_conn_le_phy_update(struct bt_conn *conn, { uint8_t phy_opts, all_phys; - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -4023,7 +4007,7 @@ int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb) #if defined(CONFIG_BT_SMP) int bt_conn_auth_cb_overlay(struct bt_conn *conn, const struct bt_conn_auth_cb *cb) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -4037,7 +4021,7 @@ int bt_conn_auth_cb_overlay(struct bt_conn *conn, const struct bt_conn_auth_cb * return -EINVAL; } - if (conn->type == BT_CONN_TYPE_LE) { + if (bt_conn_is_le(conn)) { return bt_smp_auth_cb_overlay(conn, cb); } @@ -4075,16 +4059,16 @@ int bt_conn_auth_info_cb_unregister(struct bt_conn_auth_info_cb *cb) int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } - if (IS_ENABLED(CONFIG_BT_SMP) && conn->type == BT_CONN_TYPE_LE) { + if (IS_ENABLED(CONFIG_BT_SMP) && bt_conn_is_le(conn)) { return bt_smp_auth_passkey_entry(conn, passkey); } - if (IS_ENABLED(CONFIG_BT_CLASSIC) && conn->type == BT_CONN_TYPE_BR) { + if (bt_conn_is_br(conn)) { if (!bt_auth) { return -EINVAL; } @@ -4099,7 +4083,7 @@ int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey) int bt_conn_auth_keypress_notify(struct bt_conn *conn, enum bt_conn_auth_keypress type) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { + if (!bt_conn_is_le(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } @@ -4115,16 +4099,16 @@ int bt_conn_auth_keypress_notify(struct bt_conn *conn, int bt_conn_auth_passkey_confirm(struct bt_conn *conn) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } - if (IS_ENABLED(CONFIG_BT_SMP) && conn->type == BT_CONN_TYPE_LE) { + if (IS_ENABLED(CONFIG_BT_SMP) && bt_conn_is_le(conn)) { return bt_smp_auth_passkey_confirm(conn); } - if (IS_ENABLED(CONFIG_BT_CLASSIC) && conn->type == BT_CONN_TYPE_BR) { + if (bt_conn_is_br(conn)) { if (!bt_auth) { return -EINVAL; } @@ -4137,16 +4121,16 @@ int bt_conn_auth_passkey_confirm(struct bt_conn *conn) int bt_conn_auth_cancel(struct bt_conn *conn) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } - if (IS_ENABLED(CONFIG_BT_SMP) && conn->type == BT_CONN_TYPE_LE) { + if (IS_ENABLED(CONFIG_BT_SMP) && bt_conn_is_le(conn)) { return bt_smp_auth_cancel(conn); } - if (IS_ENABLED(CONFIG_BT_CLASSIC) && conn->type == BT_CONN_TYPE_BR) { + if (bt_conn_is_br(conn)) { if (!bt_auth) { return -EINVAL; } @@ -4159,16 +4143,16 @@ int bt_conn_auth_cancel(struct bt_conn *conn) int bt_conn_auth_pairing_confirm(struct bt_conn *conn) { - if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR)) { + if (!bt_conn_is_le(conn) && !bt_conn_is_br(conn)) { LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); return -EINVAL; } - if (IS_ENABLED(CONFIG_BT_SMP) && conn->type == BT_CONN_TYPE_LE) { + if (IS_ENABLED(CONFIG_BT_SMP) && bt_conn_is_le(conn)) { return bt_smp_auth_pairing_confirm(conn); } - if (IS_ENABLED(CONFIG_BT_CLASSIC) && conn->type == BT_CONN_TYPE_BR) { + if (bt_conn_is_br(conn)) { if (!bt_auth) { return -EINVAL; } diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index c64ad277b4f8..f1e4a289a135 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -363,6 +363,38 @@ static inline void *closure_data(void *storage) return ((struct closure *)storage)->data; } +#if defined(CONFIG_BT_CLASSIC) +static inline bool bt_conn_is_br(const struct bt_conn *conn) +{ + return conn->type == BT_CONN_TYPE_BR; +} +#else +#define bt_conn_is_br(conn) (false) +#endif + +static inline bool bt_conn_is_le(const struct bt_conn *conn) +{ + return conn->type == BT_CONN_TYPE_LE; +} + +#if defined(CONFIG_BT_ISO) +static inline bool bt_conn_is_iso(const struct bt_conn *conn) +{ + return conn->type == BT_CONN_TYPE_ISO; +} +#else +#define bt_conn_is_iso(conn) (false) +#endif + +#if defined(CONFIG_BT_CLASSIC) +static inline bool bt_conn_is_sco(const struct bt_conn *conn) +{ + return conn->type == BT_CONN_TYPE_SCO; +} +#else +#define bt_conn_is_sco(conn) (false) +#endif + void bt_conn_tx_notify(struct bt_conn *conn, bool wait_for_completion); void bt_conn_reset_rx_state(struct bt_conn *conn); @@ -442,8 +474,7 @@ static inline bool bt_conn_is_handle_valid(struct bt_conn *conn) return true; case BT_CONN_INITIATING: /* ISO connection handle assigned at connect state */ - if (IS_ENABLED(CONFIG_BT_ISO) && - conn->type == BT_CONN_TYPE_ISO) { + if (bt_conn_is_iso(conn)) { return true; } __fallthrough; From 09ef00cbac1f312fee3942c61e211365201d58b0 Mon Sep 17 00:00:00 2001 From: Timothy Keys Date: Mon, 13 Oct 2025 16:01:31 +0100 Subject: [PATCH 07/10] [nrf fromtree] bluetooth: host: Add Shorter Connection Intervals support This commit adds support for the Shorter Connection Intervals feature to the Bluetooth host. Signed-off-by: Timothy Keys (cherry picked from commit e2cd247ec4852328b94e1c8c917ca9d33e0cf72d) --- include/zephyr/bluetooth/conn.h | 269 +++++++++++++++++++++++++- include/zephyr/bluetooth/hci_types.h | 80 ++++++++ subsys/bluetooth/Kconfig | 11 +- subsys/bluetooth/controller/Kconfig | 14 ++ subsys/bluetooth/host/conn.c | 199 ++++++++++++++++++- subsys/bluetooth/host/conn_internal.h | 3 + subsys/bluetooth/host/hci_core.c | 85 +++++++- 7 files changed, 657 insertions(+), 4 deletions(-) diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 881d0894ee11..7a2d5d9c1bad 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -252,6 +252,169 @@ struct bt_conn_le_subrate_changed { uint16_t supervision_timeout; }; +/** @brief Maximum Connection Interval Groups possible + * + * The practical maximum is 41 groups based on HCI event size constraints: + * (HCI event max size - cmd_complete overhead - response fields) / sizeof(group) + * (255 - 4 - 3) / 6 = 41 groups max + */ +#define BT_CONN_LE_MAX_CONN_INTERVAL_GROUPS 41 + +/** @brief Minimum supported connection interval group + * + * Each group represents an arithmetic sequence of supported connection intervals: + * min, min + stride, min + 2 * stride, ..., min + n * stride (where min + n * stride <= max) + * + * Example: min = 10 (1250 us), max = 60 (7500 us), stride = 5 (625 us) + * -> Supported: 1250 us, 1875 us, 2500 us, ..., 6875 us, 7500 us + */ +struct bt_conn_le_min_conn_interval_group { + /** @brief Lower bound of group interval range + * + * Unit: 125 microseconds + * + * Range: @ref BT_HCI_LE_SCI_INTERVAL_MIN_125US - @ref BT_HCI_LE_SCI_INTERVAL_MAX_125US + */ + uint16_t min_125us; + /** @brief Upper bound of group interval range + * + * Unit: 125 microseconds + * + * Range: @ref BT_HCI_LE_SCI_INTERVAL_MIN_125US - @ref BT_HCI_LE_SCI_INTERVAL_MAX_125US + */ + uint16_t max_125us; + /** @brief Increment between consecutive supported intervals + * + * Unit: 125 microseconds + * + * Range: @ref BT_HCI_LE_SCI_STRIDE_MIN_125US - @ref BT_HCI_LE_SCI_INTERVAL_MAX_125US + */ + uint16_t stride_125us; +}; + +/** Minimum supported connection interval information */ +struct bt_conn_le_min_conn_interval_info { + /** @brief Minimum supported connection interval + * + * Unit: microseconds + * + * Range: @ref BT_HCI_LE_MIN_SUPP_CONN_INT_MIN_US - @ref BT_HCI_LE_MIN_SUPP_CONN_INT_MAX_US + */ + uint16_t min_supported_conn_interval_us; + /** @brief Number of interval groups. + * + * Range: 0 - @ref BT_CONN_LE_MAX_CONN_INTERVAL_GROUPS + * + * If zero, the controller only supports Rounded ConnInterval Values (RCV). + */ + uint8_t num_groups; + /** @brief Array of supported connection interval groups. + * + * Multiple groups allow representing non-contiguous or differently-strided ranges. + */ + struct bt_conn_le_min_conn_interval_group groups[BT_CONN_LE_MAX_CONN_INTERVAL_GROUPS]; +}; + +/** Connection rate parameters for LE connections */ +struct bt_conn_le_conn_rate_param { + /** @brief Minimum connection interval + * + * Unit: 125 microseconds + * + * Range: @ref BT_HCI_LE_SCI_INTERVAL_MIN_125US - @ref BT_HCI_LE_SCI_INTERVAL_MAX_125US + */ + uint16_t interval_min_125us; + /** @brief Maximum connection interval + * + * Unit: 125 microseconds + * + * Range: @ref BT_HCI_LE_SCI_INTERVAL_MIN_125US - @ref BT_HCI_LE_SCI_INTERVAL_MAX_125US + */ + uint16_t interval_max_125us; + /** @brief Minimum subrate factor + * + * Range: @ref BT_HCI_LE_SUBRATE_FACTOR_MIN - @ref BT_HCI_LE_SUBRATE_FACTOR_MAX + */ + uint16_t subrate_min; + /** @brief Maximum subrate factor + * + * Range: @ref BT_HCI_LE_SUBRATE_FACTOR_MIN - @ref BT_HCI_LE_SUBRATE_FACTOR_MAX + */ + uint16_t subrate_max; + /** @brief Maximum Peripheral latency + * + * Unit: subrated connection intervals @ref bt_conn_le_conn_rate_changed.subrate_factor + * + * Range: @ref BT_HCI_LE_PERIPHERAL_LATENCY_MIN - @ref BT_HCI_LE_PERIPHERAL_LATENCY_MAX + */ + uint16_t max_latency; + /** @brief Minimum number of underlying connection events to remain active + * after a packet containing a Link Layer PDU with a non-zero Length + * field is sent or received. + * + * Range: @ref BT_HCI_LE_CONTINUATION_NUM_MIN - @ref BT_HCI_LE_CONTINUATION_NUM_MAX + */ + uint16_t continuation_number; + /** @brief Connection Supervision timeout + * + * Unit: 10 milliseconds + * + * Range: @ref BT_HCI_LE_SUPERVISON_TIMEOUT_MIN - @ref BT_HCI_LE_SUPERVISON_TIMEOUT_MAX + */ + uint16_t supervision_timeout_10ms; + /** @brief Minimum length of connection event + * + * Unit: 125 microseconds + * + * Range: @ref BT_HCI_LE_SCI_CE_LEN_MIN_125US - @ref BT_HCI_LE_SCI_CE_LEN_MAX_125US + */ + uint16_t min_ce_len_125us; + /** @brief Maximum length of connection event + * + * Unit: 125 microseconds + * + * Range: @ref BT_HCI_LE_SCI_CE_LEN_MIN_125US - @ref BT_HCI_LE_SCI_CE_LEN_MAX_125US + */ + uint16_t max_ce_len_125us; +}; + +/** Updated connection rate parameters */ +struct bt_conn_le_conn_rate_changed { + /** Connection interval + * + * Unit: microseconds + * + * Range: @ref BT_HCI_LE_SCI_INTERVAL_MIN_US - @ref BT_HCI_LE_SCI_INTERVAL_MAX_US + */ + uint32_t interval_us; + /** Connection subrate factor + * + * Range: @ref BT_HCI_LE_SUBRATE_FACTOR_MIN - @ref BT_HCI_LE_SUBRATE_FACTOR_MAX + */ + uint16_t subrate_factor; + /** Peripheral latency + * + * Unit: subrated connection intervals @ref bt_conn_le_conn_rate_changed.subrate_factor + * + * Range: @ref BT_HCI_LE_PERIPHERAL_LATENCY_MIN - @ref BT_HCI_LE_PERIPHERAL_LATENCY_MAX + */ + uint16_t peripheral_latency; + /** Number of underlying connection events to remain active after + * a packet containing a Link Layer PDU with a non-zero Length + * field is sent or received. + * + * Range: @ref BT_HCI_LE_CONTINUATION_NUM_MIN - @ref BT_HCI_LE_CONTINUATION_NUM_MAX + */ + uint16_t continuation_number; + /** Connection Supervision timeout + * + * Unit: 10 milliseconds + * + * Range: @ref BT_HCI_LE_SUPERVISON_TIMEOUT_MIN - @ref BT_HCI_LE_SUPERVISON_TIMEOUT_MAX + */ + uint16_t supervision_timeout_10ms; +}; + /** Read all remote features complete callback params */ struct bt_conn_le_read_all_remote_feat_complete { /** @brief HCI Status from LE Read All Remote Features Complete event. @@ -890,7 +1053,12 @@ struct bt_conn_le_info { const bt_addr_le_t *local; /** Remote device address used during connection setup. */ const bt_addr_le_t *remote; - uint16_t interval; /**< Connection interval */ + /** Connection interval in microseconds */ + uint32_t interval_us; +#if !defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) || defined(__DOXYGEN__) + /** Connection interval in units of 1.25 ms */ + uint16_t interval; +#endif /* !CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ uint16_t latency; /**< Connection peripheral latency */ uint16_t timeout; /**< Connection supervision timeout */ @@ -924,6 +1092,12 @@ struct bt_conn_le_info { */ #define BT_CONN_INTERVAL_TO_US(interval) ((interval) * 1250U) +/** @brief Convert shorter connection interval to microseconds + * + * Multiply by 125 to get microseconds. + */ +#define BT_CONN_SCI_INTERVAL_TO_US(interval) ((interval) * BT_HCI_LE_SCI_INTERVAL_UNIT_US) + /** BR/EDR Connection Info Structure */ struct bt_conn_br_info { const bt_addr_t *dst; /**< Destination (Remote) BR/EDR address */ @@ -1329,6 +1503,74 @@ int bt_conn_le_subrate_set_defaults(const struct bt_conn_le_subrate_param *param int bt_conn_le_subrate_request(struct bt_conn *conn, const struct bt_conn_le_subrate_param *params); +/** @brief Read Minimum Supported Connection Interval Groups. + * + * Read the minimum supported connection interval and supported interval + * groups from the local controller. This information describes what the + * local controller supports. + * + * @sa bt_conn_le_read_min_conn_interval if only + * @ref bt_conn_le_min_conn_interval_info.min_supported_conn_interval_us + * is needed. + * + * @kconfig_dep{CONFIG_BT_SHORTER_CONNECTION_INTERVALS} + * + * @param info Pointer to structure to receive the minimum connection interval + * information. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_le_read_min_conn_interval_groups(struct bt_conn_le_min_conn_interval_info *info); + +/** @brief Read Minimum Supported Connection Interval. + * + * Read the minimum supported connection interval from the local controller. + * + * @sa bt_conn_le_read_min_conn_interval_groups if groups are needed. + * + * @kconfig_dep{CONFIG_BT_SHORTER_CONNECTION_INTERVALS} + * + * @param min_interval_us Pointer to variable to receive the minimum connection interval + * in microseconds. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_le_read_min_conn_interval(uint16_t *min_interval_us); + +/** @brief Set Default Connection Rate Parameters. + * + * Set default connection rate parameters to be used for future connections. + * This command does not affect any existing connection. + * Parameters set for specific connection will always have precedence. + * + * @kconfig_dep{CONFIG_BT_SHORTER_CONNECTION_INTERVALS} + * + * @param params Connection rate parameters. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_le_conn_rate_set_defaults(const struct bt_conn_le_conn_rate_param *params); + +/** @brief Request New Connection Rate Parameters. + * + * Request a change to the connection parameters of a connection. This includes + * Subrate parameters. This allows changing the connection interval to below the + * Baseline ConnInterval Values (BCV) and with finer granularity, if supported. + * + * Valid intervals of the local and peer controller should be known. + * See @ref bt_conn_le_read_min_conn_interval_groups + * + * @kconfig_dep{CONFIG_BT_SHORTER_CONNECTION_INTERVALS} + * + * @param conn @ref BT_CONN_TYPE_LE connection object. + * @param params Connection rate parameters. + * + * @return Zero on success or (negative) error code on failure. + * @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection. + */ +int bt_conn_le_conn_rate_request(struct bt_conn *conn, + const struct bt_conn_le_conn_rate_param *params); + /** @brief Read remote feature pages. * * Request remote feature pages, from 0 up to pages_requested or the number @@ -2052,6 +2294,31 @@ struct bt_conn_cb { const struct bt_conn_le_subrate_changed *params); #endif /* CONFIG_BT_SUBRATING */ +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) || defined(__DOXYGEN__) + /** @brief LE Connection Rate Changed event. + * + * This callback notifies the application that the connection rate + * parameters (including both connection interval and subrating) + * of the connection may have changed. + * + * @param conn Connection object. + * @param status HCI Status from LE Connection Rate Change event. + * Possible Status codes: + * - Success (0x00) + * - Unknown Connection Identifier (0x02) + * - Command Disallowed (0x0C) + * - Unsupported Feature or Parameter Value (0x11) + * - Invalid HCI Command Parameters (0x12) + * - Unsupported Remote Feature (0x1A) + * - Unsupported LL Parameter Value (0x20) + * @param params New connection rate parameters. + * The connection rate parameters will be NULL + * if @p status is not @ref BT_HCI_ERR_SUCCESS. + */ + void (*conn_rate_changed)(struct bt_conn *conn, uint8_t status, + const struct bt_conn_le_conn_rate_changed *params); +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ + #if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET) /** @brief Read all remote features complete event. * diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index d520a2324266..98990919b680 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -209,6 +209,8 @@ struct bt_hci_cmd_hdr { #define BT_LE_FEAT_BIT_CHANNEL_SOUNDING_TONE_QUAL_IND 48 #define BT_LE_FEAT_BIT_EXTENDED_FEAT_SET 63 #define BT_LE_FEAT_BIT_FRAME_SPACE_UPDATE 65 +#define BT_LE_FEAT_BIT_SHORTER_CONN_INTERVALS 72 +#define BT_LE_FEAT_BIT_SHORTER_CONN_INTERVALS_HOST_SUPP 73 #define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \ BIT((n) & 7)) @@ -289,6 +291,10 @@ struct bt_hci_cmd_hdr { BT_LE_FEAT_BIT_EXTENDED_FEAT_SET) #define BT_FEAT_LE_FRAME_SPACE_UPDATE_SET(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_FRAME_SPACE_UPDATE) +#define BT_FEAT_LE_SHORTER_CONN_INTERVALS(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_SHORTER_CONN_INTERVALS) +#define BT_FEAT_LE_SHORTER_CONN_INTERVALS_HOST_SUPP(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_SHORTER_CONN_INTERVALS_HOST_SUPP) #define BT_FEAT_LE_CIS(feat) (BT_FEAT_LE_CIS_CENTRAL(feat) | \ BT_FEAT_LE_CIS_PERIPHERAL(feat)) @@ -2854,6 +2860,66 @@ struct bt_hci_cp_le_frame_space_update { #define BT_HCI_OP_LE_FRAME_SPACE_UPDATE BT_OP(BT_OGF_LE, 0x009D) /* 0x209D */ +/** All limits according to BT Core spec 6.2 [Vol 4, Part E, 7.8.154]. */ +#define BT_HCI_LE_SCI_INTERVAL_MIN_125US (0x0003U) +#define BT_HCI_LE_SCI_INTERVAL_MAX_125US (0x7D00U) +#define BT_HCI_LE_SCI_INTERVAL_MIN_US (375U) +#define BT_HCI_LE_SCI_INTERVAL_MAX_US (4000000U) +#define BT_HCI_LE_SCI_INTERVAL_UNIT_US (125U) + +#define BT_HCI_LE_SCI_STRIDE_MIN_125US (0x0001U) + +#define BT_HCI_LE_MIN_SUPP_CONN_INT_MIN_US (375U) +#define BT_HCI_LE_MIN_SUPP_CONN_INT_MAX_US (7500U) + +#define BT_HCI_LE_SCI_CE_LEN_MIN_125US (0x0001U) +#define BT_HCI_LE_SCI_CE_LEN_MAX_125US (0x3E7FU) + +struct bt_hci_le_read_min_supported_conn_interval_group { + uint16_t group_min; + uint16_t group_max; + uint16_t group_stride; +} __packed; + +struct bt_hci_op_le_read_min_supported_conn_interval { + uint8_t status; + uint8_t min_supported_conn_interval; + uint8_t num_groups; + struct bt_hci_le_read_min_supported_conn_interval_group groups[]; +} __packed; + +#define BT_HCI_OP_LE_READ_MIN_SUPPORTED_CONN_INTERVAL \ + BT_OP(BT_OGF_LE, 0x00A3) /* 0x20A3 */ + +struct bt_hci_op_le_set_default_rate_parameters { + uint16_t conn_interval_min; + uint16_t conn_interval_max; + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t continuation_number; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +} __packed; + +#define BT_HCI_OP_LE_SET_DEFAULT_RATE_PARAMETERS BT_OP(BT_OGF_LE, 0x00A2) /* 0x20A2 */ + +struct bt_hci_op_le_connection_rate_request { + uint16_t handle; + uint16_t conn_interval_min; + uint16_t conn_interval_max; + uint16_t subrate_min; + uint16_t subrate_max; + uint16_t max_latency; + uint16_t continuation_number; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +} __packed; + +#define BT_HCI_OP_LE_CONNECTION_RATE_REQUEST BT_OP(BT_OGF_LE, 0x00A1) /* 0x20A1 */ + /* Event definitions */ #define BT_HCI_EVT_UNKNOWN 0x00 @@ -3218,6 +3284,7 @@ struct bt_hci_evt_le_advertising_report { /** All limits according to BT Core Spec v5.4 [Vol 4, Part E]. */ #define BT_HCI_LE_INTERVAL_MIN 0x0006 #define BT_HCI_LE_INTERVAL_MAX 0x0c80 +#define BT_HCI_LE_PERIPHERAL_LATENCY_MIN (0x0000U) #define BT_HCI_LE_PERIPHERAL_LATENCY_MAX 0x01f3 #define BT_HCI_LE_SUPERVISON_TIMEOUT_MIN 0x000a #define BT_HCI_LE_SUPERVISON_TIMEOUT_MAX 0x0c80 @@ -3609,6 +3676,7 @@ struct bt_hci_evt_le_biginfo_adv_report { /** All limits according to BT Core Spec v5.4 [Vol 4, Part E]. */ #define BT_HCI_LE_SUBRATE_FACTOR_MIN 0x0001 #define BT_HCI_LE_SUBRATE_FACTOR_MAX 0x01f4 +#define BT_HCI_LE_CONTINUATION_NUM_MIN (0x0000U) #define BT_HCI_LE_CONTINUATION_NUM_MAX 0x01f3 #define BT_HCI_EVT_LE_SUBRATE_CHANGE 0x23 @@ -4053,6 +4121,17 @@ struct bt_hci_evt_le_frame_space_update_complete { uint16_t spacing_types; } __packed; +#define BT_HCI_EVT_LE_CONN_RATE_CHANGE 0x37 +struct bt_hci_evt_le_conn_rate_change { + uint8_t status; + uint16_t handle; + uint16_t conn_interval; + uint16_t subrate_factor; + uint16_t peripheral_latency; + uint16_t continuation_number; + uint16_t supervision_timeout; +} __packed; + /* Event mask bits */ #define BT_EVT_BIT(n) (1ULL << (n)) @@ -4155,6 +4234,7 @@ struct bt_hci_evt_le_frame_space_update_complete { #define BT_EVT_MASK_LE_CS_TEST_END_COMPLETE BT_EVT_BIT(50) #define BT_EVT_MASK_LE_FRAME_SPACE_UPDATE_COMPLETE BT_EVT_BIT(52) +#define BT_EVT_MASK_LE_CONN_RATE_CHANGE BT_EVT_BIT(54) /** HCI Error Codes, BT Core Spec v5.4 [Vol 1, Part F]. */ #define BT_HCI_ERR_SUCCESS 0x00 diff --git a/subsys/bluetooth/Kconfig b/subsys/bluetooth/Kconfig index 7e8fa5dca6ec..ec5d4fafcc88 100644 --- a/subsys/bluetooth/Kconfig +++ b/subsys/bluetooth/Kconfig @@ -117,7 +117,7 @@ config BT_CONN_TX config BT_LE_LOCAL_MINIMUM_REQUIRED_FEATURE_PAGE int - default 1 if BT_FRAME_SPACE_UPDATE + default 1 if BT_FRAME_SPACE_UPDATE || BT_SHORTER_CONNECTION_INTERVALS default 0 depends on BT_LE_EXTENDED_FEAT_SET help @@ -260,6 +260,15 @@ config BT_CHANNEL_SOUNDING_REASSEMBLY_BUFFER_CNT results. Each running CS procedure is allocated one buffer and the number of concurrent CS procedures is limited by this value. +config BT_SHORTER_CONNECTION_INTERVALS + bool "Shorter Connection Intervals" + depends on !HAS_BT_CTLR || BT_CTLR_SHORTER_CONNECTION_INTERVALS_SUPPORT + depends on BT_LE_EXTENDED_FEAT_SET + depends on BT_SUBRATING + help + Enable support for the Bluetooth 6.2 Shorter Connection Intervals + feature. + endif # BT_CONN config BT_ISO diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 98107940b949..0892bd97b7eb 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -133,6 +133,9 @@ config BT_CTLR_CHANNEL_SOUNDING_SUPPORT config BT_CTLR_EXTENDED_FEAT_SET_SUPPORT bool +config BT_CTLR_SHORTER_CONNECTION_INTERVALS_SUPPORT + bool + # Virtual option that all local LL implementations should select config HAS_BT_CTLR bool @@ -1186,6 +1189,17 @@ config BT_CTLR_EXTENDED_FEAT_SET Enable support for Bluetooth 6.0 LL Extended Feature Set in the Controller. +config BT_CTLR_SHORTER_CONNECTION_INTERVALS + bool "Shorter Connection Intervals" + depends on BT_CTLR_SHORTER_CONNECTION_INTERVALS_SUPPORT + depends on BT_CTLR_EXTENDED_FEAT_SET + depends on BT_CTLR_SUBRATING + select BT_CTLR_SET_HOST_FEATURE + default y if BT_SHORTER_CONNECTION_INTERVALS + help + Enable support for Bluetooth 6.2 Shorter Connection Intervals + in the controller. + rsource "Kconfig.df" rsource "Kconfig.ll_sw_split" rsource "Kconfig.dtm" diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index d310ff1de5fe..6eb8d307bf08 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2839,7 +2839,10 @@ int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info) info->le.local = &conn->le.resp_addr; info->le.remote = &conn->le.init_addr; } - info->le.interval = conn->le.interval; + info->le.interval_us = conn->le.interval_us; +#if !defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) + info->le.interval = conn->le.interval_us / BT_HCI_LE_INTERVAL_UNIT_US; +#endif info->le.latency = conn->le.latency; info->le.timeout = conn->le.timeout; #if defined(CONFIG_BT_USER_PHY_UPDATE) @@ -3197,6 +3200,24 @@ void bt_conn_notify_subrate_change(struct bt_conn *conn, } } +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) +void bt_conn_notify_conn_rate_change(struct bt_conn *conn, uint8_t status, + const struct bt_conn_le_conn_rate_changed *params) +{ + BT_CONN_CB_DYNAMIC_FOREACH(callback) { + if (callback->conn_rate_changed != NULL) { + callback->conn_rate_changed(conn, status, params); + } + } + + STRUCT_SECTION_FOREACH(bt_conn_cb, cb) { + if (cb->conn_rate_changed != NULL) { + cb->conn_rate_changed(conn, status, params); + } + } +} +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ + static bool le_subrate_common_params_valid(const struct bt_conn_le_subrate_param *param) { /* All limits according to BT Core spec 5.4 [Vol 4, Part E, 7.8.123] */ @@ -3285,6 +3306,182 @@ int bt_conn_le_subrate_request(struct bt_conn *conn, } #endif /* CONFIG_BT_SUBRATING */ +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) +int bt_conn_le_read_min_conn_interval_groups(struct bt_conn_le_min_conn_interval_info *info) +{ + struct net_buf *rsp; + struct bt_hci_op_le_read_min_supported_conn_interval *rp; + int err; + + if (info == NULL) { + return -EINVAL; + } + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_MIN_SUPPORTED_CONN_INTERVAL, NULL, + &rsp); + if (err != 0) { + return err; + } + + rp = (struct bt_hci_op_le_read_min_supported_conn_interval *)rsp->data; + + if (rp->num_groups > BT_CONN_LE_MAX_CONN_INTERVAL_GROUPS) { + LOG_ERR("Too many groups: %d (max %d)", + rp->num_groups, BT_CONN_LE_MAX_CONN_INTERVAL_GROUPS); + net_buf_unref(rsp); + return -ENOMEM; + } + + info->min_supported_conn_interval_us = + BT_CONN_SCI_INTERVAL_TO_US(rp->min_supported_conn_interval); + info->num_groups = rp->num_groups; + + /* Copy groups up to the number allocated by the application */ + for (uint8_t i = 0; i < rp->num_groups; i++) { + info->groups[i].min_125us = sys_le16_to_cpu(rp->groups[i].group_min); + info->groups[i].max_125us = sys_le16_to_cpu(rp->groups[i].group_max); + info->groups[i].stride_125us = sys_le16_to_cpu(rp->groups[i].group_stride); + } + + net_buf_unref(rsp); + return 0; +} + +int bt_conn_le_read_min_conn_interval(uint16_t *min_interval_us) +{ + int err; + struct net_buf *rsp; + struct bt_hci_op_le_read_min_supported_conn_interval *rp; + + if (min_interval_us == NULL) { + return -EINVAL; + } + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_MIN_SUPPORTED_CONN_INTERVAL, NULL, + &rsp); + if (err != 0) { + return err; + } + + rp = (struct bt_hci_op_le_read_min_supported_conn_interval *)rsp->data; + *min_interval_us = BT_CONN_SCI_INTERVAL_TO_US(rp->min_supported_conn_interval); + + net_buf_unref(rsp); + return 0; +} + +static bool le_conn_rate_common_params_valid(const struct bt_conn_le_conn_rate_param *param) +{ + /* All limits according to BT Core spec 6.2 [Vol 4, Part E, 7.8.154] */ + + if (!IN_RANGE(param->interval_min_125us, BT_HCI_LE_SCI_INTERVAL_MIN_125US, + BT_HCI_LE_SCI_INTERVAL_MAX_125US) || + !IN_RANGE(param->interval_max_125us, BT_HCI_LE_SCI_INTERVAL_MIN_125US, + BT_HCI_LE_SCI_INTERVAL_MAX_125US) || + param->interval_min_125us > param->interval_max_125us) { + return false; + } + + if (!IN_RANGE(param->subrate_min, BT_HCI_LE_SUBRATE_FACTOR_MIN, + BT_HCI_LE_SUBRATE_FACTOR_MAX) || + !IN_RANGE(param->subrate_max, BT_HCI_LE_SUBRATE_FACTOR_MIN, + BT_HCI_LE_SUBRATE_FACTOR_MAX) || + param->subrate_min > param->subrate_max) { + return false; + } + + if (!IN_RANGE(param->max_latency, 0, BT_HCI_LE_PERIPHERAL_LATENCY_MAX) || + param->subrate_max * (param->max_latency + 1) > 500) { + return false; + } + + if (!IN_RANGE(param->continuation_number, 0, BT_HCI_LE_CONTINUATION_NUM_MAX) || + param->continuation_number >= param->subrate_max) { + return false; + } + + if (!IN_RANGE(param->supervision_timeout_10ms, BT_HCI_LE_SUPERVISON_TIMEOUT_MIN, + BT_HCI_LE_SUPERVISON_TIMEOUT_MAX)) { + return false; + } + + if (!IN_RANGE(param->min_ce_len_125us, BT_HCI_LE_SCI_CE_LEN_MIN_125US, + BT_HCI_LE_SCI_CE_LEN_MAX_125US) || + !IN_RANGE(param->max_ce_len_125us, BT_HCI_LE_SCI_CE_LEN_MIN_125US, + BT_HCI_LE_SCI_CE_LEN_MAX_125US) || + param->max_ce_len_125us < param->min_ce_len_125us) { + return false; + } + + return true; +} + +#if defined(CONFIG_BT_CENTRAL) +int bt_conn_le_conn_rate_set_defaults(const struct bt_conn_le_conn_rate_param *params) +{ + struct bt_hci_op_le_set_default_rate_parameters *cp; + struct net_buf *buf; + + if (params == NULL || !le_conn_rate_common_params_valid(params)) { + return -EINVAL; + } + + buf = bt_hci_cmd_alloc(K_FOREVER); + if (buf == NULL) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->conn_interval_min = sys_cpu_to_le16(params->interval_min_125us); + cp->conn_interval_max = sys_cpu_to_le16(params->interval_max_125us); + cp->subrate_min = sys_cpu_to_le16(params->subrate_min); + cp->subrate_max = sys_cpu_to_le16(params->subrate_max); + cp->max_latency = sys_cpu_to_le16(params->max_latency); + cp->continuation_number = sys_cpu_to_le16(params->continuation_number); + cp->supervision_timeout = sys_cpu_to_le16(params->supervision_timeout_10ms); + cp->min_ce_len = sys_cpu_to_le16(params->min_ce_len_125us); + cp->max_ce_len = sys_cpu_to_le16(params->max_ce_len_125us); + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_DEFAULT_RATE_PARAMETERS, buf, NULL); +} +#endif /* CONFIG_BT_CENTRAL */ + +int bt_conn_le_conn_rate_request(struct bt_conn *conn, + const struct bt_conn_le_conn_rate_param *params) +{ + struct bt_hci_op_le_connection_rate_request *cp; + struct net_buf *buf; + + if (!bt_conn_is_le(conn)) { + LOG_DBG("Invalid connection type: %u for %p", conn->type, conn); + return -EINVAL; + } + + if (params == NULL || !le_conn_rate_common_params_valid(params)) { + return -EINVAL; + } + + buf = bt_hci_cmd_alloc(K_FOREVER); + if (buf == NULL) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->conn_interval_min = sys_cpu_to_le16(params->interval_min_125us); + cp->conn_interval_max = sys_cpu_to_le16(params->interval_max_125us); + cp->subrate_min = sys_cpu_to_le16(params->subrate_min); + cp->subrate_max = sys_cpu_to_le16(params->subrate_max); + cp->max_latency = sys_cpu_to_le16(params->max_latency); + cp->continuation_number = sys_cpu_to_le16(params->continuation_number); + cp->supervision_timeout = sys_cpu_to_le16(params->supervision_timeout_10ms); + cp->min_ce_len = sys_cpu_to_le16(params->min_ce_len_125us); + cp->max_ce_len = sys_cpu_to_le16(params->max_ce_len_125us); + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CONNECTION_RATE_REQUEST, buf, NULL); +} +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ + #if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET) void bt_conn_notify_read_all_remote_feat_complete(struct bt_conn *conn, struct bt_conn_le_read_all_remote_feat_complete *params) diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index f1e4a289a135..3a4e2847e84d 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -527,6 +527,9 @@ void bt_conn_notify_path_loss_threshold_report(struct bt_conn *conn, void bt_conn_notify_subrate_change(struct bt_conn *conn, struct bt_conn_le_subrate_changed params); +void bt_conn_notify_conn_rate_change(struct bt_conn *conn, uint8_t status, + const struct bt_conn_le_conn_rate_changed *params); + void bt_conn_notify_read_all_remote_feat_complete(struct bt_conn *conn, struct bt_conn_le_read_all_remote_feat_complete *params); diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index ee16fea31064..b1586d56f930 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -2807,6 +2807,72 @@ void bt_hci_le_subrate_change_event(struct net_buf *buf) } #endif /* CONFIG_BT_SUBRATING */ +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) +void bt_hci_le_conn_rate_change_event(struct net_buf *buf) +{ + struct bt_hci_evt_le_conn_rate_change *evt; + struct bt_conn_le_conn_rate_changed params; + struct bt_conn *conn; + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + + conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->handle), BT_CONN_TYPE_LE); + if (conn == NULL) { + LOG_ERR("Unknown conn handle 0x%04X for connection rate event", + sys_le16_to_cpu(evt->handle)); + return; + } + + if (evt->status == BT_HCI_ERR_SUCCESS) { + conn->le.interval_us = + BT_CONN_SCI_INTERVAL_TO_US(sys_le16_to_cpu(evt->conn_interval)); + conn->le.subrate.factor = sys_le16_to_cpu(evt->subrate_factor); + conn->le.subrate.continuation_number = sys_le16_to_cpu(evt->continuation_number); + conn->le.latency = sys_le16_to_cpu(evt->peripheral_latency); + conn->le.timeout = sys_le16_to_cpu(evt->supervision_timeout); + + if (!IS_ENABLED(CONFIG_BT_CONN_PARAM_ANY)) { + if (!IN_RANGE(conn->le.interval_us / BT_HCI_LE_SCI_INTERVAL_UNIT_US, + BT_HCI_LE_SCI_INTERVAL_MIN_125US, + BT_HCI_LE_SCI_INTERVAL_MAX_125US)) { + LOG_WRN("interval_us exceeds the valid range %u us", + conn->le.interval_us); + } + if (!IN_RANGE(conn->le.subrate.factor, BT_HCI_LE_SUBRATE_FACTOR_MIN, + BT_HCI_LE_SUBRATE_FACTOR_MAX)) { + LOG_WRN("subrate_factor exceeds the valid range %d", + conn->le.subrate.factor); + } + if (conn->le.latency > BT_HCI_LE_PERIPHERAL_LATENCY_MAX) { + LOG_WRN("peripheral_latency exceeds the valid range 0x%04x", + conn->le.latency); + } + if (conn->le.subrate.continuation_number > BT_HCI_LE_CONTINUATION_NUM_MAX) { + LOG_WRN("continuation_number exceeds the valid range %d", + conn->le.subrate.continuation_number); + } + if (!IN_RANGE(conn->le.timeout, BT_HCI_LE_SUPERVISON_TIMEOUT_MIN, + BT_HCI_LE_SUPERVISON_TIMEOUT_MAX)) { + LOG_WRN("supervision_timeout exceeds the valid range 0x%04x", + conn->le.timeout); + } + } + + params.interval_us = conn->le.interval_us; + params.subrate_factor = conn->le.subrate.factor; + params.continuation_number = conn->le.subrate.continuation_number; + params.peripheral_latency = conn->le.latency; + params.supervision_timeout_10ms = conn->le.timeout; + + bt_conn_notify_conn_rate_change(conn, evt->status, ¶ms); + } else { + bt_conn_notify_conn_rate_change(conn, evt->status, NULL); + } + + bt_conn_unref(conn); +} +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ + static const struct event_handler vs_events[] = { #if defined(CONFIG_BT_DF_VS_CL_IQ_REPORT_16_BITS_IQ_SAMPLES) EVENT_HANDLER(BT_HCI_EVT_VS_LE_CONNECTIONLESS_IQ_REPORT, @@ -2957,7 +3023,11 @@ static const struct event_handler meta_events[] = { #if defined(CONFIG_BT_SUBRATING) EVENT_HANDLER(BT_HCI_EVT_LE_SUBRATE_CHANGE, bt_hci_le_subrate_change_event, sizeof(struct bt_hci_evt_le_subrate_change)), -#endif /* CONFIG_BT_PATH_LOSS_MONITORING */ +#endif /* CONFIG_BT_SUBRATING */ +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) + EVENT_HANDLER(BT_HCI_EVT_LE_CONN_RATE_CHANGE, bt_hci_le_conn_rate_change_event, + sizeof(struct bt_hci_evt_le_conn_rate_change)), +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ #if defined(CONFIG_BT_PER_ADV_SYNC_RSP) EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2, bt_hci_le_per_adv_report_v2, sizeof(struct bt_hci_evt_le_per_advertising_report_v2)), @@ -3566,6 +3636,11 @@ static int le_set_event_mask(void) mask |= BT_EVT_MASK_LE_SUBRATE_CHANGE; } + if (IS_ENABLED(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) && + BT_FEAT_LE_SHORTER_CONN_INTERVALS(bt_dev.le.features)) { + mask |= BT_EVT_MASK_LE_CONN_RATE_CHANGE; + } + if (IS_ENABLED(CONFIG_BT_LE_EXTENDED_FEAT_SET) && BT_FEAT_LE_EXTENDED_FEAT_SET(bt_dev.le.features)) { mask |= BT_EVT_MASK_LE_READ_ALL_REMOTE_FEAT_COMPLETE; @@ -3880,6 +3955,14 @@ static int le_init(void) } } + if (IS_ENABLED(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) && + BT_FEAT_LE_SHORTER_CONN_INTERVALS(bt_dev.le.features)) { + err = le_set_host_feature(BT_LE_FEAT_BIT_SHORTER_CONN_INTERVALS_HOST_SUPP, 1); + if (err != 0) { + return err; + } + } + return le_set_event_mask(); } From 95fd5a16fadf56b46f4220632de1bbacd19656b1 Mon Sep 17 00:00:00 2001 From: Timothy Keys Date: Thu, 16 Oct 2025 16:49:42 +0100 Subject: [PATCH 08/10] [nrf fromtree] bluetooth: host: Change uses of interval to interval_us Since Shorter Connection Intervals changes the unit that connection intervals can be represented in. It is necessary to change how they are stored and represented. This commit deprecates interval in favour of interval_us. Remove use of interval in internal bt_conn struct since it is no longer needed. Signed-off-by: Timothy Keys (cherry picked from commit c14dcaf1995ea9c70b4ce334e4c9765da09eb35d) --- doc/releases/migration-guide-4.4.rst | 3 +++ doc/releases/release-notes-4.4.rst | 6 ++++++ include/zephyr/bluetooth/conn.h | 16 +++++++++++++--- include/zephyr/bluetooth/hci_types.h | 2 ++ subsys/bluetooth/audio/ascs.c | 10 +++++----- subsys/bluetooth/audio/bap_broadcast_assistant.c | 4 ++-- subsys/bluetooth/audio/bap_scan_delegator.c | 2 +- subsys/bluetooth/audio/bap_unicast_client.c | 4 ++-- subsys/bluetooth/audio/tbs.c | 2 +- subsys/bluetooth/host/att.c | 2 +- subsys/bluetooth/host/conn.c | 16 ++++++++-------- subsys/bluetooth/host/conn_internal.h | 2 +- subsys/bluetooth/host/hci_core.c | 13 +++++++------ subsys/bluetooth/host/shell/bt.c | 15 ++++++++++----- tests/bluetooth/audio/ascs/src/main.c | 2 +- tests/bluetooth/audio/ascs/src/test_common.c | 2 +- tests/bluetooth/tester/src/btp_gap.c | 2 +- 17 files changed, 65 insertions(+), 38 deletions(-) diff --git a/doc/releases/migration-guide-4.4.rst b/doc/releases/migration-guide-4.4.rst index 7966cd0f25e3..554607e5f857 100644 --- a/doc/releases/migration-guide-4.4.rst +++ b/doc/releases/migration-guide-4.4.rst @@ -40,6 +40,9 @@ Bluetooth Host * :kconfig:option:`CONFIG_BT_SIGNING` has been deprecated. * :c:macro:`BT_GATT_CHRC_AUTH` has been deprecated. +* :c:member:`bt_conn_le_info.interval` has been deprecated. Use + :c:member:`bt_conn_le_info.interval_us` instead. Note that the units have changed: ``interval`` + was in units of 1.25 milliseconds, while ``interval_us`` is in microseconds. Networking ********** diff --git a/doc/releases/release-notes-4.4.rst b/doc/releases/release-notes-4.4.rst index 9622d9c5bd38..79a2bbf802e2 100644 --- a/doc/releases/release-notes-4.4.rst +++ b/doc/releases/release-notes-4.4.rst @@ -62,6 +62,12 @@ Deprecated APIs and options * The callback :c:member:`output_number` in :c:struct:`bt_mesh_prov` structure was deprecated. Applications should use :c:member:`output_numeric` callback instead. + * Host + + * :c:member:`bt_conn_le_info.interval` has been deprecated. Use + :c:member:`bt_conn_le_info.interval_us` instead. Note that the units have changed: + ``interval`` was in units of 1.25 milliseconds, while ``interval_us`` is in microseconds. + New APIs and options ==================== diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 7a2d5d9c1bad..4472a2690445 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -1056,9 +1056,19 @@ struct bt_conn_le_info { /** Connection interval in microseconds */ uint32_t interval_us; #if !defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) || defined(__DOXYGEN__) - /** Connection interval in units of 1.25 ms */ - uint16_t interval; + union { + /** @brief Connection interval in units of 1.25 ms + * + * @deprecated Use @ref bt_conn_le_info.interval_us instead + */ + __deprecated uint16_t interval; + /** @cond INTERNAL_HIDDEN */ + /** Workaround for setting deprecated @ref bt_conn_le_info.interval */ + uint16_t _interval; + /** @endcond */ + }; #endif /* !CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ + uint16_t latency; /**< Connection peripheral latency */ uint16_t timeout; /**< Connection supervision timeout */ @@ -1096,7 +1106,7 @@ struct bt_conn_le_info { * * Multiply by 125 to get microseconds. */ -#define BT_CONN_SCI_INTERVAL_TO_US(interval) ((interval) * BT_HCI_LE_SCI_INTERVAL_UNIT_US) +#define BT_CONN_SCI_INTERVAL_TO_US(_interval) ((_interval) * BT_HCI_LE_SCI_INTERVAL_UNIT_US) /** BR/EDR Connection Info Structure */ struct bt_conn_br_info { diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 98990919b680..ebdbe5c926ce 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -3289,6 +3289,8 @@ struct bt_hci_evt_le_advertising_report { #define BT_HCI_LE_SUPERVISON_TIMEOUT_MIN 0x000a #define BT_HCI_LE_SUPERVISON_TIMEOUT_MAX 0x0c80 +#define BT_HCI_LE_INTERVAL_UNIT_US (1250U) + #define BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE 0x03 struct bt_hci_evt_le_conn_update_complete { uint8_t status; diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 48ed34cfd570..b8123cc3fcf4 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -525,7 +525,7 @@ static void state_transition_work_handler(struct k_work *work) err = ase_state_notify(ase); if (err == -ENOMEM) { struct bt_conn_info info; - uint32_t retry_delay_ms; + uint32_t retry_delay_us; /* Revert back to old state */ ase->ep.state = old_state; @@ -533,14 +533,14 @@ static void state_transition_work_handler(struct k_work *work) err = bt_conn_get_info(ase->conn, &info); __ASSERT_NO_MSG(err == 0); - retry_delay_ms = BT_CONN_INTERVAL_TO_MS(info.le.interval); + retry_delay_us = info.le.interval_us; /* Reschedule the state transition */ - err = k_work_reschedule(d_work, K_MSEC(retry_delay_ms)); + err = k_work_reschedule(d_work, K_USEC(retry_delay_us)); if (err >= 0) { LOG_DBG("Out of buffers for ase state notification. " - "Will retry in %dms", - retry_delay_ms); + "Will retry in %dus", + retry_delay_us); return; } } diff --git a/subsys/bluetooth/audio/bap_broadcast_assistant.c b/subsys/bluetooth/audio/bap_broadcast_assistant.c index 77ead34fef68..76b80fb59d86 100644 --- a/subsys/bluetooth/audio/bap_broadcast_assistant.c +++ b/subsys/bluetooth/audio/bap_broadcast_assistant.c @@ -453,12 +453,12 @@ static void long_bap_read(struct bt_conn *conn, uint16_t handle) if (err != 0) { LOG_DBG("Failed to get conn info, use default interval"); - conn_info.le.interval = BT_GAP_INIT_CONN_INT_MIN; + conn_info.le.interval_us = BT_CONN_INTERVAL_TO_US(BT_GAP_INIT_CONN_INT_MIN); } /* Wait a connection interval to retry */ err = k_work_reschedule(&inst->bap_read_work, - K_USEC(BT_CONN_INTERVAL_TO_US(conn_info.le.interval))); + K_USEC(conn_info.le.interval_us)); if (err < 0) { LOG_DBG("Failed to reschedule read work: %d", err); bap_long_read_reset(inst); diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index 8c21b806900f..1be1eec56a82 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -240,7 +240,7 @@ static void receive_state_notify_cb(struct bt_conn *conn, void *data) LOG_DBG("Could not notify receive state: %d", err); err = k_work_reschedule(&internal_state->notify_work, - K_USEC(BT_CONN_INTERVAL_TO_US(conn_info.le.interval))); + K_USEC(conn_info.le.interval_us)); __ASSERT(err >= 0, "Failed to reschedule work: %d", err); } } diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 48c43f9faa8b..429431ada433 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -1767,12 +1767,12 @@ static void long_ase_read(struct bt_bap_unicast_client_ep *client_ep) if (err != 0) { LOG_DBG("Failed to get conn info, use default interval"); - conn_info.le.interval = BT_GAP_INIT_CONN_INT_MIN; + conn_info.le.interval_us = BT_CONN_INTERVAL_TO_US(BT_GAP_INIT_CONN_INT_MIN); } /* Wait a connection interval to retry */ err = k_work_reschedule(&client_ep->ase_read_work, - K_USEC(BT_CONN_INTERVAL_TO_US(conn_info.le.interval))); + K_USEC(conn_info.le.interval_us)); if (err < 0) { LOG_DBG("Failed to reschedule ASE long read work: %d", err); } diff --git a/subsys/bluetooth/audio/tbs.c b/subsys/bluetooth/audio/tbs.c index 7526c5327e0f..d7026c63dbe3 100644 --- a/subsys/bluetooth/audio/tbs.c +++ b/subsys/bluetooth/audio/tbs.c @@ -1005,7 +1005,7 @@ static void notify_handler_cb(struct bt_conn *conn, void *data) LOG_DBG("Notify failed (%d), retrying next connection interval", err); reschedule: err = k_work_reschedule(&inst->notify_work, - K_USEC(BT_CONN_INTERVAL_TO_US(info.le.interval))); + K_USEC(info.le.interval_us)); __ASSERT(err >= 0, "Failed to reschedule work: %d", err); } diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index c822de7ab4bc..644952f55257 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -3538,7 +3538,7 @@ static k_timeout_t credit_based_connection_delay(struct bt_conn *conn) * result in an overflow */ const uint32_t calculated_delay_us = - 2 * (conn->le.latency + 1) * BT_CONN_INTERVAL_TO_US(conn->le.interval); + 2 * (conn->le.latency + 1) * conn->le.interval_us; const uint32_t calculated_delay_ms = calculated_delay_us / USEC_PER_MSEC; return K_MSEC(MAX(100, calculated_delay_ms + rand_delay)); diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 6eb8d307bf08..f7658646acb1 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1960,30 +1960,30 @@ void bt_conn_notify_remote_info(struct bt_conn *conn) void bt_conn_notify_le_param_updated(struct bt_conn *conn) { + uint16_t interval_1250us = conn->le.interval_us / BT_HCI_LE_INTERVAL_UNIT_US; + /* If new connection parameters meet requirement of pending * parameters don't send peripheral conn param request anymore on timeout */ if (atomic_test_bit(conn->flags, BT_CONN_PERIPHERAL_PARAM_SET) && - conn->le.interval >= conn->le.interval_min && - conn->le.interval <= conn->le.interval_max && + interval_1250us >= conn->le.interval_min && + interval_1250us <= conn->le.interval_max && conn->le.latency == conn->le.pending_latency && conn->le.timeout == conn->le.pending_timeout) { atomic_clear_bit(conn->flags, BT_CONN_PERIPHERAL_PARAM_SET); } - BT_CONN_CB_DYNAMIC_FOREACH(callback) { if (callback->le_param_updated) { - callback->le_param_updated(conn, conn->le.interval, + callback->le_param_updated(conn, interval_1250us, conn->le.latency, conn->le.timeout); } } STRUCT_SECTION_FOREACH(bt_conn_cb, cb) { if (cb->le_param_updated) { - cb->le_param_updated(conn, conn->le.interval, - conn->le.latency, - conn->le.timeout); + cb->le_param_updated(conn, interval_1250us, + conn->le.latency, conn->le.timeout); } } } @@ -2841,7 +2841,7 @@ int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info) } info->le.interval_us = conn->le.interval_us; #if !defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) - info->le.interval = conn->le.interval_us / BT_HCI_LE_INTERVAL_UNIT_US; + info->le._interval = conn->le.interval_us / BT_HCI_LE_INTERVAL_UNIT_US; #endif info->le.latency = conn->le.latency; info->le.timeout = conn->le.timeout; diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 3a4e2847e84d..32c2445cb0c1 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -107,7 +107,7 @@ struct bt_conn_le { bt_addr_le_t init_addr; bt_addr_le_t resp_addr; - uint16_t interval; + uint32_t interval_us; uint16_t interval_min; uint16_t interval_max; diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index b1586d56f930..f02755ccf872 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1408,7 +1408,7 @@ static void update_conn(struct bt_conn *conn, const bt_addr_le_t *id_addr, { conn->handle = sys_le16_to_cpu(evt->handle); bt_addr_le_copy(&conn->le.dst, id_addr); - conn->le.interval = sys_le16_to_cpu(evt->interval); + conn->le.interval_us = sys_le16_to_cpu(evt->interval) * BT_HCI_LE_INTERVAL_UNIT_US; conn->le.latency = sys_le16_to_cpu(evt->latency); conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout); conn->role = evt->role; @@ -2060,15 +2060,16 @@ static void le_conn_update_complete(struct net_buf *buf) bt_l2cap_update_conn_param(conn, ¶m); } else { if (!evt->status) { - conn->le.interval = sys_le16_to_cpu(evt->interval); + conn->le.interval_us = + sys_le16_to_cpu(evt->interval) * BT_HCI_LE_INTERVAL_UNIT_US; conn->le.latency = sys_le16_to_cpu(evt->latency); conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout); if (!IS_ENABLED(CONFIG_BT_CONN_PARAM_ANY)) { - if (!IN_RANGE(conn->le.interval, BT_HCI_LE_INTERVAL_MIN, - BT_HCI_LE_INTERVAL_MAX)) { - LOG_WRN("interval exceeds the valid range 0x%04x", - conn->le.interval); + if (!IN_RANGE(conn->le.interval_us / BT_HCI_LE_INTERVAL_UNIT_US, + BT_HCI_LE_INTERVAL_MIN, BT_HCI_LE_INTERVAL_MAX)) { + LOG_WRN("interval exceeds the valid range %u us", + conn->le.interval_us); } if (conn->le.latency > BT_HCI_LE_PERIPHERAL_LATENCY_MAX) { LOG_WRN("latency exceeds the valid range 0x%04x", diff --git a/subsys/bluetooth/host/shell/bt.c b/subsys/bluetooth/host/shell/bt.c index 816b6549853b..4395a3c62c26 100644 --- a/subsys/bluetooth/host/shell/bt.c +++ b/subsys/bluetooth/host/shell/bt.c @@ -3715,8 +3715,13 @@ static int cmd_info(const struct shell *sh, size_t argc, char *argv[]) print_le_addr("Local on-air", info.le.local); shell_print(sh, "Interval: 0x%04x (%u us)", - info.le.interval, - BT_CONN_INTERVAL_TO_US(info.le.interval)); +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) + info.le.interval_us / BT_HCI_LE_SCI_INTERVAL_UNIT_US, +#else + info.le.interval_us / BT_HCI_LE_INTERVAL_UNIT_US, +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ + info.le.interval_us); + shell_print(sh, "Latency: 0x%04x", info.le.latency); shell_print(sh, "Supervision timeout: 0x%04x (%d ms)", @@ -4138,9 +4143,9 @@ static void connection_info(struct bt_conn *conn, void *user_data) #endif case BT_CONN_TYPE_LE: bt_addr_le_to_str(info.le.dst, addr, sizeof(addr)); - bt_shell_print("%s#%u [LE][%s] %s: Interval %u latency %u timeout %u", selected, - info.id, role_str, addr, info.le.interval, info.le.latency, - info.le.timeout); + bt_shell_print("%s#%u [LE][%s] %s: Interval %u us, latency %u, timeout %u ms", + selected, info.id, role_str, addr, info.le.interval_us, + info.le.latency, info.le.timeout * 10); break; #if defined(CONFIG_BT_ISO) case BT_CONN_TYPE_ISO: diff --git a/tests/bluetooth/audio/ascs/src/main.c b/tests/bluetooth/audio/ascs/src/main.c index a326c7b1495f..4aca7cee1c11 100644 --- a/tests/bluetooth/audio/ascs/src/main.c +++ b/tests/bluetooth/audio/ascs/src/main.c @@ -667,7 +667,7 @@ ZTEST_F(ascs_test_suite, test_ase_state_notification_retry) zassert_equal(err, 0); /* Wait for ASE state notification retry */ - k_sleep(K_MSEC(BT_CONN_INTERVAL_TO_MS(info.le.interval))); + k_sleep(K_USEC(info.le.interval_us)); expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY); } diff --git a/tests/bluetooth/audio/ascs/src/test_common.c b/tests/bluetooth/audio/ascs/src/test_common.c index b09677592f46..f97840fe40ac 100644 --- a/tests/bluetooth/audio/ascs/src/test_common.c +++ b/tests/bluetooth/audio/ascs/src/test_common.c @@ -77,7 +77,7 @@ void test_conn_init(struct bt_conn *conn) conn->info.security.level = BT_SECURITY_L2; conn->info.security.enc_key_size = BT_ENC_KEY_SIZE_MAX; conn->info.security.flags = BT_SECURITY_FLAG_OOB | BT_SECURITY_FLAG_SC; - conn->info.le.interval = BT_GAP_INIT_CONN_INT_MIN; + conn->info.le.interval_us = BT_GAP_INIT_CONN_INT_MIN * BT_HCI_LE_INTERVAL_UNIT_US; } const struct bt_gatt_attr *test_ase_control_point_get(void) diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c index 80b30467bd9d..f3535d4acca7 100644 --- a/tests/bluetooth/tester/src/btp_gap.c +++ b/tests/bluetooth/tester/src/btp_gap.c @@ -134,7 +134,7 @@ static void le_connected(struct bt_conn *conn, uint8_t err) if (bt_conn_is_type(conn, BT_CONN_TYPE_LE)) { bt_addr_le_copy(&ev.address, info.le.dst); - ev.interval = sys_cpu_to_le16(info.le.interval); + ev.interval = sys_cpu_to_le16(info.le.interval_us / BT_HCI_LE_INTERVAL_UNIT_US); ev.latency = sys_cpu_to_le16(info.le.latency); ev.timeout = sys_cpu_to_le16(info.le.timeout); } else if (IS_ENABLED(CONFIG_BT_CLASSIC) && bt_conn_is_type(conn, BT_CONN_TYPE_BR)) { From 6c570a86d7eb25310f2c110acd5e8a19931b642b Mon Sep 17 00:00:00 2001 From: Timothy Keys Date: Wed, 15 Oct 2025 16:03:50 +0100 Subject: [PATCH 09/10] [nrf fromtree] bluetooth: host: shell: Add SCI shell commands This adds support for Shorter Connection Interval commands in the bt shell. Signed-off-by: Timothy Keys (cherry picked from commit 6bfa6fa9a825f2076ae9a070abb28e09556872ec) --- subsys/bluetooth/host/shell/bt.c | 182 ++++++++++++++++++++++++++-- tests/bluetooth/shell/testcase.yaml | 7 ++ 2 files changed, 178 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/host/shell/bt.c b/subsys/bluetooth/host/shell/bt.c index 4395a3c62c26..21302647bdf7 100644 --- a/subsys/bluetooth/host/shell/bt.c +++ b/subsys/bluetooth/host/shell/bt.c @@ -1009,7 +1009,30 @@ void subrate_changed(struct bt_conn *conn, bt_shell_print("Subrate change failed (HCI status 0x%02x)", params->status); } } -#endif + +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) +static void conn_rate_changed(struct bt_conn *conn, uint8_t status, + const struct bt_conn_le_conn_rate_changed *params) +{ + if (status == BT_HCI_ERR_SUCCESS) { + bt_shell_print("Connection rate parameters changed: " + "Connection Interval: %u us " + "Subrate Factor: %d " + "Peripheral latency: 0x%04x " + "Continuation Number: %d " + "Supervision timeout: 0x%04x (%d ms)", + params->interval_us, + params->subrate_factor, + params->peripheral_latency, + params->continuation_number, + params->supervision_timeout_10ms, + params->supervision_timeout_10ms * 10); + } else { + bt_shell_print("Connection rate change failed (HCI status 0x%02x)", status); + } +} +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ +#endif /* CONFIG_BT_SUBRATING */ #if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET) void read_all_remote_feat_complete(struct bt_conn *conn, @@ -1255,6 +1278,9 @@ BT_CONN_CB_DEFINE(conn_callbacks) = { #if defined(CONFIG_BT_SUBRATING) .subrate_changed = subrate_changed, #endif +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) + .conn_rate_changed = conn_rate_changed, +#endif #if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET) .read_all_remote_feat_complete = read_all_remote_feat_complete, #endif @@ -3361,7 +3387,130 @@ static int cmd_subrate_request(const struct shell *sh, size_t argc, char *argv[] return 0; } -#endif + +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) +static int cmd_read_min_conn_interval_groups(const struct shell *sh, size_t argc, char *argv[]) +{ + int err; + struct bt_conn_le_min_conn_interval_info info; + + err = bt_conn_le_read_min_conn_interval_groups(&info); + if (err != 0) { + shell_error(sh, "bt_conn_le_read_min_conn_interval_groups returned error %d", err); + return -ENOEXEC; + } + + shell_print(sh, "Minimum supported connection interval: %u us", + info.min_supported_conn_interval_us); + shell_print(sh, "Number of groups: %u", info.num_groups); + + for (uint8_t i = 0; i < info.num_groups; i++) { + shell_print( + sh, + " Group %u: min=0x%04x (%u us), max=0x%04x (%u us), stride=0x%04x (%u us)", + i, + info.groups[i].min_125us, + BT_CONN_SCI_INTERVAL_TO_US(info.groups[i].min_125us), + info.groups[i].max_125us, + BT_CONN_SCI_INTERVAL_TO_US(info.groups[i].max_125us), + info.groups[i].stride_125us, + BT_CONN_SCI_INTERVAL_TO_US(info.groups[i].stride_125us)); + } + + return 0; +} + +static int cmd_read_min_conn_interval(const struct shell *sh, size_t argc, char *argv[]) +{ + int err; + uint16_t min_interval_us; + + err = bt_conn_le_read_min_conn_interval(&min_interval_us); + if (err != 0) { + shell_error(sh, "bt_conn_le_read_min_conn_interval returned error %d", err); + return -ENOEXEC; + } + + shell_print(sh, "Minimum supported connection interval: %u us", min_interval_us); + return 0; +} + +static int cmd_conn_rate_set_defaults(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + + for (size_t argn = 1; argn < argc; argn++) { + (void)shell_strtoul(argv[argn], 10, &err); + + if (err != 0) { + shell_help(sh); + shell_error(sh, "Could not parse input number %zu", argn); + return SHELL_CMD_HELP_PRINTED; + } + } + + const struct bt_conn_le_conn_rate_param params = { + .interval_min_125us = shell_strtoul(argv[1], 10, &err), + .interval_max_125us = shell_strtoul(argv[2], 10, &err), + .subrate_min = shell_strtoul(argv[3], 10, &err), + .subrate_max = shell_strtoul(argv[4], 10, &err), + .max_latency = shell_strtoul(argv[5], 10, &err), + .continuation_number = shell_strtoul(argv[6], 10, &err), + .supervision_timeout_10ms = shell_strtoul(argv[7], 10, &err), + .min_ce_len_125us = shell_strtoul(argv[8], 10, &err), + .max_ce_len_125us = shell_strtoul(argv[9], 10, &err), + }; + + err = bt_conn_le_conn_rate_set_defaults(¶ms); + if (err != 0) { + shell_error(sh, "bt_conn_le_conn_rate_set_defaults returned error %d", err); + return -ENOEXEC; + } + + return 0; +} + +static int cmd_conn_rate_request(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + + if (default_conn == NULL) { + shell_error(sh, "Conn handle error, at least one connection is required."); + return -ENOEXEC; + } + + for (size_t argn = 1; argn < argc; argn++) { + (void)shell_strtoul(argv[argn], 10, &err); + + if (err != 0) { + shell_help(sh); + shell_error(sh, "Could not parse input number %zu", argn); + return SHELL_CMD_HELP_PRINTED; + } + } + + const struct bt_conn_le_conn_rate_param params = { + .interval_min_125us = shell_strtoul(argv[1], 10, &err), + .interval_max_125us = shell_strtoul(argv[2], 10, &err), + .subrate_min = shell_strtoul(argv[3], 10, &err), + .subrate_max = shell_strtoul(argv[4], 10, &err), + .max_latency = shell_strtoul(argv[5], 10, &err), + .continuation_number = shell_strtoul(argv[6], 10, &err), + .supervision_timeout_10ms = shell_strtoul(argv[7], 10, &err), + .min_ce_len_125us = shell_strtoul(argv[8], 10, &err), + .max_ce_len_125us = shell_strtoul(argv[9], 10, &err), + }; + + err = bt_conn_le_conn_rate_request(default_conn, ¶ms); + if (err != 0) { + shell_error(sh, "bt_conn_le_conn_rate_request returned error %d", err); + return -ENOEXEC; + } + + return 0; +} +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ +#endif /* CONFIG_BT_SUBRATING */ #if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET) static int cmd_read_all_remote_features(const struct shell *sh, size_t argc, char *argv[]) @@ -3714,14 +3863,7 @@ static int cmd_info(const struct shell *sh, size_t argc, char *argv[]) print_le_addr("Remote on-air", info.le.remote); print_le_addr("Local on-air", info.le.local); - shell_print(sh, "Interval: 0x%04x (%u us)", -#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) - info.le.interval_us / BT_HCI_LE_SCI_INTERVAL_UNIT_US, -#else - info.le.interval_us / BT_HCI_LE_INTERVAL_UNIT_US, -#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ - info.le.interval_us); - + shell_print(sh, "Interval: %u us", info.le.interval_us); shell_print(sh, "Latency: 0x%04x", info.le.latency); shell_print(sh, "Supervision timeout: 0x%04x (%d ms)", @@ -5216,7 +5358,25 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds, " " " ", cmd_subrate_request, 6, 0), -#endif +#if defined(CONFIG_BT_SHORTER_CONNECTION_INTERVALS) + SHELL_CMD_ARG(read-min-conn-interval-groups, NULL, + "Read minimum supported connection interval and groups", + cmd_read_min_conn_interval_groups, 1, 0), + SHELL_CMD_ARG(read-min-conn-interval, NULL, + "Read minimum supported connection interval only", + cmd_read_min_conn_interval, 1, 0), + SHELL_CMD_ARG(conn-rate-set-defaults, NULL, + " " + " " + " ", + cmd_conn_rate_set_defaults, 10, 0), + SHELL_CMD_ARG(conn-rate-request, NULL, + " " + " " + " ", + cmd_conn_rate_request, 10, 0), +#endif /* CONFIG_BT_SHORTER_CONNECTION_INTERVALS */ +#endif /* CONFIG_BT_SUBRATING */ #if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET) SHELL_CMD_ARG(read-all-remote-features, NULL, "", cmd_read_all_remote_features, 2, 0), diff --git a/tests/bluetooth/shell/testcase.yaml b/tests/bluetooth/shell/testcase.yaml index 399c939b0661..7cf350dabe81 100644 --- a/tests/bluetooth/shell/testcase.yaml +++ b/tests/bluetooth/shell/testcase.yaml @@ -46,6 +46,13 @@ tests: - CONFIG_BT_LE_EXTENDED_FEAT_SET=y - CONFIG_BT_LL_SW_SPLIT=n build_only: true + bluetooth.shell.shorter_connection_intervals: + extra_configs: + - CONFIG_BT_SHORTER_CONNECTION_INTERVALS=y + - CONFIG_BT_LE_EXTENDED_FEAT_SET=y + - CONFIG_BT_SUBRATING=y + - CONFIG_BT_LL_SW_SPLIT=n + build_only: true bluetooth.shell.channel_sounding: extra_configs: - CONFIG_BT_CHANNEL_SOUNDING=y From 394b00b7047fa559334c59c75b6b4a4aef8f88d0 Mon Sep 17 00:00:00 2001 From: Aleksandar Stanoev Date: Wed, 19 Nov 2025 15:31:29 +0000 Subject: [PATCH 10/10] [nrf fromtree] bluetooth: host: Fix bt_conn reference leak in Frame Space Update Fix a missing unref of a bt_conn reference, leading to a ref count mismatch, and causing the following warning to be printed: bt_conn: Found valid connection ... in disconnected state. Signed-off-by: Aleksandar Stanoev (cherry picked from commit 1eea6adad2963a7c889281e7024cc0f01af7e842) --- subsys/bluetooth/host/hci_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index f02755ccf872..66ba610bee2b 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1856,6 +1856,8 @@ static void le_frame_space_update_complete(struct net_buf *buf) } bt_conn_notify_frame_space_update_complete(conn, ¶ms); + + bt_conn_unref(conn); } #endif /* CONFIG_BT_FRAME_SPACE_UPDATE */