Fix duplicate disconnect messages when Mac app closes

- Added gracefullyLeftPeers tracking to prevent duplicate disconnect messages
- Show disconnect message immediately when leave announcement is received
- Skip duplicate message when physical disconnect happens after graceful leave
- Fixed API misuse by adding peripheral.state checks before readRSSI() calls
- Added debug logging to track graceful leave flow
This commit is contained in:
jack
2025-07-24 15:11:45 +02:00
parent 439668f745
commit bdbc0a6cfe
+15 -9
View File
@@ -2495,18 +2495,13 @@ class BluetoothMeshService: NSObject {
// Mark as gracefully left to prevent duplicate disconnect message
self.gracefullyLeftPeers.insert(senderID)
// Remove after a delay to handle race conditions with physical disconnect
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { [weak self] in
self?.gracefullyLeftPeers.remove(senderID)
}
SecureLogger.log("📴 Peer left network: \(senderID) (\(nickname))", category: SecureLogger.session, level: .info)
SecureLogger.log("📴 Peer left network: \(senderID) (\(nickname)) - marked as gracefully left", category: SecureLogger.session, level: .info)
}
}
announcedPeers.remove(senderID)
// Show leave message
// Show disconnect message immediately when peer leaves
DispatchQueue.main.async {
self.delegate?.didDisconnectFromPeer(senderID)
}
@@ -3376,8 +3371,18 @@ extension BluetoothMeshService: CBCentralManagerDelegate {
// Reset handshake state to prevent stuck handshakes
handshakeCoordinator.resetHandshakeState(for: peerID)
// Notify delegate immediately about disconnect (unless peer gracefully left)
if !gracefullyLeftPeers.contains(peerID) {
// Check if peer gracefully left and notify delegate
let shouldNotifyDisconnect = collectionsQueue.sync {
let isGracefullyLeft = self.gracefullyLeftPeers.contains(peerID)
if isGracefullyLeft {
SecureLogger.log("Physical disconnect for \(peerID) - was gracefully left, NOT notifying delegate", category: SecureLogger.session, level: .info)
} else {
SecureLogger.log("Physical disconnect for \(peerID) - was NOT gracefully left, will notify delegate", category: SecureLogger.session, level: .info)
}
return !isGracefullyLeft
}
if shouldNotifyDisconnect {
DispatchQueue.main.async {
self.delegate?.didDisconnectFromPeer(peerID)
}
@@ -3442,6 +3447,7 @@ extension BluetoothMeshService: CBCentralManagerDelegate {
} else {
// Peer gracefully left, just clean up the tracking
self.gracefullyLeftPeers.remove(peerID)
SecureLogger.log("Cleaning up gracefullyLeftPeers for \(peerID)", category: SecureLogger.session, level: .debug)
}
}