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 b9035d28c nimble/host: ble_hs_stop: Handle BLE_HS_EALREADY case
b9035d28c is described below

commit b9035d28c68a19789a1427a029b03fa759d906f9
Author: Magdalena Kasenberg <[email protected]>
AuthorDate: Wed Jun 25 12:43:53 2025 +0200

    nimble/host: ble_hs_stop: Handle BLE_HS_EALREADY case
    
    If `ble_hs_stop_terminate_conn()` returns `BLE_HS_EALREADY`, the stop
    callback may be triggered before the HCI Disconnection Complete event
    is received. Until that event, some connection-related resources are
    still in use, and calling APIs like `ble_gatts_reset()` will return
    BUSY.
    
    Let's use the host stop timeout for the use case with BLE_HS_EALREADY
    to make sure the stop callback won't be sent too early.
    
    Call HCI reset in the stop sequence to reset the LL state.
---
 nimble/host/src/ble_hs_stop.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/nimble/host/src/ble_hs_stop.c b/nimble/host/src/ble_hs_stop.c
index e48fff389..2a07329eb 100644
--- a/nimble/host/src/ble_hs_stop.c
+++ b/nimble/host/src/ble_hs_stop.c
@@ -42,6 +42,13 @@ static uint8_t ble_hs_stop_conn_cnt;
 
 static struct ble_npl_callout ble_hs_stop_terminate_tmo;
 
+static int
+ble_hs_stop_hci_reset(void)
+{
+    return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND, 
BLE_HCI_OCF_CB_RESET),
+                             NULL, 0, NULL, 0);
+}
+
 /**
  * Called when a stop procedure has completed.
  */
@@ -62,6 +69,14 @@ ble_hs_stop_done(int status)
 
     ble_hs_enabled_state = BLE_HS_ENABLED_STATE_OFF;
 
+    ble_hs_stop_hci_reset();
+
+    /* After LL reset the controller loses its random address */
+    ble_hs_id_reset();
+
+    /* Clear advertising, scanning and connection states. */
+    ble_gap_reset_state(0);
+
     ble_hs_unlock();
 
     SLIST_FOREACH(listener, &slist, link) {
@@ -114,7 +129,7 @@ ble_hs_stop_terminate_conn(struct ble_hs_conn *conn, void 
*arg)
     int rc;
 
     rc = ble_gap_terminate_with_conn(conn, BLE_ERR_REM_USER_CONN_TERM);
-    if (rc == 0) {
+    if (rc == 0 || rc == BLE_HS_EALREADY) {
         /* Terminate procedure successfully initiated.  Let the GAP event
          * handler deal with the result.
          */
@@ -256,6 +271,8 @@ ble_hs_stop(struct ble_hs_stop_listener *listener,
         return rc;
     }
 
+    ble_hs_stop_conn_cnt = 0;
+
     ble_hs_lock();
     ble_hs_conn_foreach(ble_hs_stop_terminate_conn, NULL);
     ble_hs_unlock();

Reply via email to