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:
parent
c1b5aaecf8
commit
105621bdce
6 changed files with 45 additions and 34 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue