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

janc 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 d42a0ebe6 nimble/host: Fix disconnect on host connection timeout
d42a0ebe6 is described below

commit d42a0ebe6632bd0c318560e4293a522634f60594
Author: Szymon Janc <[email protected]>
AuthorDate: Mon Jan 29 16:28:12 2024 +0100

    nimble/host: Fix disconnect on host connection timeout
    
    We don't need to have double loop and lock-unlock host lock when
    issuing disconnect. ble_gap_terminate_with_conn() can be used
    to disconnect and it can be called with already provided conn object
    under host lock.
---
 nimble/host/src/ble_hs_conn.c | 111 +++++++++++++++++++-----------------------
 1 file changed, 49 insertions(+), 62 deletions(-)

diff --git a/nimble/host/src/ble_hs_conn.c b/nimble/host/src/ble_hs_conn.c
index 9b7bdbb3d..57ba16af8 100644
--- a/nimble/host/src/ble_hs_conn.c
+++ b/nimble/host/src/ble_hs_conn.c
@@ -477,86 +477,73 @@ ble_hs_conn_timer(void)
 #endif
 
     struct ble_hs_conn *conn;
-    ble_npl_time_t now;
-    int32_t next_exp_in;
+    ble_npl_time_t now = ble_npl_time_get();
+    int32_t next_exp_in = BLE_HS_FOREVER;
+    int32_t next_exp_in_new;
+    bool next_exp_in_updated;
     int32_t time_diff;
-    uint16_t conn_handle;
 
-    for (;;) {
-        conn_handle = BLE_HS_CONN_HANDLE_NONE;
-        next_exp_in = BLE_HS_FOREVER;
-        now = ble_npl_time_get();
+    ble_hs_lock();
 
-        ble_hs_lock();
-
-        /* This loop performs one of two tasks:
-         * 1. Determine if any connections need to be terminated due to 
timeout.
-         *    If so, break out of the loop and terminate the connection.  This
-         *    function will need to be executed again.
-         * 2. Otherwise, determine when the next timeout will occur.
-         */
-        SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
-            if (!(conn->bhc_flags & BLE_HS_CONN_F_TERMINATING)) {
+    /* This loop performs one of two tasks:
+     * 1. Determine if any connections need to be terminated due to timeout. If
+     *    so connection is disconnected.
+     * 2. Otherwise, determine when the next timeout will occur.
+     */
+    SLIST_FOREACH(conn, &ble_hs_conns, bhc_next) {
+        if (!(conn->bhc_flags & BLE_HS_CONN_F_TERMINATING)) {
+            next_exp_in_updated = false;
 
 #if MYNEWT_VAL(BLE_L2CAP_RX_FRAG_TIMEOUT) != 0
-                /* Check each connection's rx fragment timer.  If too much time
-                 * passes after a partial packet is received, the connection is
-                 * terminated.
-                 */
-                if (conn->bhc_rx_chan != NULL) {
-                    time_diff = conn->bhc_rx_timeout - now;
-
-                    if (time_diff <= 0) {
-                        /* ACL reassembly has timed out.  Remember the 
connection
-                         * handle so it can be terminated after the mutex is
-                         * unlocked.
-                         */
-                        conn_handle = conn->bhc_handle;
-                        break;
-                    }
-
-                    /* Determine if this connection is the soonest to time 
out. */
-                    if (time_diff < next_exp_in) {
-                        next_exp_in = time_diff;
-                    }
-                }
-#endif
+            /* Check each connection's rx fragment timer.  If too much time
+             * passes after a partial packet is received, the connection is
+             * terminated.
+             */
+            if (conn->bhc_rx_chan != NULL) {
+                time_diff = conn->bhc_rx_timeout - now;
 
-#if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO
-                /* Check each connection's rx queued write timer.  If too much
-                 * time passes after a prep write is received, the queue is
-                 * cleared.
-                 */
-                time_diff = ble_att_svr_ticks_until_tmo(&conn->bhc_att_svr, 
now);
                 if (time_diff <= 0) {
-                    /* ACL reassembly has timed out.  Remember the connection
-                     * handle so it can be terminated after the mutex is
-                     * unlocked.
-                     */
-                    conn_handle = conn->bhc_handle;
-                    break;
+                    /* ACL reassembly has timed out.*/
+                    ble_gap_terminate_with_conn(conn, 
BLE_ERR_REM_USER_CONN_TERM);
+                    continue;
                 }
 
                 /* Determine if this connection is the soonest to time out. */
                 if (time_diff < next_exp_in) {
-                    next_exp_in = time_diff;
+                    next_exp_in_new = time_diff;
+                    next_exp_in_updated = true;
                 }
+            }
 #endif
+
+#if BLE_HS_ATT_SVR_QUEUED_WRITE_TMO
+            /* Check each connection's rx queued write timer.  If too much
+             * time passes after a prep write is received, the queue is
+             * cleared.
+             */
+            time_diff = ble_att_svr_ticks_until_tmo(&conn->bhc_att_svr, now);
+            if (time_diff <= 0) {
+                /* Queued write has timed out.*/
+                ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM);
+                continue;
             }
-        }
 
-        ble_hs_unlock();
+            /* Determine if this connection is the soonest to time out. */
+            if (time_diff < next_exp_in) {
+                next_exp_in_new = time_diff;
+                next_exp_in_updated = true;
+            }
+#endif
 
-        /* If a connection has timed out, terminate it.  We need to repeatedly
-         * call this function again to determine when the next timeout is.
-         */
-        if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
-            ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
-            continue;
+            if (next_exp_in_updated) {
+                next_exp_in = next_exp_in_new;
+            }
         }
-
-        return next_exp_in;
     }
+
+    ble_hs_unlock();
+
+    return next_exp_in;
 }
 
 int

Reply via email to