123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- using InABox.Core;
- using Plugin.BLE;
- using Plugin.BLE.Abstractions;
- using Plugin.BLE.Abstractions.Contracts;
- using Plugin.BLE.Abstractions.EventArgs;
- using System;
- using System.Linq;
- using System.Threading.Tasks;
- namespace InABox.Avalonia.Platform.iOS;
- public class iOS_Bluetooth : IBluetooth
- {
- public Logger? Logger { get; set; }
- public event EventHandler? Changed;
- public CoreObservableCollection<IBluetoothDevice> Devices { get; } = new ();
-
- private IBluetoothLE _ble;
- private IAdapter _adapter;
- private ScanFilterOptions _scanoptions = new ScanFilterOptions();
- private StaleItemMonitor<IBluetoothDevice> _staleItemMonitor;
- public iOS_Bluetooth()
- {
-
- _staleItemMonitor = new StaleItemMonitor<IBluetoothDevice>(
- Devices,
- x=>x.LastSeen,
- x =>x.ID,
- TimeSpan.FromSeconds(10),
- TimeSpan.FromMilliseconds(500)
- );
-
- _ble = CrossBluetoothLE.Current;
- _adapter = CrossBluetoothLE.Current.Adapter;
- _adapter.ScanTimeout = 5000;
- _adapter.ScanTimeoutElapsed += async (sender, args) => { await _adapter.StartScanningForDevicesAsync(_scanoptions); };
- _adapter.DeviceDiscovered += AdapterOnDeviceDiscovered;
- //_adapter.ScanMatchMode = ScanMatchMode.AGRESSIVE;
- //_adapter.ScanMode = ScanMode.LowLatency;
-
- // Task.Run(() =>
- // {
- // while (true)
- // {
- // var stale = Devices.ToArray().Where(x => (x == null) || (x.LastSeen < DateTime.Now.Subtract(new TimeSpan(0, 0, 10))))
- // .ToArray();
- // if (stale.Any())
- // {
- // Devices.RemoveRange(stale);
- // Changed?.Invoke(this, EventArgs.Empty);
- // }
- //
- // Task.Delay(500);
- // }
- // });
- }
-
- // public static async Task<bool> IsPermitted<TPermission>() where TPermission : Permissions.BasePermission, new()
- // {
- // try
- // {
- // PermissionStatus status = await Permissions.CheckStatusAsync<TPermission>();
- // if (status == PermissionStatus.Granted)
- // return true;
- // var request = await Permissions.RequestAsync<TPermission>();
- // return request == PermissionStatus.Granted;
- //
- // }
- // catch (TaskCanceledException ex)
- // {
- // return false;
- // }
- // }
-
- public async Task<bool> IsAvailable()
- {
- //if (await IsPermitted<Permissions.Bluetooth>())
- //{
- //}
- return _adapter != null;
- }
- public async Task<bool> StartScanningAsync(Guid configServiceId)
- {
-
- _scanoptions.ServiceUuids = [configServiceId];
- return await StartScanningAsync();
- }
- private async Task<bool> StartScanningAsync()
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Starting Bluetooth Scanning...");
- await _staleItemMonitor.StartAsync();
- await _adapter.StartScanningForDevicesAsync(_scanoptions);
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Bluetooth Scanning Started.");
- return true;
- }
- private void AdapterOnDeviceDiscovered(object? sender, DeviceEventArgs e)
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Found device {e.Device.Name}...");
- var device = Devices.FirstOrDefault(x => string.Equals(x.ID, e.Device.Id.ToString()));
- if (device == null)
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Adding device {e.Device.Id}...");
- device = new iOS_BluetoothDevice(e.Device);
- Devices.Add(device);
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Added device {device.ID}.");
- }
- device.LastSeen = DateTime.Now;
- device.ManufacturerData = e.Device.AdvertisementRecords
- .FirstOrDefault(x => x.Type == AdvertisementRecordType.ManufacturerSpecificData)?.Data ?? [];
-
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Notifying Changes...");
- Changed?.Invoke(this, EventArgs.Empty);
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Changes Notified.");
- }
-
- public async Task<bool> StopScanningAsync()
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Stopping Bluetooth Scanning...");
- await _staleItemMonitor.StopAsync();
- await _adapter.StopScanningForDevicesAsync();
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Bluetooth Scanning Stopped.");
- return true;
- }
- public async Task<IConnectedBluetoothDevice?> Connect(IBluetoothDevice device)
- {
- if (Guid.TryParse(device.ID, out var deviceid))
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Connecting Bluetooth Device {device.ID}...");
- await StopScanningAsync();
- var connected = await _adapter.ConnectToKnownDeviceAsync(deviceid);
- if (connected != null)
- {
- var result = new iOS_ConnectedBluetoothDevice(device);
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Bluetooth Device {device.ID} connected.");
- return result;
- }
- await StartScanningAsync();
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Connection to {device.ID} failed.");
- }
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Device has invalid ID.");
- return null;
- }
- public async Task<bool> Disconnect(IConnectedBluetoothDevice device)
- {
- if (device is iOS_ConnectedBluetoothDevice connected)
- {
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Disconnecting Bluetooth Device {device.ID}...");
- await _adapter.DisconnectDeviceAsync(connected.Device.Native);
- await StartScanningAsync();
- System.Diagnostics.Debug.WriteLine($"{DateTime.Now:O} Bluetooth Device {device.ID} disconnected.");
- }
- return true;
- }
- }
|