feat: redesign and lots of progress
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:anyhow/anyhow.dart';
|
||||
import 'package:flutter/foundation.dart'
|
||||
show TargetPlatform, defaultTargetPlatform;
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'
|
||||
hide ConnectionStatus, Result, Logger;
|
||||
@ -173,9 +175,6 @@ class BluetoothController {
|
||||
(currentState.$1 == ConnectionStatus.connected ||
|
||||
currentState.$1 == ConnectionStatus.connecting)) {
|
||||
log.info('Already connected or connecting to $deviceId.');
|
||||
if (currentState.$1 == ConnectionStatus.connected) {
|
||||
unawaited(_requestMtuOnConnect(deviceId));
|
||||
}
|
||||
return Ok(null);
|
||||
}
|
||||
|
||||
@ -191,6 +190,7 @@ class BluetoothController {
|
||||
try {
|
||||
await _connectionStateSubscription?.cancel();
|
||||
_updateConnectionState(ConnectionStatus.connecting, deviceId);
|
||||
final connectionResult = Completer<Result<void>>();
|
||||
|
||||
_connectionStateSubscription = _ble
|
||||
.connectToDevice(
|
||||
@ -199,12 +199,21 @@ class BluetoothController {
|
||||
servicesWithCharacteristicsToDiscover:
|
||||
servicesWithCharacteristicsToDiscover,
|
||||
)
|
||||
.listen((update) {
|
||||
.listen((update) async {
|
||||
switch (update.connectionState) {
|
||||
case DeviceConnectionState.connected:
|
||||
_connectedDeviceId = deviceId;
|
||||
_updateConnectionState(ConnectionStatus.connected, deviceId);
|
||||
unawaited(_requestMtuOnConnect(deviceId));
|
||||
if (!connectionResult.isCompleted) {
|
||||
final mtuResult = await _requestInitialMtu(deviceId);
|
||||
if (mtuResult.isErr()) {
|
||||
log.warning(
|
||||
'Initial MTU request failed for $deviceId: '
|
||||
'${mtuResult.unwrapErr()}',
|
||||
);
|
||||
}
|
||||
connectionResult.complete(Ok(null));
|
||||
}
|
||||
break;
|
||||
case DeviceConnectionState.connecting:
|
||||
_updateConnectionState(ConnectionStatus.connecting, deviceId);
|
||||
@ -214,14 +223,31 @@ class BluetoothController {
|
||||
break;
|
||||
case DeviceConnectionState.disconnected:
|
||||
_cleanUpConnection();
|
||||
if (!connectionResult.isCompleted) {
|
||||
connectionResult.complete(
|
||||
bail('Failed to connect to $deviceId: disconnected'),
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}, onError: (Object error, StackTrace st) {
|
||||
log.severe('Failed to connect to $deviceId: $error', error, st);
|
||||
_cleanUpConnection();
|
||||
if (!connectionResult.isCompleted) {
|
||||
connectionResult.complete(
|
||||
bail('Failed to connect to $deviceId: $error'),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return Ok(null);
|
||||
try {
|
||||
return await connectionResult.future.timeout(timeout);
|
||||
} on TimeoutException {
|
||||
await _connectionStateSubscription?.cancel();
|
||||
_connectionStateSubscription = null;
|
||||
_cleanUpConnection();
|
||||
return bail('Timed out connecting to $deviceId');
|
||||
}
|
||||
} catch (e) {
|
||||
_cleanUpConnection();
|
||||
return bail('Failed to connect to $deviceId: $e');
|
||||
@ -301,7 +327,7 @@ class BluetoothController {
|
||||
{int mtu = defaultMtu}) async {
|
||||
final result = await requestMtuAndGetValue(deviceId, mtu: mtu);
|
||||
if (result.isErr()) {
|
||||
return bail(result.unwrapErr());
|
||||
return Err(result.unwrapErr());
|
||||
}
|
||||
return Ok(null);
|
||||
}
|
||||
@ -310,6 +336,10 @@ class BluetoothController {
|
||||
{int mtu = defaultMtu}) async {
|
||||
try {
|
||||
final negotiatedMtu = await _ble.requestMtu(deviceId: deviceId, mtu: mtu);
|
||||
if (negotiatedMtu <= 0) {
|
||||
return bail(
|
||||
'Error requesting MTU $mtu for $deviceId: negotiated invalid MTU $negotiatedMtu');
|
||||
}
|
||||
log.info(
|
||||
'MTU negotiated for $deviceId: requested $mtu, got $negotiatedMtu');
|
||||
return Ok(negotiatedMtu);
|
||||
@ -318,12 +348,11 @@ class BluetoothController {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _requestMtuOnConnect(String deviceId) async {
|
||||
final mtuResult = await requestMtu(deviceId, mtu: defaultMtu);
|
||||
if (mtuResult.isErr()) {
|
||||
log.warning(
|
||||
'MTU request after connect failed for $deviceId: ${mtuResult.unwrapErr()}');
|
||||
Future<Result<void>> _requestInitialMtu(String deviceId) async {
|
||||
if (defaultTargetPlatform != TargetPlatform.android) {
|
||||
return Ok(null);
|
||||
}
|
||||
return requestMtu(deviceId, mtu: defaultMtu);
|
||||
}
|
||||
|
||||
Stream<List<int>> subscribeToCharacteristic(
|
||||
|
||||
Reference in New Issue
Block a user