Skip to content

Commit e874798

Browse files
committed
bluetooth: host: Add support for extended feature set feature
This commit adds support for the extended feature set feature. This includes: - hci boilerplate - kconfigs, including one for a max local feature page - reading remote features is done by a command and callback - this is not linked into the auto feature request on connection as this procedure can take quite a few connection events, and we do not want to delay the user - added the commands to the bt shell Signed-off-by: Sean Madigan <sean.madigan@nordicsemi.no>
1 parent 70fd5ee commit e874798

File tree

11 files changed

+331
-11
lines changed

11 files changed

+331
-11
lines changed

include/zephyr/bluetooth/bluetooth.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <zephyr/bluetooth/gap.h>
3535
#include <zephyr/bluetooth/addr.h>
3636
#include <zephyr/bluetooth/crypto.h>
37+
#include <zephyr/bluetooth/hci_types.h>
3738
#include <zephyr/bluetooth/classic/classic.h>
3839
#include <zephyr/net_buf.h>
3940
#include <zephyr/sys/slist.h>
@@ -71,11 +72,16 @@ extern "C" {
7172
#define BT_ID_DEFAULT 0
7273

7374
/**
74-
* @brief Number of octets for local supported
75+
* @brief Number of octets for local supported features
7576
*
76-
* The value of 8 correspond to page 0 in the LE Controller supported features
77+
* The value of 8 correspond to page 0 in the LE Controller supported features.
78+
* 24 bytes are required for all subsequent supported feature pages.
7779
*/
78-
#define BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE 8
80+
#define BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE \
81+
(BT_HCI_LE_BYTES_PAGE_0_FEATURE_PAGE + \
82+
COND_CODE_1(CONFIG_BT_LE_MAX_LOCAL_SUPPORTED_FEATURE_PAGE, \
83+
CONFIG_BT_LE_MAX_LOCAL_SUPPORTED_FEATURE_PAGE * BT_HCI_LE_BYTES_PER_FEATURE_PAGE, \
84+
(0U)))
7985

8086
/** Opaque type representing an advertiser. */
8187
struct bt_le_ext_adv;

include/zephyr/bluetooth/conn.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,27 @@ struct bt_conn_le_subrate_changed {
252252
uint16_t supervision_timeout;
253253
};
254254

255+
/** Read all remote features complete callback params */
256+
struct bt_conn_le_read_all_remote_feat_complete {
257+
/** @brief HCI Status from LE Read All Remote Features Complete event.
258+
*
259+
* The remaining parameters will be unchanged if status is not @ref BT_HCI_ERR_SUCCESS.
260+
*/
261+
uint8_t status;
262+
/** Number of pages supported by remote device. */
263+
uint8_t max_remote_page;
264+
/** Number of pages fetched from remote device. */
265+
uint8_t max_valid_page;
266+
/** @brief Pointer to array of size 248, with feature bits of remote supported features.
267+
*
268+
* Page 0 being 8 bytes, with the following 10 pages of 24 bytes.
269+
* Refer to BT_LE_FEAT_BIT_* for values.
270+
* Refer to the BT_FEAT_LE_* macros for value comparison.
271+
* See Bluetooth Core Specification, Vol 6, Part B, Section 4.6.
272+
*/
273+
const uint8_t *features;
274+
};
275+
255276
/** Connection Type */
256277
enum __packed bt_conn_type {
257278
/** LE Connection Type */
@@ -1186,6 +1207,24 @@ int bt_conn_le_subrate_set_defaults(const struct bt_conn_le_subrate_param *param
11861207
int bt_conn_le_subrate_request(struct bt_conn *conn,
11871208
const struct bt_conn_le_subrate_param *params);
11881209

1210+
/** @brief Read remote feature pages.
1211+
*
1212+
* Request remote feature pages, from 0 up to pages_requested or the number
1213+
* of pages supported by the peer. There is a maximum of 10 pages.
1214+
* This function will trigger the @ref read_all_remote_feat_complete callback
1215+
* when the procedure is completed.
1216+
*
1217+
* @kconfig_dep{CONFIG_BT_LE_EXTENDED_FEAT_SET}
1218+
*
1219+
* @param conn @ref BT_CONN_TYPE_LE connection object.
1220+
* @param pages_requested Number of feature pages to be requested from peer.
1221+
* There is a maximum of 10 pages.
1222+
*
1223+
* @return Zero on success or (negative) error code on failure.
1224+
* @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection.
1225+
*/
1226+
int bt_conn_le_read_all_remote_features(struct bt_conn *conn, uint8_t pages_requested);
1227+
11891228
/** @brief Update the connection parameters.
11901229
*
11911230
* If the local device is in the peripheral role then updating the connection
@@ -1877,6 +1916,25 @@ struct bt_conn_cb {
18771916
const struct bt_conn_le_subrate_changed *params);
18781917
#endif /* CONFIG_BT_SUBRATING */
18791918

1919+
#if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET)
1920+
/** @brief Read all remote features complete event.
1921+
*
1922+
* This callback notifies the application that a 'read all remote
1923+
* features' procedure of the connection is completed. The other params
1924+
* will not be populated if status is not @ref BT_HCI_ERR_SUCCESS.
1925+
*
1926+
* This callback can be triggered by calling @ref
1927+
* bt_conn_le_read_all_remote_features or by the procedure running
1928+
* autonomously in the controller.
1929+
*
1930+
* @param conn Connection object.
1931+
* @param params Remote features.
1932+
*/
1933+
void (*read_all_remote_feat_complete)(
1934+
struct bt_conn *conn,
1935+
const struct bt_conn_le_read_all_remote_feat_complete *params);
1936+
#endif /* CONFIG_BT_LE_EXTENDED_FEAT_SET */
1937+
18801938
#if defined(CONFIG_BT_CHANNEL_SOUNDING)
18811939
/** @brief LE CS Read Remote Supported Capabilities Complete event.
18821940
*

include/zephyr/bluetooth/hci_types.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ struct bt_hci_cmd_hdr {
207207
#define BT_LE_FEAT_BIT_CHANNEL_SOUNDING 46
208208
#define BT_LE_FEAT_BIT_CHANNEL_SOUNDING_HOST 47
209209
#define BT_LE_FEAT_BIT_CHANNEL_SOUNDING_TONE_QUAL_IND 48
210-
#define BT_LE_FEAT_BIT_LL_EXTENDED_FEAT_SET 63
210+
#define BT_LE_FEAT_BIT_EXTENDED_FEAT_SET 63
211211

212212
#define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \
213213
BIT((n) & 7))
@@ -284,6 +284,8 @@ struct bt_hci_cmd_hdr {
284284
BT_LE_FEAT_BIT_CHANNEL_SOUNDING)
285285
#define BT_FEAT_LE_CHANNEL_SOUNDING_HOST(feat) BT_LE_FEAT_TEST(feat, \
286286
BT_LE_FEAT_BIT_CHANNEL_SOUNDING_HOST)
287+
#define BT_FEAT_LE_EXTENDED_FEAT_SET(feat) BT_LE_FEAT_TEST(feat, \
288+
BT_LE_FEAT_BIT_EXTENDED_FEAT_SET)
287289

288290
#define BT_FEAT_LE_CIS(feat) (BT_FEAT_LE_CIS_CENTRAL(feat) | \
289291
BT_FEAT_LE_CIS_PERIPHERAL(feat))
@@ -2438,6 +2440,22 @@ struct bt_hci_cp_le_tx_test_v4 {
24382440
uint8_t ant_ids[0];
24392441
} __packed;
24402442

2443+
#define BT_HCI_OP_LE_READ_ALL_LOCAL_SUPPORTED_FEATURES BT_OP(BT_OGF_LE, 0x0087) /* 0x2087 */
2444+
struct bt_hci_rp_le_read_all_local_supported_features {
2445+
uint8_t status;
2446+
uint8_t max_page;
2447+
uint8_t features[248];
2448+
} __packed;
2449+
2450+
#define BT_READ_ALL_LOCAL_FEATURES_SUPPORTED(supported_commands) \
2451+
BT_CMD_TEST(supported_commands, 47, 2)
2452+
2453+
#define BT_HCI_OP_LE_READ_ALL_REMOTE_FEATURES BT_OP(BT_OGF_LE, 0x0088) /* 0x2088 */
2454+
struct bt_hci_cp_le_read_all_remote_features {
2455+
uint16_t handle;
2456+
uint8_t pages_requested;
2457+
} __packed;
2458+
24412459
#define BT_HCI_TX_TEST_POWER_MIN -0x7F
24422460
#define BT_HCI_TX_TEST_POWER_MAX 0x14
24432461

@@ -3552,6 +3570,20 @@ struct bt_hci_evt_le_cis_established_v2 {
35523570
uint8_t framing;
35533571
} __packed;
35543572

3573+
#define BT_HCI_EVT_LE_READ_ALL_REMOTE_FEAT_COMPLETE 0x2b
3574+
3575+
#define BT_HCI_LE_FEATURE_PAGE_MAX 10
3576+
#define BT_HCI_LE_BYTES_PER_FEATURE_PAGE 24
3577+
#define BT_HCI_LE_BYTES_PAGE_0_FEATURE_PAGE 8
3578+
3579+
struct bt_hci_evt_le_read_all_remote_feat_complete {
3580+
uint8_t status;
3581+
uint16_t handle;
3582+
uint8_t max_remote_page;
3583+
uint8_t max_valid_page;
3584+
uint8_t features[248];
3585+
} __packed;
3586+
35553587
#define BT_HCI_LE_CS_INITIATOR_ROLE_MASK BIT(0)
35563588
#define BT_HCI_LE_CS_REFLECTOR_ROLE_MASK BIT(1)
35573589

@@ -4024,6 +4056,8 @@ struct bt_hci_evt_le_cs_procedure_enable_complete {
40244056
#define BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2 BT_EVT_BIT(40)
40254057
#define BT_EVT_MASK_LE_CIS_ESTABLISHED_V2 BT_EVT_BIT(41)
40264058

4059+
#define BT_EVT_MASK_LE_READ_ALL_REMOTE_FEAT_COMPLETE BT_EVT_BIT(42)
4060+
40274061
#define BT_EVT_MASK_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE BT_EVT_BIT(43)
40284062
#define BT_EVT_MASK_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE BT_EVT_BIT(44)
40294063
#define BT_EVT_MASK_LE_CS_SECURITY_ENABLE_COMPLETE BT_EVT_BIT(45)

subsys/bluetooth/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,21 @@ config BT_CONN_TX
115115
help
116116
Hidden configuration that is true if ACL or broadcast ISO is enabled
117117

118+
config BT_LE_MAX_LOCAL_SUPPORTED_FEATURE_PAGE
119+
int "Maximum supported feature page"
120+
default 0
121+
range 0 10
122+
depends on BT_LE_EXTENDED_FEAT_SET
123+
help
124+
Maximum supported feature page that can be stored locally and fetched
125+
from the remote connection with the LL Extended Feature Set feature.
126+
127+
config BT_LE_EXTENDED_FEAT_SET
128+
bool "LL Extended Feature Set"
129+
depends on !HAS_BT_CTLR || BT_CTLR_EXTENDED_FEAT_SET_SUPPORT
130+
help
131+
Enable support for the LL Extended Feature Set feature.
132+
118133
if BT_CONN
119134
config BT_HCI_ACL_FLOW_CONTROL
120135
bool "Controller to Host ACL flow control support"

subsys/bluetooth/common/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ config BT_BUF_ACL_RX_COUNT
119119

120120
config BT_BUF_EVT_RX_SIZE
121121
int "Maximum supported HCI Event buffer length"
122-
default $(UINT8_MAX) if (BT_EXT_ADV && BT_OBSERVER) || BT_PER_ADV_SYNC || BT_DF_CONNECTION_CTE_RX || BT_CLASSIC || BT_CHANNEL_SOUNDING
122+
default $(UINT8_MAX) if (BT_EXT_ADV && BT_OBSERVER) || BT_PER_ADV_SYNC || BT_DF_CONNECTION_CTE_RX || BT_CLASSIC || BT_CHANNEL_SOUNDING || BT_LE_EXTENDED_FEAT_SET
123123
# LE Read Supported Commands command complete event.
124124
default 68
125125
range 68 $(UINT8_MAX)

subsys/bluetooth/controller/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ config BT_CTLR_SUBRATING_SUPPORT
128128
config BT_CTLR_CHANNEL_SOUNDING_SUPPORT
129129
bool
130130

131+
config BT_CTLR_EXTENDED_FEAT_SET_SUPPORT
132+
bool
133+
131134
# Virtual option that all local LL implementations should select
132135
config HAS_BT_CTLR
133136
bool
@@ -1174,6 +1177,14 @@ config BT_CTLR_CHANNEL_SOUNDING
11741177
Enable support for Bluetooth 6.0 Channel Sounding in the
11751178
Controller.
11761179

1180+
config BT_CTLR_EXTENDED_FEAT_SET
1181+
bool "LL Extended Feature Set support"
1182+
depends on BT_CTLR_EXTENDED_FEAT_SET_SUPPORT
1183+
default y if BT_LE_EXTENDED_FEAT_SET
1184+
help
1185+
Enable support for Bluetooth 6.0 LL Extended Feature Set
1186+
in the Controller.
1187+
11771188
rsource "Kconfig.df"
11781189
rsource "Kconfig.ll_sw_split"
11791190
rsource "Kconfig.dtm"

subsys/bluetooth/host/conn.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3289,6 +3289,53 @@ int bt_conn_le_subrate_request(struct bt_conn *conn,
32893289
}
32903290
#endif /* CONFIG_BT_SUBRATING */
32913291

3292+
#if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET)
3293+
void notify_read_all_remote_feat_complete(struct bt_conn *conn,
3294+
struct bt_conn_le_read_all_remote_feat_complete *params)
3295+
{
3296+
struct bt_conn_cb *callback;
3297+
3298+
SYS_SLIST_FOR_EACH_CONTAINER(&conn_cbs, callback, _node) {
3299+
if (callback->read_all_remote_feat_complete != NULL) {
3300+
callback->read_all_remote_feat_complete(conn, params);
3301+
}
3302+
}
3303+
3304+
STRUCT_SECTION_FOREACH(bt_conn_cb, cb)
3305+
{
3306+
if (cb->read_all_remote_feat_complete != NULL) {
3307+
cb->read_all_remote_feat_complete(conn, params);
3308+
}
3309+
}
3310+
}
3311+
3312+
int bt_conn_le_read_all_remote_features(struct bt_conn *conn, uint8_t pages_requested)
3313+
{
3314+
struct bt_hci_cp_le_read_all_remote_features *cp;
3315+
struct net_buf *buf;
3316+
3317+
if (!bt_conn_is_type(conn, BT_CONN_TYPE_LE)) {
3318+
LOG_DBG("Invalid connection type: %u for %p", conn->type, conn);
3319+
return -EINVAL;
3320+
}
3321+
3322+
if (pages_requested > BT_HCI_LE_FEATURE_PAGE_MAX) {
3323+
return -EINVAL;
3324+
}
3325+
3326+
buf = bt_hci_cmd_alloc(K_FOREVER);
3327+
if (buf == NULL) {
3328+
return -ENOBUFS;
3329+
}
3330+
3331+
cp = net_buf_add(buf, sizeof(*cp));
3332+
cp->handle = sys_cpu_to_le16(conn->handle);
3333+
cp->pages_requested = pages_requested;
3334+
3335+
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_ALL_REMOTE_FEATURES, buf, NULL);
3336+
}
3337+
#endif /* CONFIG_BT_LE_EXTENDED_FEAT_SET */
3338+
32923339
#if defined(CONFIG_BT_CHANNEL_SOUNDING)
32933340
void notify_remote_cs_capabilities(struct bt_conn *conn, uint8_t status,
32943341
struct bt_conn_le_cs_capabilities *params)

subsys/bluetooth/host/conn_internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,9 @@ void notify_path_loss_threshold_report(struct bt_conn *conn,
512512
void notify_subrate_change(struct bt_conn *conn,
513513
struct bt_conn_le_subrate_changed params);
514514

515+
void notify_read_all_remote_feat_complete(struct bt_conn *conn,
516+
struct bt_conn_le_read_all_remote_feat_complete *params);
517+
515518
void notify_remote_cs_capabilities(struct bt_conn *conn,
516519
uint8_t status,
517520
struct bt_conn_le_cs_capabilities *params);

0 commit comments

Comments
 (0)