Skip to content

Commit 963e407

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 963e407

File tree

11 files changed

+319
-13
lines changed

11 files changed

+319
-13
lines changed

include/zephyr/bluetooth/bluetooth.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,15 @@ extern "C" {
7171
#define BT_ID_DEFAULT 0
7272

7373
/**
74-
* @brief Number of octets for local supported
74+
* @brief Number of octets for local supported features
7575
*
76-
* The value of 8 correspond to page 0 in the LE Controller supported features
76+
* The value of 8 correspond to page 0 in the LE Controller supported features.
77+
* 24 bytes are required for all subsequent supported feature pages.
7778
*/
78-
#define BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE 8
79+
#define BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE \
80+
(8U + COND_CODE_1(CONFIG_BT_LE_MAX_LOCAL_SUPPORTED_FEATURE_PAGE, \
81+
CONFIG_BT_LE_MAX_LOCAL_SUPPORTED_FEATURE_PAGE * BT_HCI_LE_BYTES_PER_FEATURE_PAGE, \
82+
(0U)))
7983

8084
/** Opaque type representing an advertiser. */
8185
struct bt_le_ext_adv;
@@ -611,11 +615,12 @@ struct bt_le_local_features {
611615
/**
612616
* @brief Local LE controller supported features.
613617
*
618+
* Pointer to array of size BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE.
614619
* Refer to BT_LE_FEAT_BIT_* for values.
615620
* Refer to the BT_FEAT_LE_* macros for value comparionson.
616621
* See Bluetooth Core Specification, Vol 6, Part B, Section 4.6.
617622
*/
618-
uint8_t features[BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE];
623+
uint8_t *features;
619624

620625
/**
621626
* @brief Local LE controller supported states

include/zephyr/bluetooth/conn.h

Lines changed: 52 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+
/** HCI Status from LE Read All Remote Features Complete event.
258+
* The remaining parameters will be unchanged if status is not
259+
* 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+
/** Pointer to array of size 248, with feature bits of remote
267+
* supported features. Page 0 being 8 bytes, with the following
268+
* 10 pages of 24 bytes.
269+
* Refer to BT_LE_FEAT_BIT_* for values.
270+
* Refer to the BT_FEAT_LE_* macros for value comparionson.
271+
* See Bluetooth Core Specification, Vol 6, Part B, Section 4.6.
272+
*/
273+
uint8_t *features;
274+
};
275+
255276
/** Connection Type */
256277
enum __packed bt_conn_type {
257278
/** LE Connection Type */
@@ -1186,6 +1207,22 @@ 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+
*
1215+
* @note To use this API @kconfig{CONFIG_BT_LE_EXTENDED_FEAT_SET} must be set.
1216+
*
1217+
* @param conn @ref BT_CONN_TYPE_LE connection object.
1218+
* @param pages_requested Number of feature pages to be requested from peer.
1219+
* There is a maximum of 10 pages.
1220+
*
1221+
* @return Zero on success or (negative) error code on failure.
1222+
* @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection.
1223+
*/
1224+
int bt_conn_le_read_all_remote_features(struct bt_conn *conn, uint8_t pages_requested);
1225+
11891226
/** @brief Update the connection parameters.
11901227
*
11911228
* If the local device is in the peripheral role then updating the connection
@@ -1877,6 +1914,21 @@ struct bt_conn_cb {
18771914
const struct bt_conn_le_subrate_changed *params);
18781915
#endif /* CONFIG_BT_SUBRATING */
18791916

1917+
#if defined(CONFIG_BT_LE_EXTENDED_FEAT_SET)
1918+
/** @brief Read all remote features complete event.
1919+
*
1920+
* This callback notifies the application that read all remote features
1921+
* procedure of the connection is complete.
1922+
* The other params will not be populated if status is not BT_HCI_ERR_SUCCESS.
1923+
*
1924+
* @param conn Connection object.
1925+
* @param params Remote features.
1926+
*/
1927+
void (*read_all_remote_feat_complete)(
1928+
struct bt_conn *conn,
1929+
const struct bt_conn_le_read_all_remote_feat_complete *params);
1930+
#endif /* CONFIG_BT_LE_EXTENDED_FEAT_SET */
1931+
18801932
#if defined(CONFIG_BT_CHANNEL_SOUNDING)
18811933
/** @brief LE CS Read Remote Supported Capabilities Complete event.
18821934
*

include/zephyr/bluetooth/hci_types.h

Lines changed: 32 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,20 @@ 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+
2451+
#define BT_HCI_OP_LE_READ_ALL_REMOTE_FEATURES BT_OP(BT_OGF_LE, 0x0088) /* 0x2088 */
2452+
struct bt_hci_cp_le_read_all_remote_features {
2453+
uint16_t handle;
2454+
uint8_t pages_requested;
2455+
} __packed;
2456+
24412457
#define BT_HCI_TX_TEST_POWER_MIN -0x7F
24422458
#define BT_HCI_TX_TEST_POWER_MAX 0x14
24432459

@@ -3552,6 +3568,19 @@ struct bt_hci_evt_le_cis_established_v2 {
35523568
uint8_t framing;
35533569
} __packed;
35543570

3571+
#define BT_HCI_EVT_LE_READ_ALL_REMOTE_FEAT_COMPLETE 0x2b
3572+
3573+
#define BT_HCI_LE_FEATURE_PAGE_MAX 10
3574+
#define BT_HCI_LE_BYTES_PER_FEATURE_PAGE 24
3575+
3576+
struct bt_hci_evt_le_read_all_remote_feat_complete {
3577+
uint8_t status;
3578+
uint16_t handle;
3579+
uint8_t max_remote_page;
3580+
uint8_t max_valid_page;
3581+
uint8_t features[248];
3582+
} __packed;
3583+
35553584
#define BT_HCI_LE_CS_INITIATOR_ROLE_MASK BIT(0)
35563585
#define BT_HCI_LE_CS_REFLECTOR_ROLE_MASK BIT(1)
35573586

@@ -4024,6 +4053,8 @@ struct bt_hci_evt_le_cs_procedure_enable_complete {
40244053
#define BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2 BT_EVT_BIT(40)
40254054
#define BT_EVT_MASK_LE_CIS_ESTABLISHED_V2 BT_EVT_BIT(41)
40264055

4056+
#define BT_EVT_MASK_LE_READ_ALL_REMOTE_FEAT_COMPLETE BT_EVT_BIT(42)
4057+
40274058
#define BT_EVT_MASK_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE BT_EVT_BIT(43)
40284059
#define BT_EVT_MASK_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE BT_EVT_BIT(44)
40294060
#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) {
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) {
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_MAX_FEATURE_PAGE) {
3323+
return -EINVAL;
3324+
}
3325+
3326+
buf = bt_hci_cmd_alloc(K_FOREVER);
3327+
if (!buf) {
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)