Skip to content

Commit d1b017d

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 d1b017d

File tree

11 files changed

+322
-14
lines changed

11 files changed

+322
-14
lines changed

include/zephyr/bluetooth/bluetooth.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,16 @@ 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+
(BT_HCI_LE_BYTES_PAGE_0_FEATURE_PAGE + \
81+
COND_CODE_1(CONFIG_BT_LE_MAX_LOCAL_SUPPORTED_FEATURE_PAGE, \
82+
CONFIG_BT_LE_MAX_LOCAL_SUPPORTED_FEATURE_PAGE * BT_HCI_LE_BYTES_PER_FEATURE_PAGE, \
83+
(0U)))
7984

8085
/** Opaque type representing an advertiser. */
8186
struct bt_le_ext_adv;
@@ -611,11 +616,12 @@ struct bt_le_local_features {
611616
/**
612617
* @brief Local LE controller supported features.
613618
*
619+
* Pointer to array of size BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE.
614620
* Refer to BT_LE_FEAT_BIT_* for values.
615-
* Refer to the BT_FEAT_LE_* macros for value comparionson.
621+
* Refer to the BT_FEAT_LE_* macros for value comparison.
616622
* See Bluetooth Core Specification, Vol 6, Part B, Section 4.6.
617623
*/
618-
uint8_t features[BT_LE_LOCAL_SUPPORTED_FEATURES_SIZE];
624+
const uint8_t *features;
619625

620626
/**
621627
* @brief Local LE controller supported states

include/zephyr/bluetooth/conn.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,26 @@ 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 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+
* Page 0 being 8 bytes, with the following 10 pages of 24 bytes.
268+
* Refer to BT_LE_FEAT_BIT_* for values.
269+
* Refer to the BT_FEAT_LE_* macros for value comparison.
270+
* See Bluetooth Core Specification, Vol 6, Part B, Section 4.6.
271+
*/
272+
uint8_t *features;
273+
};
274+
255275
/** Connection Type */
256276
enum __packed bt_conn_type {
257277
/** LE Connection Type */
@@ -1186,6 +1206,22 @@ int bt_conn_le_subrate_set_defaults(const struct bt_conn_le_subrate_param *param
11861206
int bt_conn_le_subrate_request(struct bt_conn *conn,
11871207
const struct bt_conn_le_subrate_param *params);
11881208

1209+
/** @brief Read remote feature pages.
1210+
*
1211+
* Request remote feature pages, from 0 up to pages_requested or the number
1212+
* of pages supported by the peer. There is a maximum of 10 pages.
1213+
*
1214+
* @kconfig_dep{CONFIG_BT_LE_EXTENDED_FEAT_SET}
1215+
*
1216+
* @param conn @ref BT_CONN_TYPE_LE connection object.
1217+
* @param pages_requested Number of feature pages to be requested from peer.
1218+
* There is a maximum of 10 pages.
1219+
*
1220+
* @return Zero on success or (negative) error code on failure.
1221+
* @return -EINVAL @p conn is not a valid @ref BT_CONN_TYPE_LE connection.
1222+
*/
1223+
int bt_conn_le_read_all_remote_features(struct bt_conn *conn, uint8_t pages_requested);
1224+
11891225
/** @brief Update the connection parameters.
11901226
*
11911227
* If the local device is in the peripheral role then updating the connection
@@ -1877,6 +1913,21 @@ struct bt_conn_cb {
18771913
const struct bt_conn_le_subrate_changed *params);
18781914
#endif /* CONFIG_BT_SUBRATING */
18791915

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

include/zephyr/bluetooth/hci_types.h

Lines changed: 33 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,20 @@ 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+
#define BT_HCI_LE_BYTES_PAGE_0_FEATURE_PAGE 8
3576+
3577+
struct bt_hci_evt_le_read_all_remote_feat_complete {
3578+
uint8_t status;
3579+
uint16_t handle;
3580+
uint8_t max_remote_page;
3581+
uint8_t max_valid_page;
3582+
uint8_t features[248];
3583+
} __packed;
3584+
35553585
#define BT_HCI_LE_CS_INITIATOR_ROLE_MASK BIT(0)
35563586
#define BT_HCI_LE_CS_REFLECTOR_ROLE_MASK BIT(1)
35573587

@@ -4024,6 +4054,8 @@ struct bt_hci_evt_le_cs_procedure_enable_complete {
40244054
#define BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2 BT_EVT_BIT(40)
40254055
#define BT_EVT_MASK_LE_CIS_ESTABLISHED_V2 BT_EVT_BIT(41)
40264056

4057+
#define BT_EVT_MASK_LE_READ_ALL_REMOTE_FEAT_COMPLETE BT_EVT_BIT(42)
4058+
40274059
#define BT_EVT_MASK_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE BT_EVT_BIT(43)
40284060
#define BT_EVT_MASK_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE BT_EVT_BIT(44)
40294061
#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)