Desktop_Bluetooth.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using BluetoothLENet;
  2. using InABox.Core;
  3. namespace InABox.Avalonia.Platform.Desktop;
  4. public class Desktop_Bluetooth : IBluetooth, IDisposable
  5. {
  6. public Logger? Logger { get; set; }
  7. private BLE _adapter;
  8. public Action<IBluetoothDevice>? DeviceFound { get; set; }
  9. public CoreObservableCollection<IBluetoothDevice> Devices { get; } = new();
  10. public event EventHandler? Changed;
  11. public Desktop_Bluetooth()
  12. {
  13. Devices.CollectionChanged += (_,_) => Changed?.Invoke(this, EventArgs.Empty);
  14. ResetAdapter();
  15. }
  16. private void ResetAdapter()
  17. {
  18. _adapter = new BLE();
  19. _adapter.Changed += (_,_) =>
  20. {
  21. try
  22. {
  23. var found = _adapter.Devices.Select(x => (x.MacAddress,x.ManufacturerData)).ToArray();
  24. var cache = Devices.OfType<Desktop_BluetoothDevice>().Select(x => (x.ID,x.ManufacturerData)).ToArray();
  25. if (found.Except(cache).Any() || cache.Except(found).Any())
  26. {
  27. var devices = _adapter.Devices
  28. .ToArray()
  29. .Select(x => new Desktop_BluetoothDevice(x))
  30. .ToArray();
  31. Console.WriteLine($"BLE:Found {devices.Length} devices");
  32. Devices.ReplaceRange(devices);
  33. Console.WriteLine($"BLE:Triggering Changed()");
  34. Changed?.Invoke(this, EventArgs.Empty);
  35. }
  36. else
  37. Changed?.Invoke(this, EventArgs.Empty);
  38. }
  39. catch (Exception e)
  40. {
  41. Logger?.Send(LogType.Error, "", $"{e.Message}\n{e.StackTrace}");
  42. }
  43. };
  44. }
  45. public async Task<bool> IsAvailable()
  46. {
  47. return await Task.FromResult(true);
  48. }
  49. public async Task<bool> StartScanningAsync(Guid configServiceId)
  50. {
  51. ResetAdapter();
  52. if (await IsAvailable())
  53. return await _adapter.StartScanningAsync(configServiceId);
  54. return false;
  55. }
  56. public async Task<bool> StopScanningAsync()
  57. {
  58. if (await IsAvailable())
  59. return await _adapter.StopScanningAsync();
  60. return false;
  61. }
  62. public async Task<IConnectedBluetoothDevice?> Connect(IBluetoothDevice device)
  63. {
  64. if (await IsAvailable())
  65. {
  66. if (device is Desktop_BluetoothDevice d)
  67. {
  68. var result = await _adapter.Connect(d.Device);
  69. if (result == ConnectDeviceResult.Ok)
  70. return new Desktop_ConnectedBluetoothDevice(d.Device);
  71. }
  72. }
  73. return null;
  74. }
  75. public async Task<bool> Disconnect(IConnectedBluetoothDevice device)
  76. {
  77. if (await IsAvailable())
  78. {
  79. if (device is Desktop_BluetoothDevice { Device: not null } d)
  80. {
  81. _adapter.Disconnect(d.Device);
  82. await Task.Delay(1000);
  83. }
  84. }
  85. return true;
  86. }
  87. public void Dispose()
  88. {
  89. foreach (var device in Devices)
  90. device.Dispose();
  91. Devices.Clear();
  92. }
  93. }