A quick and dirty library for BlueZ's D-Bus APIs. Primary focus is Bluetooth Low Energy.
Uses Tmds.DBus to access D-Bus. Tmds.DBus.Tool was used to generate the D-Bus object interfaces. D-Bus is the preferred interface for Bluetooth in userspace. The Doing Bluetooth Low Energy on Linux presentation says "Use D-Bus API (documentation in doc/) whenever possible".
- Linux
- A recent release of BlueZ. This package was tested with BlueZ 5.50. You can check which version you're using with
bluetoothd -v.
dotnet add package HashtagChris.DotNetBlueZC# events are available for several properties. Events are useful for properly handling disconnects and reconnects.
using HashtagChris.DotNetBlueZ;
...
IAdapter1 adapter = (await BlueZManager.GetAdaptersAsync()).FirstOrDefault();or get a particular adapter:
IAdapter1 adapter = await BlueZManager.GetAdapterAsync(adapterName: "hci0");adapter.DeviceFound += adapter_DeviceFoundAsync;
await adapter.StartDiscoveryAsync();
...
await adapter.StopDiscoveryAsync();adapter.DeviceFound (above) will be called immediately for existing devices, and as new devices show up during scanning; eventArgs.IsStateChange can be used to distinguish between existing and new devices. Alternatively you can can use GetDevicesAsync:
IReadOnlyList<Device> devices = await adapter.GetDevicesAsync();device.Connected += device_ConnectedAsync;
device.Disconnected += device_DisconnectedAsync;
device.ServicesResolved += device_ServicesResolvedAsync;
await device.ConnectAsync();Alternatively you can wait for "Connected" and "ServicesResolved" to equal true:
TimeSpan timeout = TimeSpan.FromSeconds(15);
await device.ConnectAsync();
await device.WaitForPropertyValueAsync("Connected", value: true, timeout);
await device.WaitForPropertyValueAsync("ServicesResolved", value: true, timeout);Prerequisite: You must be connected to a device and services must be resolved. You may need to pair with the device in order to use some services.
Example using GATT Device Information Service UUIDs.
string serviceUUID = "0000180a-0000-1000-8000-00805f9b34fb";
string characteristicUUID = "00002a24-0000-1000-8000-00805f9b34fb";
IGattService1 service = await device.GetServiceAsync(serviceUUID);
IGattCharacteristic1 characteristic = await service.GetCharacteristicAsync(characteristicUUID);byte[] value = await characteristic.ReadValueAsync(timeout);
string modelName = Encoding.UTF8.GetString(value);characteristic.Value += characteristic_Value;
...
private static async Task characteristic_Value(GattCharacteristic characteristic, GattCharacteristicValueEventArgs e)
{
try
{
Console.WriteLine($"Characteristic value (hex): {BitConverter.ToString(e.Value)}");
Console.WriteLine($"Characteristic value (UTF-8): \"{Encoding.UTF8.GetString(e.Value)}\"");
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
}It may be necessary to pair with a device for a GATT service to be visible or for reading GATT characteristics to work. To pair, one option is to run bluetoothctl (or sudo bluetoothctl)
and then run default agent and agent on within bluetoothctl. Watch bluetoothctl for pairing requests.
See Ubuntu's Introduction to Pairing.
See Contributing.