Fix remaining Bluetooth write errors

- Check characteristic write properties before all writes
- Add proper error handling for specific BLE error codes
- Rediscover services on invalid handle errors
- Increase delay between key exchange and announce
- Reduce connection flooding by spacing out initial messages

The ATT Error 242 was caused by writing too quickly after
connection establishment. Adding delays gives the connection
time to stabilize.
This commit is contained in:
jack
2025-07-04 14:36:15 +02:00
parent 7b3cfb6227
commit 31abe1a1ce
2 changed files with 27 additions and 5 deletions
+6
View File
@@ -255,6 +255,7 @@
DEVELOPMENT_TEAM = L3N5LHJD5Y;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = bitchat/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = bitchat;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
@@ -286,6 +287,7 @@
DEVELOPMENT_TEAM = L3N5LHJD5Y;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = bitchat/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = bitchat;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
@@ -316,6 +318,8 @@
COMBINE_HIDPI_IMAGES = YES;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = bitchat/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = bitchat;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -399,6 +403,8 @@
COMBINE_HIDPI_IMAGES = YES;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = bitchat/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = bitchat;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
+21 -5
View File
@@ -1716,15 +1716,16 @@ extension BluetoothMeshService: CBPeripheralDelegate {
)
if let data = packet.toBinaryData() {
peripheral.writeValue(data, for: characteristic, type: .withResponse)
let writeType: CBCharacteristicWriteType = characteristic.properties.contains(.write) ? .withResponse : .withoutResponse
peripheral.writeValue(data, for: characteristic, type: writeType)
// Sent key exchange
}
// Send announce packet immediately after key exchange
// Send announce packet after a short delay to avoid overwhelming the connection
// Send multiple times for reliability
if let vm = self.delegate as? ChatViewModel {
// Send announces multiple times with delays
for delay in [0.1, 0.5, 1.0] {
for delay in [0.3, 0.8, 1.5] {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
guard let self = self else { return }
let announcePacket = BitchatPacket(
@@ -1751,7 +1752,8 @@ extension BluetoothMeshService: CBPeripheralDelegate {
payload: Data(vm.nickname.utf8)
)
if let data = announcePacket.toBinaryData() {
peripheral.writeValue(data, for: characteristic, type: .withResponse)
let writeType: CBCharacteristicWriteType = characteristic.properties.contains(.write) ? .withResponse : .withoutResponse
peripheral.writeValue(data, for: characteristic, type: writeType)
// Sent targeted announce
}
}
@@ -1782,7 +1784,21 @@ extension BluetoothMeshService: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
if let error = error {
print("[ERROR] Write failed: \(error)")
// Handle specific BLE errors
if let bleError = error as? CBATTError {
switch bleError.code {
case .invalidHandle, .invalidPdu, .insufficientAuthorization:
// Characteristic might be invalid, rediscover services
peripheral.discoverServices([BluetoothMeshService.serviceUUID])
case .connectionTimeout, .linkLost:
// Connection issue, will be handled by disconnect
break
default:
print("[ERROR] Write failed: \(error)")
}
} else {
print("[ERROR] Write failed: \(error)")
}
} else {
// Write completed
}