Bluetooth: controller: Only generate ntf on host initiated feature exch

Only generate notification when feature exchange was initiated by host

Signed-off-by: Erik Brockhoff <erbr@oticon.com>
This commit is contained in:
Erik Brockhoff 2023-05-09 14:29:34 +02:00 committed by Alberto Escolar
parent c1b5aaecf8
commit 105621bdce
6 changed files with 45 additions and 34 deletions

View file

@ -447,7 +447,7 @@ uint8_t ll_feature_req_send(uint16_t handle)
uint8_t err;
err = ull_cp_feature_exchange(conn);
err = ull_cp_feature_exchange(conn, 1U);
if (err) {
return err;
}

View file

@ -701,7 +701,7 @@ uint8_t ull_cp_le_ping(struct ll_conn *conn)
#endif /* CONFIG_BT_CTLR_LE_PING */
#if defined(CONFIG_BT_CENTRAL) || defined(CONFIG_BT_CTLR_PER_INIT_FEAT_XCHG)
uint8_t ull_cp_feature_exchange(struct ll_conn *conn)
uint8_t ull_cp_feature_exchange(struct ll_conn *conn, uint8_t host_initiated)
{
struct proc_ctx *ctx;
@ -710,6 +710,8 @@ uint8_t ull_cp_feature_exchange(struct ll_conn *conn)
return BT_HCI_ERR_CMD_DISALLOWED;
}
ctx->data.fex.host_initiated = host_initiated;
llcp_lr_enqueue(conn, ctx);
return BT_HCI_ERR_SUCCESS;

View file

@ -85,7 +85,7 @@ uint8_t ull_cp_version_exchange(struct ll_conn *conn);
/**
* @brief Initiate a Feature Exchange Procedure.
*/
uint8_t ull_cp_feature_exchange(struct ll_conn *conn);
uint8_t ull_cp_feature_exchange(struct ll_conn *conn, uint8_t host_initiated);
#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
/**

View file

@ -427,23 +427,6 @@ static void lp_comm_terminate_invalid_pdu(struct ll_conn *conn, struct proc_ctx
ctx->state = LP_COMMON_STATE_IDLE;
}
static void lp_comm_ntf_complete_proxy(struct ll_conn *conn, struct proc_ctx *ctx,
const bool valid_pdu)
{
if (valid_pdu) {
if (!llcp_ntf_alloc_is_available()) {
ctx->state = LP_COMMON_STATE_WAIT_NTF;
} else {
lp_comm_ntf(conn, ctx);
llcp_lr_complete(conn);
ctx->state = LP_COMMON_STATE_IDLE;
}
} else {
/* Illegal response opcode */
lp_comm_terminate_invalid_pdu(conn, ctx);
}
}
static void lp_comm_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
{
switch (ctx->proc) {
@ -460,9 +443,21 @@ static void lp_comm_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
break;
#endif /* CONFIG_BT_CTLR_LE_PING */
case PROC_FEATURE_EXCHANGE:
lp_comm_ntf_complete_proxy(conn, ctx,
(ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP ||
ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_FEATURE_RSP));
if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP ||
ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_FEATURE_RSP) {
if (ctx->data.fex.host_initiated) {
if (!llcp_ntf_alloc_is_available()) {
ctx->state = LP_COMMON_STATE_WAIT_NTF;
break;
}
lp_comm_ntf(conn, ctx);
}
llcp_lr_complete(conn);
ctx->state = LP_COMMON_STATE_IDLE;
} else {
/* Illegal response opcode */
lp_comm_terminate_invalid_pdu(conn, ctx);
}
break;
#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN) && defined(CONFIG_BT_PERIPHERAL)
case PROC_MIN_USED_CHANS:
@ -471,8 +466,18 @@ static void lp_comm_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
break;
#endif /* CONFIG_BT_CTLR_MIN_USED_CHAN && CONFIG_BT_PERIPHERAL */
case PROC_VERSION_EXCHANGE:
lp_comm_ntf_complete_proxy(conn, ctx,
(ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_VERSION_IND));
if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_VERSION_IND) {
if (!llcp_ntf_alloc_is_available()) {
ctx->state = LP_COMMON_STATE_WAIT_NTF;
} else {
lp_comm_ntf(conn, ctx);
llcp_lr_complete(conn);
ctx->state = LP_COMMON_STATE_IDLE;
}
} else {
/* Illegal response opcode */
lp_comm_terminate_invalid_pdu(conn, ctx);
}
break;
case PROC_TERMINATE:
/* No notification */

View file

@ -167,6 +167,10 @@ struct proc_ctx {
/* Procedure data */
union {
/* Feature Exchange Procedure */
struct {
uint8_t host_initiated:1;
} fex;
/* Used by Minimum Used Channels Procedure */
#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
struct {

View file

@ -110,7 +110,7 @@ ZTEST(fex_central, test_feat_exchange_central_loc)
ull_cp_state_set(&conn, ULL_CP_CONNECTED);
/* Initiate a Feature Exchange Procedure */
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
zassert_equal(err, BT_HCI_ERR_SUCCESS);
event_prepare(&conn);
@ -140,7 +140,7 @@ ZTEST(fex_central, test_feat_exchange_central_loc)
sys_put_le64(set_featureset[0], local_feature_req.features);
/* Initiate a Feature Exchange Procedure */
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
zassert_equal(err, BT_HCI_ERR_SUCCESS);
event_prepare(&conn);
@ -209,7 +209,7 @@ ZTEST(fex_central, test_feat_exchange_central_loc_invalid_rsp)
ull_cp_state_set(&conn, ULL_CP_CONNECTED);
/* Initiate a Feature Exchange Procedure */
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
zassert_equal(err, BT_HCI_ERR_SUCCESS);
event_prepare(&conn);
@ -243,7 +243,7 @@ ZTEST(fex_central, test_feat_exchange_central_loc_invalid_rsp)
ull_cp_state_set(&conn, ULL_CP_CONNECTED);
/* Initiate another Feature Exchange Procedure */
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
zassert_equal(err, BT_HCI_ERR_SUCCESS);
event_prepare(&conn);
@ -277,10 +277,10 @@ ZTEST(fex_central, test_feat_exchange_central_loc_2)
test_set_role(&conn, BT_HCI_ROLE_CENTRAL);
ull_cp_state_set(&conn, ULL_CP_CONNECTED);
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
for (int i = 0U; i < CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM; i++) {
zassert_equal(err, BT_HCI_ERR_SUCCESS);
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
}
zassert_not_equal(err, BT_HCI_ERR_SUCCESS, NULL);
@ -405,7 +405,7 @@ ZTEST(fex_central, test_feat_exchange_central_rem_2)
sys_put_le64(ut_featureset[feat_count], ut_feature_req.features);
sys_put_le64(ut_exp_featureset[feat_count], ut_feature_rsp.features);
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
zassert_equal(err, BT_HCI_ERR_SUCCESS);
event_prepare(&conn);
@ -468,7 +468,7 @@ ZTEST(fex_periph, test_peripheral_feat_exchange_periph_loc)
}
/* Initiate a Feature Exchange Procedure */
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
zassert_equal(err, BT_HCI_ERR_SUCCESS);
event_prepare(&conn);
@ -529,7 +529,7 @@ ZTEST(fex_periph, test_feat_exchange_periph_loc_unknown_rsp)
/* Initiate a Feature Exchange Procedure */
event_prepare(&conn);
err = ull_cp_feature_exchange(&conn);
err = ull_cp_feature_exchange(&conn, 1U);
zassert_equal(err, BT_HCI_ERR_SUCCESS);
event_done(&conn);