Bluetooth: Controller: Add CTE REQ disable when change PHY to CODED
Accodring to BT 5.3 Core Vol 4, Part E section 7.8.85 the CTE request procedure has to be disabled as if Host issued the HCI_LE_Connection- CTE_Request_Enable with enable property set to 0. It means a Controller should automaticall disable the procedure. There were no handling of this part of specification. Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
9603e103b9
commit
dbf86b0359
3 changed files with 72 additions and 20 deletions
|
@ -1654,9 +1654,24 @@ void ull_conn_done(struct node_rx_event_done *done)
|
||||||
if (conn->llcp.cte_req.req_expire > elapsed_event) {
|
if (conn->llcp.cte_req.req_expire > elapsed_event) {
|
||||||
conn->llcp.cte_req.req_expire -= elapsed_event;
|
conn->llcp.cte_req.req_expire -= elapsed_event;
|
||||||
} else {
|
} else {
|
||||||
|
uint8_t err;
|
||||||
|
|
||||||
conn->llcp.cte_req.req_expire = 0U;
|
conn->llcp.cte_req.req_expire = 0U;
|
||||||
ull_cp_cte_req(conn, conn->llcp.cte_req.min_cte_len,
|
|
||||||
conn->llcp.cte_req.cte_type);
|
err = ull_cp_cte_req(conn, conn->llcp.cte_req.min_cte_len,
|
||||||
|
conn->llcp.cte_req.cte_type);
|
||||||
|
|
||||||
|
if (err == BT_HCI_ERR_CMD_DISALLOWED) {
|
||||||
|
/* Conditions has changed e.g. PHY was changed to CODED.
|
||||||
|
* New CTE REQ is not possible. Disable the periodic requests.
|
||||||
|
*
|
||||||
|
* If the CTE REQ is in active state, let it complete and disable
|
||||||
|
* in regular control procedure way.
|
||||||
|
*/
|
||||||
|
if (!conn->llcp.cte_req.is_active) {
|
||||||
|
ull_cp_cte_req_set_disable(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
||||||
|
|
|
@ -903,19 +903,30 @@ uint8_t ull_cp_cte_req(struct ll_conn *conn, uint8_t min_cte_len, uint8_t cte_ty
|
||||||
{
|
{
|
||||||
struct proc_ctx *ctx;
|
struct proc_ctx *ctx;
|
||||||
|
|
||||||
ctx = llcp_create_local_procedure(PROC_CTE_REQ);
|
/* The request may be started by periodic CTE request procedure, so it skips earlier
|
||||||
if (!ctx) {
|
* verification of PHY. In case the PHY has changed to CODE the request should be stopped.
|
||||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
*/
|
||||||
|
#if defined(CONFIG_BT_CTLR_PHY)
|
||||||
|
if (conn->lll.phy_rx != PHY_CODED) {
|
||||||
|
#else
|
||||||
|
if (1) {
|
||||||
|
#endif /* CONFIG_BT_CTLR_PHY */
|
||||||
|
ctx = llcp_create_local_procedure(PROC_CTE_REQ);
|
||||||
|
if (!ctx) {
|
||||||
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->data.cte_req.min_len = min_cte_len;
|
||||||
|
ctx->data.cte_req.type = cte_type;
|
||||||
|
|
||||||
|
conn->llcp.cte_req.is_active = 1U;
|
||||||
|
|
||||||
|
llcp_lr_enqueue(conn, ctx);
|
||||||
|
|
||||||
|
return BT_HCI_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->data.cte_req.min_len = min_cte_len;
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
ctx->data.cte_req.type = cte_type;
|
|
||||||
|
|
||||||
conn->llcp.cte_req.is_active = 1U;
|
|
||||||
|
|
||||||
llcp_lr_enqueue(conn, ctx);
|
|
||||||
|
|
||||||
return BT_HCI_ERR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ull_cp_cte_req_set_disable(struct ll_conn *conn)
|
void ull_cp_cte_req_set_disable(struct ll_conn *conn)
|
||||||
|
|
|
@ -353,14 +353,22 @@ static void lp_comm_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
|
||||||
conn->llcp.cte_req.req_interval != 0U) {
|
conn->llcp.cte_req.req_interval != 0U) {
|
||||||
conn->llcp.cte_req.req_expire = conn->llcp.cte_req.req_interval;
|
conn->llcp.cte_req.req_expire = conn->llcp.cte_req.req_interval;
|
||||||
} else {
|
} else {
|
||||||
conn->llcp.cte_req.is_enabled = 0U;
|
/* TODO: add wait for notification buffer */
|
||||||
lp_comm_ntf(conn, ctx);
|
lp_comm_ntf(conn, ctx);
|
||||||
ull_cp_cte_req_set_disable(conn);
|
ull_cp_cte_req_set_disable(conn);
|
||||||
}
|
}
|
||||||
} else if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND &&
|
} else if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND &&
|
||||||
ctx->reject_ext_ind.reject_opcode == PDU_DATA_LLCTRL_TYPE_CTE_REQ) {
|
ctx->reject_ext_ind.reject_opcode == PDU_DATA_LLCTRL_TYPE_CTE_REQ) {
|
||||||
|
/* TODO: add wait for notification buffer */
|
||||||
lp_comm_ntf(conn, ctx);
|
lp_comm_ntf(conn, ctx);
|
||||||
conn->llcp.cte_req.is_enabled = 0U;
|
ull_cp_cte_req_set_disable(conn);
|
||||||
|
} else if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_UNUSED) {
|
||||||
|
/* This path is related with handling disable the CTE REQ when PHY
|
||||||
|
* has been changed to CODED PHY. BT 5.3 Core Vol 4 Part E 7.8.85
|
||||||
|
* says CTE REQ has to be automatically disabled as if it had been requested
|
||||||
|
* by Host. There is no notification send to Host.
|
||||||
|
*/
|
||||||
|
ull_cp_cte_req_set_disable(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
llcp_rr_set_paused_cmd(conn, PROC_NONE);
|
llcp_rr_set_paused_cmd(conn, PROC_NONE);
|
||||||
|
@ -467,12 +475,30 @@ static void lp_comm_send_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
|
||||||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
|
||||||
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ)
|
||||||
case PROC_CTE_REQ:
|
case PROC_CTE_REQ:
|
||||||
if (ctx->pause || !llcp_tx_alloc_peek(conn, ctx) ||
|
#if defined(CONFIG_BT_CTLR_PHY)
|
||||||
(llcp_rr_get_paused_cmd(conn) == PROC_CTE_REQ)) {
|
if (conn->lll.phy_rx != PHY_CODED) {
|
||||||
ctx->state = LP_COMMON_STATE_WAIT_TX;
|
#else
|
||||||
|
if (1) {
|
||||||
|
#endif /* CONFIG_BT_CTLR_PHY */
|
||||||
|
if (ctx->pause || !llcp_tx_alloc_peek(conn, ctx) ||
|
||||||
|
(llcp_rr_get_paused_cmd(conn) == PROC_CTE_REQ)) {
|
||||||
|
ctx->state = LP_COMMON_STATE_WAIT_TX;
|
||||||
|
} else {
|
||||||
|
lp_comm_tx(conn, ctx);
|
||||||
|
ctx->state = LP_COMMON_STATE_WAIT_RX;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
lp_comm_tx(conn, ctx);
|
/* The PHY was changed to CODED when the request was waiting in a local
|
||||||
ctx->state = LP_COMMON_STATE_WAIT_RX;
|
* request queue.
|
||||||
|
*
|
||||||
|
* Use of pair: proc PROC_CTE_REQ and rx_opcode PDU_DATA_LLCTRL_TYPE_UNUSED
|
||||||
|
* to complete the procedure before sending a request to peer.
|
||||||
|
* This is a special complete execution path to disable the procedure
|
||||||
|
* due to change of RX PHY to CODED.
|
||||||
|
*/
|
||||||
|
ctx->rx_opcode = PDU_DATA_LLCTRL_TYPE_UNUSED;
|
||||||
|
ctx->state = LP_COMMON_STATE_IDLE;
|
||||||
|
llcp_lr_complete(conn);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue