import 'bluetooth_device_info.dart'; /// Praefix, an dem der mLRS-Backpack in seinem Bluetooth-Namen erkannt wird /// (Doku Kommunikationsschicht Abschnitt 3.2). const mLrsDeviceNamePrefix = 'mLRS'; /// Ergebnis der automatischen Geraeteauswahl (Doku Abschnitt 3.2): entweder /// ein eindeutig bestimmtes Geraet, oder die Angabe, dass die Oberflaeche /// eine Auswahlliste zeigen muss. sealed class BluetoothDeviceSelection { const BluetoothDeviceSelection(); } class BluetoothDeviceResolved extends BluetoothDeviceSelection { const BluetoothDeviceResolved(this.device); final BluetoothDeviceInfo device; } class BluetoothDeviceSelectionRequired extends BluetoothDeviceSelection { const BluetoothDeviceSelectionRequired(this.candidates); /// Gekoppelte Geraete, aus denen die Oberflaeche eine Auswahl anbieten /// muss (Doku 3.2c). final List candidates; } /// Reine Auswahllogik, unabhaengig vom Bluetooth-Plugin und ohne /// Plattform-Channel - daher ohne Hardware testbar. /// /// Reihenfolge (Doku Abschnitt 3.2): /// a) gemerkte MAC-Adresse aus den Einstellungen (falls noch gekoppelt) /// b) erstes gekoppeltes Geraet, dessen Name mit "mLRS" beginnt /// c) sonst: Auswahlliste anzeigen BluetoothDeviceSelection selectBluetoothDevice({ required List bondedDevices, String? rememberedAddress, }) { if (rememberedAddress != null) { final remembered = _firstWhereOrNull( bondedDevices, (d) => d.address == rememberedAddress, ); if (remembered != null) return BluetoothDeviceResolved(remembered); } final mLrsDevice = _firstWhereOrNull( bondedDevices, (d) => (d.name ?? '').startsWith(mLrsDeviceNamePrefix), ); if (mLrsDevice != null) return BluetoothDeviceResolved(mLrsDevice); return BluetoothDeviceSelectionRequired(bondedDevices); } BluetoothDeviceInfo? _firstWhereOrNull( List devices, bool Function(BluetoothDeviceInfo) test, ) { for (final device in devices) { if (test(device)) return device; } return null; }