Bluetooth: controller: Fix missing encryption procedure state check
Fix a missing encryption procedure state check which allowed out of order receive of START_ENC_RSP PDU, which made the controller to believe its already in an encryption procedure in progress state. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
1690f27658
commit
41e9493ae1
2 changed files with 37 additions and 27 deletions
|
@ -2996,6 +2996,11 @@ static inline void event_enc_prep(struct ll_conn *conn)
|
|||
event_enc_reject_prep(conn, pdu_ctrl_tx);
|
||||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
|
||||
/* procedure request acked */
|
||||
conn->llcp_ack = conn->llcp_req;
|
||||
|
||||
return;
|
||||
}
|
||||
/* place the start enc req packet as next in tx queue */
|
||||
else {
|
||||
|
@ -3041,19 +3046,16 @@ static inline void event_enc_prep(struct ll_conn *conn)
|
|||
}
|
||||
|
||||
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
|
||||
/* Peripheral sends start enc rsp after reception of start enc rsp */
|
||||
} else {
|
||||
start_enc_rsp_send(conn, pdu_ctrl_tx);
|
||||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
|
||||
/* resume data packet rx and tx */
|
||||
conn->llcp_enc.pause_rx = 0U;
|
||||
conn->llcp_enc.pause_tx = 0U;
|
||||
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
|
||||
}
|
||||
|
||||
/* procedure request acked */
|
||||
conn->llcp_ack = conn->llcp_req;
|
||||
/* Wait for encryption setup to complete */
|
||||
conn->llcp.encryption.state = LLCP_ENC_STATE_ENC_WAIT;
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
||||
|
||||
|
@ -5608,13 +5610,29 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
|
|||
break;
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_START_ENC_REQ:
|
||||
/* Nothing to do.
|
||||
* Remember that we may have received encrypted START_ENC_RSP
|
||||
/* Remember that we may have received encrypted START_ENC_RSP
|
||||
* alongwith this tx ack at this point in time.
|
||||
*/
|
||||
conn->llcp.encryption.state = LLCP_ENC_STATE_ENC_WAIT;
|
||||
break;
|
||||
#endif /* CONFIG_BT_PERIPHERAL */
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_START_ENC_RSP:
|
||||
if (conn->lll.role) {
|
||||
/* resume data packet rx and tx */
|
||||
conn->llcp_enc.pause_rx = 0U;
|
||||
conn->llcp_enc.pause_tx = 0U;
|
||||
|
||||
/* Procedure complete */
|
||||
conn->procedure_expire = 0U;
|
||||
|
||||
/* procedure request acked */
|
||||
conn->llcp_ack = conn->llcp_req;
|
||||
} else {
|
||||
conn->llcp.encryption.state = LLCP_ENC_STATE_ENC_WAIT;
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined(CONFIG_BT_CENTRAL)
|
||||
case PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_REQ:
|
||||
/* pause data packet tx */
|
||||
|
@ -5961,39 +5979,34 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
|
|||
#endif /* CONFIG_BT_CENTRAL */
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_START_ENC_RSP:
|
||||
if (PDU_DATA_LLCTRL_LEN(start_enc_rsp) != pdu_rx->len) {
|
||||
if ((conn->llcp_req == conn->llcp_ack) ||
|
||||
(conn->llcp_type != LLCP_ENCRYPTION) ||
|
||||
(PDU_DATA_LLCTRL_LEN(start_enc_rsp) != pdu_rx->len)) {
|
||||
goto ull_conn_rx_unknown_rsp_send;
|
||||
}
|
||||
|
||||
if (conn->lll.role) {
|
||||
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
|
||||
if ((conn->llcp_req != conn->llcp_ack) &&
|
||||
(conn->llcp_type != LLCP_ENCRYPTION)) {
|
||||
goto ull_conn_rx_unknown_rsp_send;
|
||||
}
|
||||
|
||||
/* start enc rsp to be scheduled in slave prepare */
|
||||
/* start enc rsp to be scheduled in slave prepare */
|
||||
conn->llcp.encryption.state = LLCP_ENC_STATE_INPROG;
|
||||
if (conn->llcp_req == conn->llcp_ack) {
|
||||
conn->llcp_type = LLCP_ENCRYPTION;
|
||||
conn->llcp_ack -= 2U;
|
||||
}
|
||||
|
||||
#else /* CONFIG_BT_CTLR_FAST_ENC */
|
||||
nack = start_enc_rsp_send(conn, NULL);
|
||||
if (nack) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* resume data packet rx and tx */
|
||||
conn->llcp_enc.pause_rx = 0U;
|
||||
conn->llcp_enc.pause_tx = 0U;
|
||||
#endif /* CONFIG_BT_CTLR_FAST_ENC */
|
||||
|
||||
} else {
|
||||
/* resume data packet rx and tx */
|
||||
conn->llcp_enc.pause_rx = 0U;
|
||||
conn->llcp_enc.pause_tx = 0U;
|
||||
|
||||
/* Procedure complete */
|
||||
conn->procedure_expire = 0U;
|
||||
|
||||
/* procedure request acked */
|
||||
conn->llcp_ack = conn->llcp_req;
|
||||
}
|
||||
|
||||
/* enqueue the start enc resp (encryption change/refresh) */
|
||||
|
@ -6003,10 +6016,6 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
|
|||
/* key refresh event */
|
||||
(*rx)->hdr.type = NODE_RX_TYPE_ENC_REFRESH;
|
||||
}
|
||||
|
||||
/* Procedure complete */
|
||||
conn->procedure_expire = 0U;
|
||||
|
||||
break;
|
||||
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue