mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 11:45:19 +00:00
Guard BLE link state lookups on BLE queue (#805)
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
This commit is contained in:
@@ -1514,6 +1514,22 @@ extension BLEService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Safely fetch the current direct-link state for a peer using the BLE queue.
|
||||
private func linkState(for peerID: PeerID) -> (hasPeripheral: Bool, hasCentral: Bool) {
|
||||
let computeState = { () -> (Bool, Bool) in
|
||||
let peripheralUUID = self.peerToPeripheralUUID[peerID]
|
||||
let hasPeripheral = peripheralUUID.flatMap { self.peripherals[$0]?.isConnected } ?? false
|
||||
let hasCentral = self.centralToPeerID.values.contains(peerID)
|
||||
return (hasPeripheral, hasCentral)
|
||||
}
|
||||
|
||||
if DispatchQueue.getSpecific(key: bleQueueKey) != nil {
|
||||
return computeState()
|
||||
} else {
|
||||
return bleQueue.sync { computeState() }
|
||||
}
|
||||
}
|
||||
|
||||
private func configureNoiseServiceCallbacks(for service: NoiseEncryptionService) {
|
||||
service.onPeerAuthenticated = { [weak self] peerID, fingerprint in
|
||||
let peerID = PeerID(str: peerID)
|
||||
@@ -2458,15 +2474,15 @@ extension BLEService {
|
||||
// Track if this is a new or reconnected peer
|
||||
var isNewPeer = false
|
||||
var isReconnectedPeer = false
|
||||
let directLinkState = linkState(for: peerID)
|
||||
|
||||
collectionsQueue.sync(flags: .barrier) {
|
||||
// Check if we have an actual BLE connection to this peer
|
||||
let peripheralUUID = peerToPeripheralUUID[peerID]
|
||||
let hasPeripheralConnection = peripheralUUID != nil && peripherals[peripheralUUID!]?.isConnected == true
|
||||
let hasPeripheralConnection = directLinkState.hasPeripheral
|
||||
|
||||
// Check if this peer is subscribed to us as a central
|
||||
// Note: We can't identify which specific central is which peer without additional mapping
|
||||
let hasCentralSubscription = centralToPeerID.values.contains(peerID)
|
||||
let hasCentralSubscription = directLinkState.hasCentral
|
||||
|
||||
// Direct announces arrive with full TTL (no prior hop)
|
||||
let isDirectAnnounce = (packet.ttl == messageTTL)
|
||||
@@ -2698,12 +2714,8 @@ extension BLEService {
|
||||
return
|
||||
}
|
||||
// Determine if we have a direct link to the sender
|
||||
let hasDirectLink: Bool = collectionsQueue.sync {
|
||||
let perUUID = peerToPeripheralUUID[peerID]
|
||||
let perConnected = perUUID != nil && peripherals[perUUID!]?.isConnected == true
|
||||
let hasCentral = centralToPeerID.values.contains(peerID)
|
||||
return perConnected || hasCentral
|
||||
}
|
||||
let directLink = linkState(for: peerID)
|
||||
let hasDirectLink = directLink.hasPeripheral || directLink.hasCentral
|
||||
|
||||
let pathTag = hasDirectLink ? "direct" : "mesh"
|
||||
SecureLogger.debug("💬 [\(senderNickname)] TTL:\(packet.ttl) (\(pathTag)): \(String(content.prefix(50)))\(content.count > 50 ? "..." : "")", category: .session)
|
||||
@@ -3046,6 +3058,11 @@ extension BLEService {
|
||||
private func checkPeerConnectivity() {
|
||||
let now = Date()
|
||||
var disconnectedPeers: [String] = []
|
||||
let peerIDsForLinkState: [PeerID] = collectionsQueue.sync { Array(peers.keys) }
|
||||
var cachedLinkStates: [PeerID: (hasPeripheral: Bool, hasCentral: Bool)] = [:]
|
||||
for peerID in peerIDsForLinkState {
|
||||
cachedLinkStates[peerID] = linkState(for: peerID)
|
||||
}
|
||||
|
||||
var removedOfflineCount = 0
|
||||
collectionsQueue.sync(flags: .barrier) {
|
||||
@@ -3054,9 +3071,9 @@ extension BLEService {
|
||||
let retention: TimeInterval = peer.isVerifiedNickname ? TransportConfig.bleReachabilityRetentionVerifiedSeconds : TransportConfig.bleReachabilityRetentionUnverifiedSeconds
|
||||
if peer.isConnected && age > TransportConfig.blePeerInactivityTimeoutSeconds {
|
||||
// Check if we still have an active BLE connection to this peer
|
||||
let hasPeripheralConnection = peerToPeripheralUUID[peerID] != nil &&
|
||||
peripherals[peerToPeripheralUUID[peerID]!]?.isConnected == true
|
||||
let hasCentralConnection = centralToPeerID.values.contains(peerID)
|
||||
let state = cachedLinkStates[peerID] ?? (hasPeripheral: false, hasCentral: false)
|
||||
let hasPeripheralConnection = state.hasPeripheral
|
||||
let hasCentralConnection = state.hasCentral
|
||||
|
||||
// If direct link is gone, mark as not connected (retain entry for reachability)
|
||||
if !hasPeripheralConnection && !hasCentralConnection {
|
||||
|
||||
Reference in New Issue
Block a user