Skip to content

Commit 7cf67d9

Browse files
Thalleynordicjm
authored andcommitted
[nrf fromtree] Bluetooth: Host: Add API for reading LE controller features
The function supports reading multiple controller-based values. It is effectively a copy of struct bt_dev_le but in a more application-oriented definition. It was chosen to keep the features as an array rather than a 64-bit value, as the comparison macros work on arrays and that there already exists new bits > 64 in the core spec which is not yet supported by Zephyr. It is being smoke tested in a generic GATT client test, as the individual values may depend on several Kconfig options. Signed-off-by: Emil Gydesen <[email protected]> (cherry picked from commit 44c5c1d)
1 parent d0409e0 commit 7cf67d9

File tree

6 files changed

+129
-5
lines changed

6 files changed

+129
-5
lines changed

doc/releases/release-notes-4.2.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ New APIs and options
6363
like you need to add more details, add them in the API documentation code
6464
instead.
6565
66+
* Bluetooth
67+
68+
* Host
69+
70+
* :c:func:`bt_le_get_local_features`
71+
6672
New Boards
6773
**********
6874

include/zephyr/bluetooth/bluetooth.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020

2121
#include <stdbool.h>
22+
#include <stdint.h>
2223
#include <string.h>
2324

2425
#include <zephyr/sys/util.h>
@@ -48,6 +49,13 @@ extern "C" {
4849
*/
4950
#define BT_ID_DEFAULT 0
5051

52+
/**
53+
* @brief Number of octets for local supported
54+
*
55+
* The value of 8 correspond to page 0 in the LE Controller supported features
56+
*/
57+
#define BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE 8
58+
5159
/** Opaque type representing an advertiser. */
5260
struct bt_le_ext_adv;
5361

@@ -517,6 +525,78 @@ size_t bt_data_get_len(const struct bt_data data[], size_t data_count);
517525
*/
518526
size_t bt_data_serialize(const struct bt_data *input, uint8_t *output);
519527

528+
struct bt_le_local_features {
529+
/**
530+
* @brief Local LE controller supported features.
531+
*
532+
* Refer to BT_LE_FEAT_BIT_* for values.
533+
* Refer to the BT_FEAT_LE_* macros for value comparionson.
534+
* See Bluetooth Core Specification, Vol 6, Part B, Section 4.6.
535+
*/
536+
uint8_t features[BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE];
537+
538+
/**
539+
* @brief Local LE controller supported states
540+
*
541+
* Refer to BT_LE_STATES_* for values.
542+
* See Bluetooth Core Specification 6.0, Vol 4, Part E, Section 7.8.27
543+
*/
544+
uint64_t states;
545+
546+
/**
547+
* @brief ACL data packet length
548+
*
549+
* This represents the maximum ACL HCI Data packet which can be sent from the Host to the
550+
* Controller.
551+
* The Host may support L2CAP and ATT MTUs larger than this value.
552+
* See Bluetooth Core Specification, Vol 6, Part E, Section 7.8.2.
553+
*/
554+
uint16_t acl_mtu;
555+
/** Total number of ACL data packets */
556+
uint8_t acl_pkts;
557+
558+
/**
559+
* @brief ISO data packet length
560+
*
561+
* This represents the maximum ISO HCI Data packet which can be sent from the Host to the
562+
* Controller.
563+
* ISO SDUs above this size can be fragmented assuming that the number of
564+
* @ref bt_le_local_features.iso_pkts support the maximum size.
565+
*/
566+
uint16_t iso_mtu;
567+
/** Total number of ISO data packets */
568+
uint8_t iso_pkts;
569+
570+
/**
571+
* @brief Maximum size of the controller resolving list.
572+
*
573+
* See Bluetooth Core Specification, Vol 6, Part E, Section 7.8.41.
574+
*/
575+
uint8_t rl_size;
576+
577+
/**
578+
* @brief Maximum advertising data length
579+
*
580+
* @note The maximum advertising data length also depends on advertising type.
581+
*
582+
* See Bluetooth Core Specification, Vol 6, Part E, Section 7.8.57.
583+
*/
584+
uint16_t max_adv_data_len;
585+
};
586+
587+
/**
588+
* @brief Get local Bluetooth LE controller features
589+
*
590+
* Can only be called after bt_enable()
591+
*
592+
* @param local_features Local features struct to be populated with information.
593+
*
594+
* @retval 0 Success
595+
* @retval -EAGAIN The information is not yet available.
596+
* @retval -EINVAL @p local_features is NULL.
597+
*/
598+
int bt_le_get_local_features(struct bt_le_local_features *local_features);
599+
520600
/** Advertising options */
521601
enum {
522602
/** Convenience value when no options are specified. */

include/zephyr/bluetooth/hci_types.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,14 @@ struct bt_hci_cmd_hdr {
200200
#define BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION 39
201201
#define BT_LE_FEAT_BIT_ADV_CODING_SEL 40
202202
#define BT_LE_FEAT_BIT_ADV_CODING_SEL_HOST 41
203-
203+
#define BT_LE_FEAT_BIT_DECISION_ADV_FILTER 42
204204
#define BT_LE_FEAT_BIT_PAWR_ADVERTISER 43
205205
#define BT_LE_FEAT_BIT_PAWR_SCANNER 44
206-
206+
#define BT_LE_FEAT_BIT_UNSEG_FRAMED_MODE 45
207207
#define BT_LE_FEAT_BIT_CHANNEL_SOUNDING 46
208208
#define BT_LE_FEAT_BIT_CHANNEL_SOUNDING_HOST 47
209+
#define BT_LE_FEAT_BIT_CHANNEL_SOUNDING_TONE_QUAL_IND 48
210+
#define BT_LE_FEAT_BIT_LL_EXTENDED_FEAT_SET 63
209211

210212
#define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \
211213
BIT((n) & 7))

subsys/bluetooth/host/hci_core.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
/* hci_core.c - HCI core Bluetooth handling */
22

33
/*
4-
* Copyright (c) 2017-2021 Nordic Semiconductor ASA
4+
* Copyright (c) 2017-2025 Nordic Semiconductor ASA
55
* Copyright (c) 2015-2016 Intel Corporation
66
*
77
* SPDX-License-Identifier: Apache-2.0
88
*/
99

10+
#include <zephyr/autoconf.h>
11+
1012
#include <zephyr/bluetooth/hci_types.h>
1113
#include <zephyr/kernel.h>
1214
#include <string.h>
@@ -4509,6 +4511,29 @@ int bt_set_appearance(uint16_t appearance)
45094511
}
45104512
#endif
45114513

4514+
int bt_le_get_local_features(struct bt_le_local_features *remote_info)
4515+
{
4516+
if (remote_info == NULL) {
4517+
return -EINVAL;
4518+
}
4519+
4520+
if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
4521+
return -EAGAIN;
4522+
}
4523+
4524+
memcpy(remote_info->features, bt_dev.le.features, sizeof(remote_info->features));
4525+
remote_info->states = bt_dev.le.states;
4526+
remote_info->acl_mtu = COND_CODE_1(CONFIG_BT_CONN, (bt_dev.le.acl_mtu), (0));
4527+
remote_info->acl_pkts = COND_CODE_1(CONFIG_BT_CONN, (bt_dev.le.acl_pkts.limit), (0));
4528+
remote_info->iso_mtu = COND_CODE_1(CONFIG_BT_ISO, (bt_dev.le.iso_mtu), (0));
4529+
remote_info->iso_pkts = COND_CODE_1(CONFIG_BT_ISO, (bt_dev.le.iso_limit), (0));
4530+
remote_info->rl_size = COND_CODE_1(CONFIG_BT_SMP, (bt_dev.le.rl_size), (0));
4531+
remote_info->max_adv_data_len =
4532+
COND_CODE_1(CONFIG_BT_BROADCASTER, (bt_dev.le.max_adv_data_len), (0));
4533+
4534+
return 0;
4535+
}
4536+
45124537
bool bt_addr_le_is_bonded(uint8_t id, const bt_addr_le_t *addr)
45134538
{
45144539
if (IS_ENABLED(CONFIG_BT_SMP)) {

subsys/bluetooth/host/hci_core.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
/* hci_core.h - Bluetooth HCI core access */
22

33
/*
4-
* Copyright (c) 2021 Nordic Semiconductor ASA
4+
* Copyright (c) 2021-2025 Nordic Semiconductor ASA
55
* Copyright (c) 2015-2016 Intel Corporation
66
*
77
* SPDX-License-Identifier: Apache-2.0
88
*/
9+
#include <stdint.h>
910

11+
#include <zephyr/bluetooth/bluetooth.h>
1012
#include <zephyr/devicetree.h>
1113

1214
/* LL connection parameters */
@@ -271,7 +273,7 @@ struct bt_le_per_adv_sync {
271273

272274
struct bt_dev_le {
273275
/* LE features */
274-
uint8_t features[8];
276+
uint8_t features[BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE];
275277
/* LE states */
276278
uint64_t states;
277279

tests/bsim/bluetooth/host/gatt/general/src/gatt_client_test.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <zephyr/kernel.h>
88

9+
#include <zephyr/sys/byteorder.h>
910
#include <zephyr/types.h>
1011
#include <stddef.h>
1112
#include <errno.h>
@@ -363,6 +364,7 @@ static void gatt_read(uint16_t handle, uint8_t expect_att_err)
363364

364365
static void test_main(void)
365366
{
367+
struct bt_le_local_features local_features;
366368
int err;
367369

368370
bt_conn_cb_register(&conn_callbacks);
@@ -372,6 +374,13 @@ static void test_main(void)
372374
TEST_FAIL("Bluetooth discover failed (err %d)", err);
373375
}
374376

377+
err = bt_le_get_local_features(&local_features);
378+
TEST_ASSERT(err == 0, "Failed to get local features");
379+
TEST_ASSERT(local_features.acl_mtu > 0U, "Invalid ACL MTU");
380+
TEST_ASSERT(local_features.acl_pkts > 0U, "Invalid ACL packet count");
381+
TEST_ASSERT(sys_get_le64(local_features.features) > 0U, "Invalid features");
382+
TEST_ASSERT(local_features.states > 0U, "Invalid states");
383+
375384
err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
376385
if (err != 0) {
377386
TEST_FAIL("Scanning failed to start (err %d)", err);

0 commit comments

Comments
 (0)