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