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: