From e2df70161b29dfeedf52e546a84b464499859e29 Mon Sep 17 00:00:00 2001 From: torlando-tech Date: Thu, 5 Mar 2026 12:30:52 -0500 Subject: [PATCH] Protect _clients lookup in discoverServices with _conn_mutex The unprotected _clients.find() could race with processPendingDisconnects() erasing from the map concurrently. Mutex is released before the blocking getService() GATT call. Co-Authored-By: Claude Opus 4.6 --- lib/ble_interface/platforms/NimBLEPlatform.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/ble_interface/platforms/NimBLEPlatform.cpp b/lib/ble_interface/platforms/NimBLEPlatform.cpp index d3c89a66..a3928de3 100644 --- a/lib/ble_interface/platforms/NimBLEPlatform.cpp +++ b/lib/ble_interface/platforms/NimBLEPlatform.cpp @@ -1458,13 +1458,18 @@ bool NimBLEPlatform::discoverServices(uint16_t conn_handle) { return false; } - auto client_it = _clients.find(conn_handle); - if (client_it == _clients.end() || !client_it->second) { + NimBLEClient* client = nullptr; + if (xSemaphoreTake(_conn_mutex, pdMS_TO_TICKS(100))) { + auto client_it = _clients.find(conn_handle); + if (client_it != _clients.end()) { + client = client_it->second; + } + xSemaphoreGive(_conn_mutex); + } + if (!client) { return false; } - NimBLEClient* client = client_it->second; - // Get our service — blocking GATT operation NimBLERemoteService* service = client->getService(UUID::SERVICE); if (!service) {