123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- using System.Text;
- using Android.Bluetooth;
- namespace InABox.Avalonia.Platform.Android;
- public class Android_ConnectedBluetoothDevice : BluetoothGattCallback,IConnectedBluetoothDevice
- {
- private BluetoothDevice? _device;
- public string ID { get; }
- public string Name { get; }
- public DateTime LastSeen { get; set; } = DateTime.Now;
- private Guid[] _availableServices = [];
- public Guid[] AvailableServices => _availableServices;
-
- private BluetoothGatt? _bluetoothGatt;
-
- private TaskCompletionSource<bool>? _connectionTaskCompletionSource;
- private TaskCompletionSource<bool>? _serviceDiscoveryTaskCompletionSource;
- private TaskCompletionSource<byte[]>? _readTaskCompletionSource;
- private TaskCompletionSource<bool>? _writeTaskCompletionSource;
- public Android_ConnectedBluetoothDevice(BluetoothDevice? device)
- {
- _device = device;
- ID = device?.Address ?? string.Empty;
- Name = device?.Name ?? "Unknown Device";
- }
- public async Task<bool> ConnectAsync()
- {
- _connectionTaskCompletionSource = new TaskCompletionSource<bool>();
- _bluetoothGatt = _device?.ConnectGatt(Application.Context, false, this);
- return await _connectionTaskCompletionSource.Task;
- }
- public override void OnConnectionStateChange(BluetoothGatt? gatt, GattStatus status, ProfileState newState)
- {
- base.OnConnectionStateChange(gatt, status, newState);
- if (newState == ProfileState.Connected && status == GattStatus.Success)
- {
- Console.WriteLine("Connected to GATT server.");
- _connectionTaskCompletionSource?.TrySetResult(true);
- }
- else
- {
- Console.WriteLine("Failed to connect or disconnected.");
- _connectionTaskCompletionSource?.TrySetResult(false);
- Dispose();
- }
- }
- public async Task<bool> DiscoverServicesAsync()
- {
- _serviceDiscoveryTaskCompletionSource = new TaskCompletionSource<bool>();
- _bluetoothGatt?.DiscoverServices();
- _availableServices = _bluetoothGatt?.Services?.Select(x => Guid.Parse(x.Uuid?.ToString() ?? Guid.Empty.ToString())).ToArray() ?? [];
- return await _serviceDiscoveryTaskCompletionSource.Task;
- }
- public override void OnServicesDiscovered(BluetoothGatt? gatt, GattStatus status)
- {
- base.OnServicesDiscovered(gatt, status);
- if (status == GattStatus.Success)
- {
- Console.WriteLine("Services discovered.");
- _serviceDiscoveryTaskCompletionSource?.TrySetResult(true);
- }
- else
- {
- Console.WriteLine("Service discovery failed.");
- _serviceDiscoveryTaskCompletionSource?.TrySetResult(false);
- }
- }
-
- public async Task<byte[]?> ReadBytesAsync(Guid serviceid, Guid characteristicid)
- {
- byte[]? result = null;
- if (_bluetoothGatt != null)
- {
- var service = _bluetoothGatt.GetService(Java.Util.UUID.FromString(serviceid.ToString()));
- if (service != null)
- {
- var characteristic = service.GetCharacteristic(Java.Util.UUID.FromString(characteristicid.ToString()));
- if (characteristic != null)
- result = await ReadCharacteristicAsync(characteristic);
- }
- }
- return result;
- }
- public async Task<String?> ReadStringAsync(Guid serviceid, Guid characteristicid)
- {
- var data = await ReadBytesAsync(serviceid,characteristicid);
- return data != null ? Encoding.UTF8.GetString(data) : null;
- }
- private async Task<byte[]?> ReadCharacteristicAsync(BluetoothGattCharacteristic characteristic)
- {
- if (_bluetoothGatt != null)
- {
- _readTaskCompletionSource = new TaskCompletionSource<byte[]>();
- if (!_bluetoothGatt.ReadCharacteristic(characteristic))
- {
- _readTaskCompletionSource.TrySetException(
- new InvalidOperationException("Failed to initiate characteristic read."));
- }
- return await _readTaskCompletionSource.Task;
- }
- return null;
- }
- public override void OnCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] data, GattStatus status)
- {
- base.OnCharacteristicRead(gatt, characteristic, data, status);
- if (status == GattStatus.Success)
- {
- Console.WriteLine("Characteristic read successfully.");
- _readTaskCompletionSource?.TrySetResult(data);
- }
- else
- {
- Console.WriteLine("Failed to read characteristic.");
- _readTaskCompletionSource?.TrySetException(new InvalidOperationException("Characteristic read failed."));
- }
- }
-
- public async Task<bool> WriteBytesAsync(Guid serviceid, Guid characteristicid, byte[] data)
- {
- var result = false;
- if (_bluetoothGatt != null)
- {
- var service = _bluetoothGatt.GetService(Java.Util.UUID.FromString(serviceid.ToString()));
- if (service != null)
- {
- var characteristic = service.GetCharacteristic(Java.Util.UUID.FromString(characteristicid.ToString()));
- if (characteristic != null)
- result = await WriteCharacteristicAsync(characteristic, data);
- }
- }
- return result;
- }
-
- public async Task<bool> WriteStringAsync(Guid serviceid, Guid characteristicid, string data)
- {
- var encoded = Encoding.UTF8.GetBytes(data);
- return await WriteBytesAsync(serviceid, characteristicid, encoded);
- }
-
- private async Task<bool> WriteCharacteristicAsync(BluetoothGattCharacteristic characteristic, byte[] data)
- {
- bool result = false;
- if (_bluetoothGatt != null)
- {
- _writeTaskCompletionSource = new TaskCompletionSource<bool>();
- _bluetoothGatt.WriteCharacteristic(characteristic, data, 2);
- result = await _writeTaskCompletionSource.Task;
- }
- return result;
- }
- public override void OnCharacteristicWrite(BluetoothGatt? gatt, BluetoothGattCharacteristic? characteristic, GattStatus status)
- {
- base.OnCharacteristicWrite(gatt, characteristic, status);
- if (status == GattStatus.Success)
- {
- Console.WriteLine("Characteristic written successfully.");
- _writeTaskCompletionSource?.TrySetResult(true);
- }
- else
- {
- Console.WriteLine("Failed to write characteristic.");
- _writeTaskCompletionSource?.TrySetException(new InvalidOperationException("Characteristic write failed."));
- }
- }
-
- public new void Dispose()
- {
- base.Dispose();
- try
- {
- _bluetoothGatt?.Disconnect();
- _bluetoothGatt?.Close();
- }
- catch (Exception ex)
- {
- Console.WriteLine($"Error during disposal: {ex.Message}");
- }
-
- _bluetoothGatt?.Dispose();
- _bluetoothGatt = null;
-
- _device?.Dispose();
- _device = null;
- Console.WriteLine("Resources released.");
-
- }
-
- }
|