Bluetooth: controller: consider host ctrl feature bits in feat exchange

Host controlled feature bits were not considered in feature exchange
procedure. This is fixed.

Signed-off-by: Erik Brockhoff <erbr@oticon.com>
This commit is contained in:
Erik Brockhoff 2022-12-15 09:55:37 +01:00 committed by Carles Cufí
commit 2f61771948
5 changed files with 41 additions and 6 deletions

View file

@ -529,7 +529,7 @@ void ull_llcp_init(struct ll_conn *conn)
/* Reset the feature exchange fields */ /* Reset the feature exchange fields */
memset(&conn->llcp.fex, 0, sizeof(conn->llcp.fex)); memset(&conn->llcp.fex, 0, sizeof(conn->llcp.fex));
conn->llcp.fex.features_used = LL_FEAT; conn->llcp.fex.features_used = ll_feat_get();
#if defined(CONFIG_BT_CTLR_LE_ENC) #if defined(CONFIG_BT_CTLR_LE_ENC)
/* Reset encryption related state */ /* Reset encryption related state */

View file

@ -133,13 +133,13 @@ void llcp_pdu_encode_feature_req(struct ll_conn *conn, struct pdu_data *pdu)
#endif /* CONFIG_BT_CTLR_PER_INIT_FEAT_XCHG && CONFIG_BT_PERIPHERAL */ #endif /* CONFIG_BT_CTLR_PER_INIT_FEAT_XCHG && CONFIG_BT_PERIPHERAL */
p = &pdu->llctrl.feature_req; p = &pdu->llctrl.feature_req;
sys_put_le64(LL_FEAT, p->features); sys_put_le64(ll_feat_get(), p->features);
} }
void llcp_pdu_encode_feature_rsp(struct ll_conn *conn, struct pdu_data *pdu) void llcp_pdu_encode_feature_rsp(struct ll_conn *conn, struct pdu_data *pdu)
{ {
struct pdu_data_llctrl_feature_rsp *p; struct pdu_data_llctrl_feature_rsp *p;
uint64_t feature_rsp = LL_FEAT; uint64_t feature_rsp = ll_feat_get();
pdu->ll_id = PDU_DATA_LLID_CTRL; pdu->ll_id = PDU_DATA_LLID_CTRL;
pdu->len = PDU_DATA_LLCTRL_LEN(feature_rsp); pdu->len = PDU_DATA_LLCTRL_LEN(feature_rsp);
@ -173,7 +173,7 @@ void llcp_pdu_decode_feature_req(struct ll_conn *conn, struct pdu_data *pdu)
uint64_t featureset; uint64_t featureset;
feature_filter(pdu->llctrl.feature_req.features, &featureset); feature_filter(pdu->llctrl.feature_req.features, &featureset);
conn->llcp.fex.features_used = LL_FEAT & featureset; conn->llcp.fex.features_used = ll_feat_get() & featureset;
featureset &= (FEAT_FILT_OCTET0 | conn->llcp.fex.features_used); featureset &= (FEAT_FILT_OCTET0 | conn->llcp.fex.features_used);
conn->llcp.fex.features_peer = featureset; conn->llcp.fex.features_peer = featureset;
@ -186,7 +186,7 @@ void llcp_pdu_decode_feature_rsp(struct ll_conn *conn, struct pdu_data *pdu)
uint64_t featureset; uint64_t featureset;
feature_filter(pdu->llctrl.feature_rsp.features, &featureset); feature_filter(pdu->llctrl.feature_rsp.features, &featureset);
conn->llcp.fex.features_used = LL_FEAT & featureset; conn->llcp.fex.features_used = ll_feat_get() & featureset;
conn->llcp.fex.features_peer = featureset; conn->llcp.fex.features_peer = featureset;
conn->llcp.fex.valid = 1; conn->llcp.fex.valid = 1;

View file

@ -33,6 +33,7 @@ FILE(GLOB ll_sw_sources
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp.c ${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_llcp.c
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_conn.c ${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ull_conn.c
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ll_addr.c ${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ll_addr.c
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/ll_feat.c
) )
FILE(GLOB mock_sources FILE(GLOB mock_sources

View file

@ -130,7 +130,40 @@ void test_feat_exchange_central_loc(void)
ull_cp_release_tx(&conn, tx); ull_cp_release_tx(&conn, tx);
ull_cp_release_ntf(ntf); ull_cp_release_ntf(ntf);
} }
zassert_equal(conn.lll.event_counter, feat_to_test, "Wrong event-count %d\n",
/* Test that host enabled feature makes it into feature exchange */
ll_set_host_feature(BT_LE_FEAT_BIT_ISO_CHANNELS, 1);
/* Add host feature bit to expected features bit mask */
set_featureset[0] |= BIT64(BT_LE_FEAT_BIT_ISO_CHANNELS);
sys_put_le64(set_featureset[0], local_feature_req.features);
/* Initiate a Feature Exchange Procedure */
err = ull_cp_feature_exchange(&conn);
zassert_equal(err, BT_HCI_ERR_SUCCESS);
event_prepare(&conn);
/* Tx Queue should have one LL Control PDU */
lt_rx(LL_FEATURE_REQ, &conn, &tx, &local_feature_req);
lt_rx_q_is_empty(&conn);
/* Rx */
lt_tx(LL_FEATURE_RSP, &conn, &remote_feature_rsp);
event_done(&conn);
/* There should be one host notification */
ut_rx_pdu(LL_FEATURE_RSP, &ntf, &exp_remote_feature_rsp);
ut_rx_q_is_empty();
ull_cp_release_tx(&conn, tx);
ull_cp_release_ntf(ntf);
/* Remove host feature bit again */
ll_set_host_feature(BT_LE_FEAT_BIT_ISO_CHANNELS, 0);
zassert_equal(conn.lll.event_counter, feat_to_test + 1, "Wrong event-count %d\n",
conn.lll.event_counter); conn.lll.event_counter);
zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(), zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(),
"Free CTX buffers %d", ctx_buffers_free()); "Free CTX buffers %d", ctx_buffers_free());

View file

@ -182,3 +182,4 @@
#define CONFIG_BT_BUF_ACL_TX_COUNT 7 #define CONFIG_BT_BUF_ACL_TX_COUNT 7
#define CONFIG_BT_BUF_ACL_TX_SIZE 251 #define CONFIG_BT_BUF_ACL_TX_SIZE 251
#define CONFIG_BT_CTLR_RX_BUFFERS 7 #define CONFIG_BT_CTLR_RX_BUFFERS 7
#define CONFIG_BT_CTLR_SET_HOST_FEATURE 1