mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 12:45:20 +00:00
Improve BLE connection stability and message reliability (#318)
* Remove sequence numbers from protocol - Remove sequenceNumber field from BitchatPacket struct - Update BinaryProtocol to not encode/decode sequence numbers (header size reduced from 17 to 13 bytes) - Replace sequence-based duplicate detection with content-based using packet ID hash - Update packet ID generation to use SHA256(senderID + timestamp + type + payload prefix) - Remove all sequence tracking variables and methods - Simplify duplicate detection to rely on timestamp and content hashing * Fix connection stability issues - Increase peer availability check interval from 5 to 15 seconds - Fix availability logic to not mark connected peers as unavailable - Add BLE connection keepalive timer (20s) to prevent iOS timeouts - Fix missing delivery ACKs by passing peripheral context through Noise decryption - Reduce identity announce frequency from 2 to 10 seconds minimum - Remove unnecessary identity announces on connection - Debounce identity cache keychain saves (2 second delay) - Add message retry notification handler in ChatViewModel - Fix version negotiation redundancy by checking existing negotiations - Keep Noise sessions for already-connected peers * Fix build errors in message retry handler - Fix reference to 'displayedMessages' - should be 'messages' - Fix sendMessage call signature to use individual parameters instead of message object - Both iOS and macOS builds now succeed * Fix remaining connection stability issues - Fix duplicate identity announces with content-based deduplication - Simplify peripheral mapping with cleaner temp ID to peer ID transitions - Improve graceful leave detection across peer ID rotations - Track previousPeerID from announcements to maintain state - Add time-based cleanup for gracefully left peers * Fix connection stability issues - Add special duplicate detection for identity announces - Simplify peripheral mapping with dedicated structure - Improve graceful leave detection with peer ID rotation handling - Track graceful leave timestamps for cleanup - Transfer states properly during peer ID rotation * Improve BLE connection stability and message reliability - Increase peer availability timeout from 5s to 15s to prevent flapping - Add BLE keepalive timer with 30s interval to maintain connections - Fix missing delivery ACKs by passing peripheral context through decryption - Reduce identity announce frequency from 2s to 10s minimum interval - Add keychain save debouncing with 2s delay to prevent excessive writes - Implement message retry system for failed deliveries to favorites - Fix version negotiation redundancy by checking existing state - Add special duplicate detection for identity announcements - Implement graceful leave detection with peer ID rotation support - Simplify peripheral mapping to reduce complexity - Fix switch statement structure issues causing build errors These changes significantly improve connection stability, eliminate peer availability flapping, and ensure reliable message delivery. --------- Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
@@ -27,6 +27,11 @@ class SecureIdentityStateManager {
|
||||
// Thread safety
|
||||
private let queue = DispatchQueue(label: "bitchat.identity.state", attributes: .concurrent)
|
||||
|
||||
// Debouncing for keychain saves
|
||||
private var saveTimer: Timer?
|
||||
private let saveDebounceInterval: TimeInterval = 2.0 // Save at most once every 2 seconds
|
||||
private var pendingSave = false
|
||||
|
||||
// Encryption key
|
||||
private let encryptionKey: SymmetricKey
|
||||
|
||||
@@ -72,16 +77,48 @@ class SecureIdentityStateManager {
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
// Force save any pending changes
|
||||
forceSave()
|
||||
}
|
||||
|
||||
func saveIdentityCache() {
|
||||
// Mark that we need to save
|
||||
pendingSave = true
|
||||
|
||||
// Cancel any existing timer
|
||||
saveTimer?.invalidate()
|
||||
|
||||
// Schedule a new save after the debounce interval
|
||||
saveTimer = Timer.scheduledTimer(withTimeInterval: saveDebounceInterval, repeats: false) { [weak self] _ in
|
||||
self?.performSave()
|
||||
}
|
||||
}
|
||||
|
||||
private func performSave() {
|
||||
guard pendingSave else { return }
|
||||
pendingSave = false
|
||||
|
||||
do {
|
||||
let data = try JSONEncoder().encode(cache)
|
||||
let sealedBox = try AES.GCM.seal(data, using: encryptionKey)
|
||||
_ = keychain.saveIdentityKey(sealedBox.combined!, forKey: cacheKey)
|
||||
let saved = keychain.saveIdentityKey(sealedBox.combined!, forKey: cacheKey)
|
||||
if saved {
|
||||
SecureLogger.log("Identity cache saved to keychain", category: SecureLogger.security, level: .debug)
|
||||
}
|
||||
} catch {
|
||||
SecureLogger.logError(error, context: "Failed to save identity cache", category: SecureLogger.security)
|
||||
}
|
||||
}
|
||||
|
||||
// Force immediate save (for app termination)
|
||||
func forceSave() {
|
||||
saveTimer?.invalidate()
|
||||
if pendingSave {
|
||||
performSave()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Identity Resolution
|
||||
|
||||
func resolveIdentity(peerID: String, claimedNickname: String) -> IdentityHint {
|
||||
|
||||
Reference in New Issue
Block a user