| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- /// A Bluetooth Classic device already paired with the tablet.
- ///
- /// [deviceClass] is Android's class-of-device value. CarDash uses it to keep
- /// phones, headsets and other non-SPP devices out of the default OBD-II
- /// adapter list. Devices with no class information stay visible; hiding a real
- /// adapter would be worse than showing an extra device.
- class BluetoothDeviceInfo {
- const BluetoothDeviceInfo({
- required this.name,
- required this.address,
- this.deviceClass,
- this.uuids = const [],
- });
- static const _sppUuid = '00001101-0000-1000-8000-00805f9b34fb';
- /// Names commonly used by ELM327 and compatible OBD-II adapters.
- static const _obdNameHints = <String>[
- 'obd',
- 'elm',
- 'vlink',
- 'v-link',
- 'vgate',
- 'v-gate',
- 'veepeak',
- 'bafx',
- 'obdlink',
- 'scantool',
- 'konnwei',
- 'autel',
- 'car scanner',
- ];
- /// Android major device classes that can plausibly carry an SPP ELM327.
- static const _likelyMajorClasses = <int>{
- 0x0000, // Miscellaneous
- 0x0100, // Computer
- 0x0300, // Networking / LAN access
- 0x1F00, // Uncategorized
- };
- final String name;
- final String address;
- final int? deviceClass;
- /// Cached SDP UUIDs, when Android already has them.
- final List<String> uuids;
- factory BluetoothDeviceInfo.fromMap(Map<dynamic, dynamic> map) {
- final rawUuids = map['uuids'];
- return BluetoothDeviceInfo(
- name: (map['name'] as String?)?.trim() ?? 'Unknown device',
- address: (map['address'] as String?) ?? '',
- deviceClass: (map['deviceClass'] as num?)?.toInt(),
- uuids: rawUuids is List
- ? rawUuids
- .whereType<String>()
- .map((uuid) => uuid.toLowerCase())
- .toList(growable: false)
- : const [],
- );
- }
- int? get majorClass => deviceClass == null ? null : deviceClass! & 0x1F00;
- bool get hasSppService => uuids.contains(_sppUuid);
- bool get hasObdName {
- final normalized = name.toLowerCase();
- return _obdNameHints.any(normalized.contains);
- }
- /// Whether the adapter is likely to be a Bluetooth Classic OBD-II device.
- ///
- /// A recognised name or the SPP service UUID always wins. Otherwise the
- /// Android major class decides; unknown class information is treated as
- /// possibly usable so a real adapter is never hidden.
- bool get isLikelyObd {
- if (hasObdName || hasSppService) return true;
- final major = majorClass;
- if (major == null) return true;
- return _likelyMajorClasses.contains(major);
- }
- String get label => name.isEmpty ? address : '$name · $address';
- }
|