Bluetooth: controller: llcp: Fix terminate timer
Add the missing terminate timer for the ACL Termination procedure. Signed-off-by: Thomas Ebert Hansen <thoh@oticon.com>
This commit is contained in:
parent
2a2856e88e
commit
5d80dbd388
6 changed files with 46 additions and 8 deletions
|
@ -1592,8 +1592,10 @@ void ull_conn_done(struct node_rx_event_done *done)
|
|||
}
|
||||
}
|
||||
#else /* CONFIG_BT_LL_SW_LLCP_LEGACY */
|
||||
if (-ETIMEDOUT == ull_cp_prt_elapse(conn, elapsed_event)) {
|
||||
conn_cleanup(conn, BT_HCI_ERR_LL_RESP_TIMEOUT);
|
||||
uint8_t error_code;
|
||||
|
||||
if (-ETIMEDOUT == ull_cp_prt_elapse(conn, elapsed_event, &error_code)) {
|
||||
conn_cleanup(conn, error_code);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -542,20 +542,40 @@ static int prt_elapse(uint16_t *expire, uint16_t elapsed_event)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ull_cp_prt_elapse(struct ll_conn *conn, uint16_t elapsed_event)
|
||||
int ull_cp_prt_elapse(struct ll_conn *conn, uint16_t elapsed_event, uint8_t *error_code)
|
||||
{
|
||||
int loc_ret;
|
||||
int rem_ret;
|
||||
|
||||
loc_ret = prt_elapse(&conn->llcp.local.prt_expire, elapsed_event);
|
||||
rem_ret = prt_elapse(&conn->llcp.remote.prt_expire, elapsed_event);
|
||||
if (loc_ret == -ETIMEDOUT) {
|
||||
/* Local Request Machine timed out */
|
||||
|
||||
if (loc_ret == -ETIMEDOUT || rem_ret == -ETIMEDOUT) {
|
||||
/* One of the timers expired */
|
||||
struct proc_ctx *ctx;
|
||||
|
||||
ctx = llcp_lr_peek(conn);
|
||||
LL_ASSERT(ctx);
|
||||
|
||||
if (ctx->proc == PROC_TERMINATE) {
|
||||
/* Active procedure is ACL Termination */
|
||||
*error_code = ctx->data.term.error_code;
|
||||
} else {
|
||||
*error_code = BT_HCI_ERR_LL_RESP_TIMEOUT;
|
||||
}
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
rem_ret = prt_elapse(&conn->llcp.remote.prt_expire, elapsed_event);
|
||||
if (rem_ret == -ETIMEDOUT) {
|
||||
/* Remote Request Machine timed out */
|
||||
|
||||
*error_code = BT_HCI_ERR_LL_RESP_TIMEOUT;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Both timers are still running */
|
||||
*error_code = BT_HCI_ERR_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,9 +38,10 @@ void ull_cp_release_ntf(struct node_rx_pdu *ntf);
|
|||
/**
|
||||
* @brief Procedure Response Timeout Check
|
||||
* @param elapsed_event The number of elapsed events.
|
||||
* @param[out] error_code The error code for this timeout.
|
||||
* @return 0 on success, -ETIMEDOUT if timer expired.
|
||||
*/
|
||||
int ull_cp_prt_elapse(struct ll_conn *conn, uint16_t elapsed_event);
|
||||
int ull_cp_prt_elapse(struct ll_conn *conn, uint16_t elapsed_event, uint8_t *error_code);
|
||||
|
||||
void ull_cp_prt_reload_set(struct ll_conn *conn, uint32_t conn_intv);
|
||||
|
||||
|
|
|
@ -162,7 +162,16 @@ static void lp_comm_tx(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
llcp_tx_enqueue(conn, tx);
|
||||
|
||||
/* Restart procedure response timeout timer */
|
||||
llcp_lr_prt_restart(conn);
|
||||
if (ctx->proc != PROC_TERMINATE) {
|
||||
/* Use normal timeout value of 40s */
|
||||
llcp_lr_prt_restart(conn);
|
||||
} else {
|
||||
/* Use supervision timeout value
|
||||
* NOTE: As the supervision timeout is at most 32s the normal procedure response
|
||||
* timeout of 40s will never come into play for the ACL Termination procedure.
|
||||
*/
|
||||
llcp_lr_prt_restart_with_value(conn, conn->supervision_reload);
|
||||
}
|
||||
}
|
||||
|
||||
static void lp_comm_ntf_feature_exchange(struct ll_conn *conn, struct proc_ctx *ctx,
|
||||
|
|
|
@ -359,6 +359,7 @@ void llcp_tx_resume_data(struct ll_conn *conn, enum llcp_tx_q_pause_data_mask re
|
|||
* LLCP Procedure Response Timeout
|
||||
*/
|
||||
void llcp_lr_prt_restart(struct ll_conn *conn);
|
||||
void llcp_lr_prt_restart_with_value(struct ll_conn *conn, uint16_t value);
|
||||
void llcp_lr_prt_stop(struct ll_conn *conn);
|
||||
void llcp_rr_prt_restart(struct ll_conn *conn);
|
||||
void llcp_rr_prt_stop(struct ll_conn *conn);
|
||||
|
|
|
@ -128,6 +128,11 @@ void llcp_lr_prt_restart(struct ll_conn *conn)
|
|||
conn->llcp.local.prt_expire = conn->llcp.prt_reload;
|
||||
}
|
||||
|
||||
void llcp_lr_prt_restart_with_value(struct ll_conn *conn, uint16_t value)
|
||||
{
|
||||
conn->llcp.local.prt_expire = value;
|
||||
}
|
||||
|
||||
void llcp_lr_prt_stop(struct ll_conn *conn)
|
||||
{
|
||||
conn->llcp.local.prt_expire = 0U;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue