using BluetoothLENet; using InABox.Core; namespace InABox.Avalonia.Platform.Desktop; public class Desktop_Bluetooth : IBluetooth, IDisposable { public Logger? Logger { get; set; } private BLE _adapter; public Action? DeviceFound { get; set; } public CoreObservableCollection Devices { get; } = new(); public event EventHandler? Changed; public Desktop_Bluetooth() { Devices.CollectionChanged += (_,_) => Changed?.Invoke(this, EventArgs.Empty); ResetAdapter(); } private void ResetAdapter() { _adapter = new BLE(); _adapter.Changed += (_,_) => { try { var found = _adapter.Devices.Select(x => (x.MacAddress,x.ManufacturerData)).ToArray(); var cache = Devices.OfType().Select(x => (x.ID,x.ManufacturerData)).ToArray(); if (found.Except(cache).Any() || cache.Except(found).Any()) { var devices = _adapter.Devices .ToArray() .Select(x => new Desktop_BluetoothDevice(x)) .ToArray(); Console.WriteLine($"BLE:Found {devices.Length} devices"); Devices.ReplaceRange(devices); Console.WriteLine($"BLE:Triggering Changed()"); Changed?.Invoke(this, EventArgs.Empty); } else Changed?.Invoke(this, EventArgs.Empty); } catch (Exception e) { Logger?.Send(LogType.Error, "", $"{e.Message}\n{e.StackTrace}"); } }; } public async Task IsAvailable() { return await Task.FromResult(true); } public async Task StartScanningAsync(Guid configServiceId) { ResetAdapter(); if (await IsAvailable()) return await _adapter.StartScanningAsync(configServiceId); return false; } public async Task StopScanningAsync() { if (await IsAvailable()) return await _adapter.StopScanningAsync(); return false; } public async Task Connect(IBluetoothDevice device) { if (await IsAvailable()) { if (device is Desktop_BluetoothDevice d) { var result = await _adapter.Connect(d.Device); if (result == ConnectDeviceResult.Ok) return new Desktop_ConnectedBluetoothDevice(d.Device); } } return null; } public async Task Disconnect(IConnectedBluetoothDevice device) { if (await IsAvailable()) { if (device is Desktop_BluetoothDevice { Device: not null } d) { _adapter.Disconnect(d.Device); await Task.Delay(1000); } } return true; } public void Dispose() { foreach (var device in Devices) device.Dispose(); Devices.Clear(); } }