feat: update optimizations

This commit is contained in:
2026-05-04 13:18:03 +02:00
parent f5e5c3904f
commit 9b672a7503
4 changed files with 60 additions and 1 deletions

View File

@ -363,6 +363,27 @@ class BluetoothController {
} }
} }
Future<Result<void>> requestHighPerformanceConnection(
String deviceId,
) async {
if (defaultTargetPlatform != TargetPlatform.android) {
return Ok(null);
}
try {
await _ble.requestConnectionPriority(
deviceId: deviceId,
priority: ConnectionPriority.highPerformance,
);
log.info('High-performance BLE connection requested for $deviceId');
return Ok(null);
} catch (e) {
return bail(
'Error requesting high-performance BLE connection for $deviceId: $e',
);
}
}
Future<Result<void>> _requestInitialMtu(String deviceId) async { Future<Result<void>> _requestInitialMtu(String deviceId) async {
if (defaultTargetPlatform != TargetPlatform.android) { if (defaultTargetPlatform != TargetPlatform.android) {
return Ok(null); return Ok(null);

View File

@ -45,7 +45,7 @@ const int universalShifterBootloaderDfuMaxPayloadSizeBytes =
universalShifterBootloaderDfuDataHeaderSizeBytes; universalShifterBootloaderDfuDataHeaderSizeBytes;
const int universalShifterBootloaderDfuStatusSizeBytes = 6; const int universalShifterBootloaderDfuStatusSizeBytes = 6;
const int universalShifterAttWriteOverheadBytes = 3; const int universalShifterAttWriteOverheadBytes = 3;
const int universalShifterDfuPreferredMtu = 128; const int universalShifterDfuPreferredMtu = 131;
const int universalShifterDfuAppStart = 0x00030000; const int universalShifterDfuAppStart = 0x00030000;
const int universalShifterDfuAppSlotSizeBytes = 0x0003F000; const int universalShifterDfuAppSlotSizeBytes = 0x0003F000;

View File

@ -148,6 +148,8 @@ class FirmwareUpdateService {
await _connectToBootloader(timeout: effectiveBootloaderConnectTimeout); await _connectToBootloader(timeout: effectiveBootloaderConnectTimeout);
} }
await _optimizeBootloaderConnection();
final mtuResult = final mtuResult =
await _transport.negotiateMtu(requestedMtu: requestedMtu); await _transport.negotiateMtu(requestedMtu: requestedMtu);
if (mtuResult.isErr()) { if (mtuResult.isErr()) {
@ -455,6 +457,13 @@ class FirmwareUpdateService {
} }
} }
Future<void> _optimizeBootloaderConnection() async {
final result = await _transport.optimizeBootloaderConnection();
if (result.isErr()) {
_emitProgress(errorMessage: result.unwrapErr().toString());
}
}
Future<DfuBootloaderStatus> _sendStartAndWaitForStatus( Future<DfuBootloaderStatus> _sendStartAndWaitForStatus(
BootloaderDfuStartPayload payload, { BootloaderDfuStartPayload payload, {
required Duration timeout, required Duration timeout,
@ -481,6 +490,7 @@ class FirmwareUpdateService {
errorMessage: failure.message, errorMessage: failure.message,
); );
await _connectToBootloader(timeout: bootloaderConnectTimeout); await _connectToBootloader(timeout: bootloaderConnectTimeout);
await _optimizeBootloaderConnection();
await _subscribeToStatus(); await _subscribeToStatus();
_emitProgress(state: DfuUpdateState.waitingForStatus); _emitProgress(state: DfuUpdateState.waitingForStatus);
return _requestStatus(timeout: timeout); return _requestStatus(timeout: timeout);
@ -746,6 +756,8 @@ abstract interface class FirmwareUpdateTransport {
Future<Result<void>> connectToBootloader({required Duration timeout}); Future<Result<void>> connectToBootloader({required Duration timeout});
Future<Result<void>> optimizeBootloaderConnection();
Future<Result<int>> negotiateMtu({required int requestedMtu}); Future<Result<int>> negotiateMtu({required int requestedMtu});
Stream<List<int>> subscribeToStatus(); Stream<List<int>> subscribeToStatus();
@ -832,6 +844,17 @@ class ShifterFirmwareUpdateTransport implements FirmwareUpdateTransport {
); );
} }
@override
Future<Result<void>> optimizeBootloaderConnection() {
final deviceId = _requireBootloaderDeviceId();
if (deviceId.isErr()) {
return Future.value(Err(deviceId.unwrapErr()));
}
return bluetoothController.requestHighPerformanceConnection(
deviceId.unwrap(),
);
}
@override @override
Future<Result<int>> negotiateMtu({required int requestedMtu}) { Future<Result<int>> negotiateMtu({required int requestedMtu}) {
final deviceId = _requireBootloaderDeviceId(); final deviceId = _requireBootloaderDeviceId();

View File

@ -28,6 +28,7 @@ void main() {
'enterBootloader', 'enterBootloader',
'waitForAppDisconnect', 'waitForAppDisconnect',
'connectToBootloader', 'connectToBootloader',
'optimizeBootloaderConnection',
'negotiateMtu', 'negotiateMtu',
'readStatus', 'readStatus',
'waitForBootloaderDisconnect', 'waitForBootloaderDisconnect',
@ -68,6 +69,7 @@ void main() {
expect(result.isOk(), isTrue); expect(result.isOk(), isTrue);
expect(transport.steps, [ expect(transport.steps, [
'isConnectedToBootloader', 'isConnectedToBootloader',
'optimizeBootloaderConnection',
'negotiateMtu', 'negotiateMtu',
'readStatus', 'readStatus',
'waitForBootloaderDisconnect', 'waitForBootloaderDisconnect',
@ -162,6 +164,12 @@ void main() {
transport.steps.where((step) => step == 'connectToBootloader').length, transport.steps.where((step) => step == 'connectToBootloader').length,
2, 2,
); );
expect(
transport.steps
.where((step) => step == 'optimizeBootloaderConnection')
.length,
2,
);
expect( expect(
transport.controlWrites transport.controlWrites
.where((write) => write.first == universalShifterDfuOpcodeGetStatus) .where((write) => write.first == universalShifterDfuOpcodeGetStatus)
@ -344,9 +352,16 @@ class _FakeFirmwareUpdateTransport implements FirmwareUpdateTransport {
return Ok(null); return Ok(null);
} }
@override
Future<Result<void>> optimizeBootloaderConnection() async {
steps.add('optimizeBootloaderConnection');
return Ok(null);
}
@override @override
Future<Result<int>> negotiateMtu({required int requestedMtu}) async { Future<Result<int>> negotiateMtu({required int requestedMtu}) async {
steps.add('negotiateMtu'); steps.add('negotiateMtu');
expect(requestedMtu, universalShifterDfuPreferredMtu);
return Ok(128); return Ok(128);
} }