This is an automated email from the ASF dual-hosted git repository.

andk 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 f9eb3c8d nimble/ll: Fix continuation events handling
f9eb3c8d is described below

commit f9eb3c8d27b07d441dc7a77de513ef940ad7da1f
Author: Andrzej Kaczmarek <[email protected]>
AuthorDate: Wed Jul 13 10:39:35 2022 +0200

    nimble/ll: Fix continuation events handling
    
    We should only start counting continuation events if a valid non-empty
    PDU was rxd/txd in a connection event. Also we should ignore any valid
    PDUs prior to subrated event.
    
    This fixes LL/CON/PER/BV-143-C and LL/CON/CEN/BV-145-C.
---
 nimble/controller/include/controller/ble_ll_conn.h |  3 +-
 nimble/controller/src/ble_ll_conn.c                | 41 ++++++++++++++++------
 2 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll_conn.h 
b/nimble/controller/include/controller/ble_ll_conn.h
index 13e9af00..413ae9ec 100644
--- a/nimble/controller/include/controller/ble_ll_conn.h
+++ b/nimble/controller/include/controller/ble_ll_conn.h
@@ -310,7 +310,8 @@ struct ble_ll_conn_sm
     uint16_t subrate_base_event;
     uint16_t subrate_factor;
     uint16_t cont_num;
-    uint16_t last_pdu_event;
+    uint16_t cont_num_left;
+    uint8_t has_nonempty_pdu;
 
     union {
         struct ble_ll_conn_subrate_params subrate_trans;
diff --git a/nimble/controller/src/ble_ll_conn.c 
b/nimble/controller/src/ble_ll_conn.c
index e2eb33e3..4d1bf85e 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -1436,9 +1436,15 @@ conn_tx_pdu:
             }
             STATS_INC(ble_ll_conn_stats, tx_empty_pdus);
         } else if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) 
{
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE)
+            connsm->has_nonempty_pdu = 1;
+#endif
             STATS_INC(ble_ll_conn_stats, tx_ctrl_pdus);
             STATS_INCN(ble_ll_conn_stats, tx_ctrl_bytes, cur_txlen);
         } else {
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE)
+            connsm->has_nonempty_pdu = 1;
+#endif
             STATS_INC(ble_ll_conn_stats, tx_l2cap_pdus);
             STATS_INCN(ble_ll_conn_stats, tx_l2cap_bytes, cur_txlen);
         }
@@ -1918,7 +1924,8 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm)
     connsm->subrate_base_event = 0;
     connsm->subrate_factor = 1;
     connsm->cont_num = 0;
-    connsm->last_pdu_event = 0;
+    connsm->cont_num_left = 0;
+    connsm->has_nonempty_pdu = 0;
 #endif
 
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PERIODIC_ADV_SYNC_TRANSFER)
@@ -2271,10 +2278,25 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
     base_event_cntr = connsm->subrate_base_event;
     subrate_factor = connsm->subrate_factor;
 
-    if ((connsm->cont_num > 0) &&
-        (connsm->event_cntr + 1 == connsm->subrate_base_event +
-                                   connsm->subrate_factor) &&
-        (connsm->event_cntr - connsm->last_pdu_event < connsm->cont_num)) {
+    /* We need to restore remaining continuation events counter if a non-empty
+     * PDU was txd/rxd in this connection event. Also we need to set counter to
+     * 0 in case there was no valid PDU at subrated event, since we should not
+     * use continuation events in such case (i.e. ignore any valid PDUs prior
+     * to subrated event).
+     *
+     * Note that has_nonempty_pdu flag is also cleared here since LL may move 
to
+     * next connection event due to scheduling conflict and there will be no
+     * start callback for new event.
+     */
+    if (connsm->has_nonempty_pdu) {
+        connsm->cont_num_left = connsm->cont_num;
+        connsm->has_nonempty_pdu = 0;
+    } else if (connsm->event_cntr == connsm->subrate_base_event) {
+        connsm->cont_num_left = 0;
+    }
+
+    if (connsm->cont_num_left > 0) {
+        connsm->cont_num_left--;
         next_is_subrated = 0;
     }
 #else
@@ -3344,11 +3366,6 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct 
ble_mbuf_hdr *hdr)
     acl_len = rxbuf[1];
     llid = hdr_byte & BLE_LL_DATA_HDR_LLID_MASK;
 
-#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE)
-    connsm->last_pdu_event = connsm->event_cntr;
-#endif
-
-
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
     if (BLE_MBUF_HDR_MIC_FAILURE(hdr)) {
         STATS_INC(ble_ll_conn_stats, mic_failures);
@@ -3428,6 +3445,10 @@ ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct 
ble_mbuf_hdr *hdr)
         goto conn_rx_data_pdu_end;
     }
 
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_ENHANCED_CONN_UPDATE)
+    connsm->has_nonempty_pdu = 1;
+#endif
+
     if (llid == BLE_LL_LLID_CTRL) {
         /* Process control frame */
         STATS_INC(ble_ll_conn_stats, rx_ctrl_pdus);

Reply via email to