mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-24 23:45:18 +00:00
Fix Bluetooth errors and improve store-and-forward
- Add peripheral state checks before all write operations - Fix 'can only accept commands while connected' errors - Check characteristic write properties to avoid ATT errors - Preserve original timestamps in store-and-forward messages - Only log crypto errors once per peer to reduce noise - Store-and-forward now correctly maintains message ordering The timestamp preservation ensures messages appear in the correct chronological order even when delivered later via store-and-forward.
This commit is contained in:
@@ -255,6 +255,7 @@
|
||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = bitchat/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -264,9 +265,12 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat;
|
||||
PRODUCT_NAME = bitchat;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -282,6 +286,7 @@
|
||||
DEVELOPMENT_TEAM = L3N5LHJD5Y;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = bitchat/Info.plist;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -291,9 +296,12 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat;
|
||||
PRODUCT_NAME = bitchat;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
+5
-1
@@ -41,9 +41,13 @@
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -35,6 +35,7 @@ class BluetoothMeshService: NSObject {
|
||||
private var activePeers: Set<String> = [] // Track all active peers
|
||||
private var peerRSSI: [String: NSNumber] = [:] // Track RSSI values for peers
|
||||
private var peripheralRSSI: [String: NSNumber] = [:] // Track RSSI by peripheral ID during discovery
|
||||
private var loggedCryptoErrors = Set<String>() // Track which peers we've logged crypto errors for
|
||||
|
||||
weak var delegate: BitchatDelegate?
|
||||
private let encryptionService = EncryptionService()
|
||||
@@ -210,6 +211,7 @@ class BluetoothMeshService: NSObject {
|
||||
self.broadcastPacket(messages[0])
|
||||
} else if let dest = destination,
|
||||
let peripheral = self.connectedPeripherals[dest],
|
||||
peripheral.state == .connected,
|
||||
let characteristic = self.peripheralCharacteristics[peripheral] {
|
||||
if let data = messages[0].toBinaryData() {
|
||||
peripheral.writeValue(data, for: characteristic, type: .withoutResponse)
|
||||
@@ -225,6 +227,7 @@ class BluetoothMeshService: NSObject {
|
||||
self?.broadcastPacket(message)
|
||||
} else if let dest = destination,
|
||||
let peripheral = self?.connectedPeripherals[dest],
|
||||
peripheral.state == .connected,
|
||||
let characteristic = self?.peripheralCharacteristics[peripheral] {
|
||||
if let data = message.toBinaryData() {
|
||||
peripheral.writeValue(data, for: characteristic, type: .withoutResponse)
|
||||
@@ -627,9 +630,11 @@ class BluetoothMeshService: NSObject {
|
||||
|
||||
// Also try targeted send if we have the peripheral
|
||||
if let peripheral = connectedPeripherals[peerID],
|
||||
peripheral.state == .connected,
|
||||
let characteristic = peripheral.services?.first(where: { $0.uuid == BluetoothMeshService.serviceUUID })?.characteristics?.first(where: { $0.uuid == BluetoothMeshService.characteristicUUID }) {
|
||||
// Also sending targeted announce
|
||||
peripheral.writeValue(data, for: characteristic, type: .withResponse)
|
||||
let writeType: CBCharacteristicWriteType = characteristic.properties.contains(.write) ? .withResponse : .withoutResponse
|
||||
peripheral.writeValue(data, for: characteristic, type: writeType)
|
||||
} else {
|
||||
// No peripheral found for targeted send
|
||||
}
|
||||
@@ -768,10 +773,10 @@ class BluetoothMeshService: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
// Create stored message
|
||||
// Create stored message with original packet timestamp preserved
|
||||
let storedMessage = StoredMessage(
|
||||
packet: packet,
|
||||
timestamp: Date(),
|
||||
timestamp: Date(timeIntervalSince1970: TimeInterval(packet.timestamp)),
|
||||
messageID: messageID,
|
||||
isForFavorite: isForFavorite
|
||||
)
|
||||
@@ -850,21 +855,14 @@ class BluetoothMeshService: NSObject {
|
||||
guard let peripheral = peripheral,
|
||||
peripheral.state == .connected else { return }
|
||||
|
||||
// Create a new packet with fresh timestamp
|
||||
let updatedPacket = BitchatPacket(
|
||||
type: storedMessage.packet.type,
|
||||
senderID: storedMessage.packet.senderID,
|
||||
recipientID: storedMessage.packet.recipientID,
|
||||
timestamp: UInt64(Date().timeIntervalSince1970),
|
||||
payload: storedMessage.packet.payload,
|
||||
signature: storedMessage.packet.signature,
|
||||
ttl: storedMessage.packet.ttl
|
||||
)
|
||||
// Send the original packet with preserved timestamp
|
||||
// This maintains message ordering for store-and-forward
|
||||
let packetToSend = storedMessage.packet
|
||||
|
||||
if let data = updatedPacket.toBinaryData(),
|
||||
if let data = packetToSend.toBinaryData(),
|
||||
characteristic.properties.contains(.writeWithoutResponse) {
|
||||
peripheral.writeValue(data, for: characteristic, type: .withoutResponse)
|
||||
// Sent cached message
|
||||
// Sent cached message with original timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1020,7 +1018,10 @@ class BluetoothMeshService: NSObject {
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
print("[CRYPTO] Failed to verify signature from \(senderID): \(error)")
|
||||
if !loggedCryptoErrors.contains(senderID) {
|
||||
print("[CRYPTO] Failed to verify signature from \(senderID): \(error)")
|
||||
loggedCryptoErrors.insert(senderID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,7 +1085,10 @@ class BluetoothMeshService: NSObject {
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
print("[CRYPTO] Failed to verify signature from \(senderID): \(error)")
|
||||
if !loggedCryptoErrors.contains(senderID) {
|
||||
print("[CRYPTO] Failed to verify signature from \(senderID): \(error)")
|
||||
loggedCryptoErrors.insert(senderID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user