You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ry...@apache.org on 2020/11/05 12:10:16 UTC
[mynewt-nimble] branch master updated: nimble/ll: Fix stuck in the
encryption process
This is an automated email from the ASF dual-hosted git repository.
rymek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
The following commit(s) were added to refs/heads/master by this push:
new f11bc67 nimble/ll: Fix stuck in the encryption process
f11bc67 is described below
commit f11bc676f380a40f73744bd83a72e5db3a3e4a37
Author: Ćukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Tue Oct 6 13:04:46 2020 +0200
nimble/ll: Fix stuck in the encryption process
Background:
When Central sends LL_ENC_REQ, Peripheral is allowed to send unencrypted
data until LL_ENC_RSP is sent back to Central. This is why, Nimble LL puts
LL_ENC_RSP to the tail of the conn_txq.
Issue description:
When lot of trafic is ongoing in the link while encryption, we might
stuck in the process.
This is because enc_state CONN_ENC_S_LTK_REQ_WAIT is set just after
LL_ENC_REQ has been received. If there are still packets in the conn_txq
to send, those will not be sent because of the enc_state. Instead empty
packets will be send and LL_ENC_RSP will stack in the conn_txq.
Fix:
Add addition state for Peripheral role and make sure that LL is able to
send unecypted packets from its conn_txq until LL_ENC_RSP is sent.
---
nimble/controller/include/controller/ble_ll_conn.h | 1 +
nimble/controller/src/ble_ll_conn.c | 20 +++++++++++++++-----
nimble/controller/src/ble_ll_ctrl.c | 3 ++-
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/nimble/controller/include/controller/ble_ll_conn.h b/nimble/controller/include/controller/ble_ll_conn.h
index 8c07462..d7db687 100644
--- a/nimble/controller/include/controller/ble_ll_conn.h
+++ b/nimble/controller/include/controller/ble_ll_conn.h
@@ -71,6 +71,7 @@ extern "C" {
enum conn_enc_state {
CONN_ENC_S_UNENCRYPTED = 1,
CONN_ENC_S_ENCRYPTED,
+ CONN_ENC_S_ENC_RSP_TO_BE_SENT,
CONN_ENC_S_ENC_RSP_WAIT,
CONN_ENC_S_PAUSE_ENC_RSP_WAIT,
CONN_ENC_S_PAUSED,
diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c
index cb80250..371ca42 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -1015,8 +1015,14 @@ ble_ll_conn_tx_pdu(struct ble_ll_conn_sm *connsm)
/*
* If we are encrypting, we are only allowed to send certain
* kinds of LL control PDU's. If none is enqueued, send empty pdu!
+ *
+ * In Slave role, we are allowed to send unencrypted packets until
+ * LL_ENC_RSP is sent.
*/
- if (connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) {
+ if (((connsm->enc_data.enc_state > CONN_ENC_S_ENCRYPTED) &&
+ CONN_IS_MASTER(connsm)) ||
+ ((connsm->enc_data.enc_state > CONN_ENC_S_ENC_RSP_TO_BE_SENT) &&
+ CONN_IS_SLAVE(connsm))) {
if (!ble_ll_ctrl_enc_allowed_pdu_tx(pkthdr)) {
CONN_F_EMPTY_PDU_TXD(connsm) = 1;
goto conn_tx_pdu;
@@ -3652,10 +3658,14 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr)
*
* Reference: Core 5.0, Vol 6, Part B, 5.1.3.1
*/
- if ((connsm->enc_data.enc_state > CONN_ENC_S_PAUSE_ENC_RSP_WAIT) &&
- !ble_ll_ctrl_enc_allowed_pdu_rx(rxpdu)) {
- ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
- goto conn_rx_data_pdu_end;
+ if ((connsm->enc_data.enc_state > CONN_ENC_S_PAUSE_ENC_RSP_WAIT &&
+ CONN_IS_MASTER(connsm)) ||
+ (connsm->enc_data.enc_state >= CONN_ENC_S_ENC_RSP_TO_BE_SENT &&
+ CONN_IS_SLAVE(connsm))) {
+ if (!ble_ll_ctrl_enc_allowed_pdu_rx(rxpdu)) {
+ ble_ll_conn_timeout(connsm, BLE_ERR_CONN_TERM_MIC);
+ goto conn_rx_data_pdu_end;
+ }
}
#endif
diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c
index ade8d7b..c4ac650 100644
--- a/nimble/controller/src/ble_ll_ctrl.c
+++ b/nimble/controller/src/ble_ll_ctrl.c
@@ -1443,7 +1443,7 @@ ble_ll_ctrl_rx_enc_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
return BLE_LL_CTRL_UNKNOWN_RSP;
}
- connsm->enc_data.enc_state = CONN_ENC_S_LTK_REQ_WAIT;
+ connsm->enc_data.enc_state = CONN_ENC_S_ENC_RSP_TO_BE_SENT;
/* In case we were already encrypted we need to reset packet counters */
connsm->enc_data.rx_pkt_cntr = 0;
@@ -2839,6 +2839,7 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm)
connsm->enc_data.enc_state = CONN_ENC_S_ENC_RSP_WAIT;
break;
case BLE_LL_CTRL_ENC_RSP:
+ connsm->enc_data.enc_state = CONN_ENC_S_LTK_REQ_WAIT;
connsm->csmflags.cfbit.send_ltk_req = 1;
break;
case BLE_LL_CTRL_START_ENC_RSP: