From ffb9448afedf996bf30ef03ce2880c7107d7bfea Mon Sep 17 00:00:00 2001 From: Matthew McGowan Date: Sat, 31 Jan 2026 14:08:42 -0800 Subject: [PATCH] fix(server): notify characteristics on client disconnect When a BLE client disconnects, iterate through all characteristics and call processSubRequest(peerInfo, 0) for any that had active subscriptions from the disconnecting client. This ensures that: 1. The onSubscribe callback is called with subValue=0 2. Applications tracking subscriber counts get notified 3. Subscription state is properly cleaned up Without this fix, applications using NuS-NimBLE-Serial or similar wrappers that track subscriber counts would retain stale subscription state after client disconnects, causing issues with reconnection. Co-Authored-By: Claude Opus 4.5 --- src/NimBLEServer.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index 3c062f78..f614756d 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -432,6 +432,23 @@ int NimBLEServer::handleGapEvent(ble_gap_event* event, void* arg) { } peerInfo.m_desc = event->disconnect.conn; + + // Notify characteristics that the client has unsubscribed. + // This ensures onSubscribe callbacks are called with subValue=0 + // so applications can clean up their subscription state. + for (const auto& svc : pServer->m_svcVec) { + for (const auto& chr : svc->getCharacteristics()) { + auto subscribers = chr->getSubscribers(); + for (const auto& entry : subscribers) { + if (entry.getConnHandle() == event->disconnect.conn.conn_handle && + (entry.isSubNotify() || entry.isSubIndicate())) { + chr->processSubRequest(peerInfo, 0); + break; + } + } + } + } + pServer->m_pServerCallbacks->onDisconnect(pServer, peerInfo, event->disconnect.reason); # if !MYNEWT_VAL(BLE_EXT_ADV) if (pServer->m_advertiseOnDisconnect) {