chrome connect

This commit is contained in:
Ben Allfree
2026-02-22 08:31:29 -08:00
parent 6ac987e7cf
commit 452e5337f0
+42 -19
View File
@@ -837,11 +837,17 @@ class MeshCoreConnector extends ChangeNotifier {
); );
// Request larger MTU for sending larger frames // Request larger MTU for sending larger frames
try { if (!PlatformInfo.isWeb) {
final mtu = await device.requestMtu(185); try {
debugPrint('MTU set to: $mtu'); final mtu = await device.requestMtu(185);
} catch (e) { debugPrint('MTU set to: $mtu');
debugPrint('MTU request failed: $e, using default'); } catch (e) {
debugPrint('MTU request failed: $e, using default');
}
} else {
// On Chrome Web Bluetooth, give the GATT connection a moment to settle
// before discovering services, which is a common quirk to avoid timeouts.
await Future.delayed(const Duration(milliseconds: 500));
} }
List<BluetoothService> services = await device.discoverServices(); List<BluetoothService> services = await device.discoverServices();
@@ -871,20 +877,7 @@ class MeshCoreConnector extends ChangeNotifier {
throw Exception("MeshCore characteristics not found"); throw Exception("MeshCore characteristics not found");
} }
// Retry setNotifyValue with increasing delays // Setup listener BEFORE enabling notifications so we don't miss anything
bool notifySet = false;
for (int attempt = 0; attempt < 3 && !notifySet; attempt++) {
try {
if (attempt > 0) {
await Future.delayed(Duration(milliseconds: 500 * attempt));
}
await _txCharacteristic!.setNotifyValue(true);
notifySet = true;
} catch (e) {
debugPrint('setNotifyValue attempt ${attempt + 1}/3 failed: $e');
if (attempt == 2) rethrow;
}
}
_notifySubscription = _txCharacteristic!.onValueReceived.listen( _notifySubscription = _txCharacteristic!.onValueReceived.listen(
_handleFrame, _handleFrame,
onError: (Object e) { onError: (Object e) {
@@ -892,6 +885,36 @@ class MeshCoreConnector extends ChangeNotifier {
}, },
); );
debugPrint('Starting setNotifyValue(true)');
if (PlatformInfo.isWeb) {
// On Web, setNotifyValue often hangs indefinitely on the Promise resolution.
// We trigger it but don't await its completion to avoid blocking the connection flow.
debugPrint('Web: Calling setNotifyValue(true) without awaiting');
// ignore: unawaited_futures
_txCharacteristic!.setNotifyValue(true).catchError((e) {
debugPrint('Web setNotifyValue error (ignoring): $e');
});
// Give the browser a moment to process the underlying startNotifications call
await Future.delayed(const Duration(milliseconds: 500));
} else {
// Native platforms handle setNotifyValue blockingly with CCCD descriptors
bool notifySet = false;
for (int attempt = 0; attempt < 3 && !notifySet; attempt++) {
try {
if (attempt > 0) {
await Future.delayed(Duration(milliseconds: 500 * attempt));
}
debugPrint('Calling setNotifyValue(true), attempt ${attempt + 1}');
await _txCharacteristic!.setNotifyValue(true);
notifySet = true;
} catch (e) {
debugPrint('setNotifyValue attempt ${attempt + 1}/3 failed: $e');
if (attempt == 2) rethrow;
}
}
}
debugPrint('setNotifyValue(true) configuration completed');
_setState(MeshCoreConnectionState.connected); _setState(MeshCoreConnectionState.connected);
await _requestDeviceInfo(); await _requestDeviceInfo();