diff --git a/lib/model/shifter_types.dart b/lib/model/shifter_types.dart index de25140..8ab3c51 100644 --- a/lib/model/shifter_types.dart +++ b/lib/model/shifter_types.dart @@ -1,5 +1,7 @@ import 'dart:convert'; +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; + const String universalShifterControlServiceUuid = '0993826f-0ee4-4b37-9614-d13ecba4ffc2'; const String universalShifterStatusCharacteristicUuid = @@ -25,6 +27,10 @@ const String deviceInformationServiceUuid = const String firmwareRevisionCharacteristicUuid = '00002a26-0000-1000-8000-00805f9b34fb'; +bool isFtmsUuid(Uuid uuid) { + return uuid.expanded == Uuid.parse(ftmsServiceUuid).expanded; +} + const int universalShifterDfuOpcodeStart = 0x01; const int universalShifterDfuOpcodeFinish = 0x02; const int universalShifterDfuOpcodeAbort = 0x03; diff --git a/lib/widgets/bike_scan_dialog.dart b/lib/widgets/bike_scan_dialog.dart index aa03ccb..dc249e7 100644 --- a/lib/widgets/bike_scan_dialog.dart +++ b/lib/widgets/bike_scan_dialog.dart @@ -137,8 +137,7 @@ class _BikeScanDialogState extends ConsumerState { const SizedBox(height: 12), itemBuilder: (context, index) { final device = devices[index]; - final isFtms = device.serviceUuids - .contains(Uuid.parse(ftmsServiceUuid)); + final isFtms = _advertisesFtms(device); return Material( color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(22), @@ -268,7 +267,6 @@ class _BikeScanDialogState extends ConsumerState { } List _filteredDevices(List devices) { - final ftmsUuid = Uuid.parse(ftmsServiceUuid); return devices.where((device) { if (device.id == widget.excludedDeviceId) { return false; @@ -276,9 +274,14 @@ class _BikeScanDialogState extends ConsumerState { if (_showAll) { return true; } - return device.serviceUuids.contains(ftmsUuid); + return _advertisesFtms(device); }).toList(growable: false); } + + bool _advertisesFtms(DiscoveredDevice device) { + return device.serviceUuids.any(isFtmsUuid) || + device.serviceData.keys.any(isFtmsUuid); + } } class _DialogHeader extends StatelessWidget { diff --git a/test/model/shifter_types_test.dart b/test/model/shifter_types_test.dart index 323dd39..b27237f 100644 --- a/test/model/shifter_types_test.dart +++ b/test/model/shifter_types_test.dart @@ -1,7 +1,16 @@ import 'package:abawo_bt_app/model/shifter_types.dart'; +import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { + group('isFtmsUuid', () { + test('matches 16-bit and expanded FTMS UUIDs', () { + expect(isFtmsUuid(Uuid.parse('1826')), isTrue); + expect(isFtmsUuid(Uuid.parse(ftmsServiceUuid)), isTrue); + expect(isFtmsUuid(Uuid.parse('180f')), isFalse); + }); + }); + group('CentralStatus.fromBytes', () { test('decodes status with FTMS ready', () { final status = CentralStatus.fromBytes(