From 91bf5e0defbce138e882792a8125a3a65a3c2a04 Mon Sep 17 00:00:00 2001 From: h2zero Date: Tue, 3 Feb 2026 19:14:59 -0700 Subject: [PATCH] [Bugfix] Peripheral connection event delay/missing disconnect event This removes some incorrect upstream changes that would allow a peripheral/server device to recieve events from connected client requests without the application being aware of the connection. The code was changed from the original mynewt event flow in that the connection event is not sent until a response from a request to read the remote version/features where originally the event was sent before these responses were received. This reverts this situaton for the peripheral role because when the connection is made in this case it is fully established and there is no need to wait for the responses to the above requests. In addition the delay caused by these was allowing connected peers to interact without the application knowing of the connection, creating unexpoected issues. One of those issues is the client could disconnect before the peripheral receives a response to the above requests and the changes that were made would prevent the disconnect event from being sent because the connection was not considered established. Finally, the connection reattempt code was checking for a connection establishment failure when the device was acting as a slave, which is incorrect as that condition cannot happen if the spec is followed. The controller should never send this event to a peripheral device waiting for connection, it should just stay advertsing. This patch removes all of the unecessary code that was added and reverts the flow to the original mynewt flow for peripheral devices. --- src/nimble/nimble/host/src/ble_gap.c | 49 ++++++--------------- src/nimble/nimble/host/src/ble_hs_hci_evt.c | 8 ++-- 2 files changed, 16 insertions(+), 41 deletions(-) diff --git a/src/nimble/nimble/host/src/ble_gap.c b/src/nimble/nimble/host/src/ble_gap.c index 778e6fbd6..6ea78e370 100644 --- a/src/nimble/nimble/host/src/ble_gap.c +++ b/src/nimble/nimble/host/src/ble_gap.c @@ -296,7 +296,6 @@ static uint8_t pawr_adv_handle; static uint16_t pawr_sync_handle; #endif -int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1]; static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry); #if NIMBLE_BLE_CONNECT @@ -1557,8 +1556,6 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) struct ble_gap_update_entry *entry; struct ble_gap_snapshot snap; struct ble_gap_event event; - struct ble_hs_conn *conn; - bool send = 1; int rc; memset(&event, 0, sizeof event); @@ -1595,19 +1592,6 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) #endif ble_hs_flow_connection_broken(conn_handle);; - ble_hs_lock(); - conn = ble_hs_conn_find(conn_handle); - ble_hs_unlock(); - - // Send disconnect event in slave role if connect was sent - if ((conn != NULL) && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { - if (slave_conn[conn_handle]) { - slave_conn[conn_handle] = 0; - } else { - send = 0; - } - } - ble_hs_atomic_conn_delete(conn_handle); g_max_tx_time[conn_handle] = 0; @@ -1618,10 +1602,8 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason) event.type = BLE_GAP_EVENT_DISCONNECT; event.disconnect.reason = reason; - if (send) { - ble_gap_event_listener_call(&event); - ble_gap_call_event_cb(&event, snap.cb, snap.cb_arg); - } + ble_gap_event_listener_call(&event); + ble_gap_call_event_cb(&event, snap.cb, snap.cb_arg); STATS_INC(ble_gap_stats, disconnect); #endif @@ -2770,9 +2752,11 @@ ble_gap_rx_conn_complete(struct ble_gap_conn_complete *evt, uint8_t instance) pawr_adv_handle = evt->adv_handle; #endif + if (evt->role == BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE) { + ble_gap_event_connect_call(evt->connection_handle, evt->status); ble_gap_rd_rem_ver_tx(evt->connection_handle); - } else { + } else { // master ble_gap_rd_rem_sup_feat_tx(evt->connection_handle); } @@ -2832,17 +2816,10 @@ ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used ble_hs_unlock(); - if ((conn != NULL) && (conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { + if ((conn != NULL) && ev->status == 0) { conn->supported_feat = get_le32(ev->features); - ble_gap_rd_rem_ver_tx(ev->conn_handle); - } else { - if ((conn != NULL) && (ev->status == 0)) { - conn->supported_feat = get_le32(ev->features); - } - - if (conn != NULL) { - ble_gap_event_connect_call(ev->conn_handle, ev->status); - slave_conn[ev->conn_handle] = 1; + if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { + ble_gap_rd_rem_ver_tx(ev->conn_handle); } } #endif @@ -2864,11 +2841,11 @@ ble_gap_rx_rd_rem_ver_info_complete(const struct ble_hci_ev_rd_rem_ver_info_cmp conn->bhc_rd_rem_ver_params.manufacturer = ev->manufacturer; conn->bhc_rd_rem_ver_params.subversion = ev->subversion; - if ((conn != NULL) && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) { - ble_gap_rd_rem_sup_feat_tx(ev->conn_handle); - } else { - if ((conn != NULL) && (ev->status == 0)) { - ble_gap_event_connect_call(ev->conn_handle, ev->status); + if ((conn != NULL)) { + if (conn->bhc_flags & BLE_HS_CONN_F_MASTER) { + ble_gap_event_connect_call(ev->conn_handle, 0); + } else { + ble_gap_rd_rem_sup_feat_tx(ev->conn_handle); } } #endif diff --git a/src/nimble/nimble/host/src/ble_hs_hci_evt.c b/src/nimble/nimble/host/src/ble_hs_hci_evt.c index c8055dfdf..c3903e2af 100644 --- a/src/nimble/nimble/host/src/ble_hs_hci_evt.c +++ b/src/nimble/nimble/host/src/ble_hs_hci_evt.c @@ -37,7 +37,6 @@ struct ble_gap_reattempt_ctxt { extern int ble_gap_master_connect_reattempt(uint16_t conn_handle); extern int ble_gap_slave_adv_reattempt(void); -extern int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1]; #endif #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) @@ -285,9 +284,8 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, memset(&reattempt_conn, 0x0, sizeof (struct ble_gap_reattempt_ctxt)); } } - else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \ - ((ev->reason == BLE_ERR_CONN_ESTABLISHMENT) || \ - (!slave_conn[ev->conn_handle] && ev->reason == BLE_ERR_CONN_SPVN_TMO))) { //slave + else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER) && + ev->reason == BLE_ERR_CONN_SPVN_TMO) { //slave BLE_HS_LOG(INFO, "Reattempt advertising; reason: 0x%x, status = %x", ev->reason, ev->status); @@ -295,7 +293,7 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data, ble_sm_connection_broken(ev->conn_handle); ble_gatts_connection_broken(ev->conn_handle); ble_gattc_connection_broken(ev->conn_handle); - ble_hs_flow_connection_broken(ev->conn_handle);; + ble_hs_flow_connection_broken(ev->conn_handle); #if MYNEWT_VAL(BLE_GATT_CACHING) ble_gattc_cache_conn_broken(ev->conn_handle); #endif