### Install DotNet-BlueZ Package Source: https://github.com/hashtagchris/dotnet-bluez/blob/main/README.md Use this command to add the DotNet-BlueZ package to your .NET project. ```bash dotnet add package HashtagChris.DotNetBlueZ ``` -------------------------------- ### Handle DeviceFound Event and Start Discovery Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Subscribes to the DeviceFound event to be notified of new devices. Automatically enumerates existing devices upon subscription. Starts and stops discovery for a specified duration. ```csharp using HashtagChris.DotNetBlueZ; adapter.DeviceFound += async (Adapter sender, DeviceFoundEventArgs e) => { var device = e.Device; var props = await device.GetAllAsync(); if (e.IsStateChange) Console.WriteLine($"[NEW] {props.Alias} ({props.Address}) RSSI={props.RSSI}"); else Console.WriteLine($"[PRE] {props.Alias} ({props.Address})"); }; await adapter.StartDiscoveryAsync(); await Task.Delay(TimeSpan.FromSeconds(15)); await adapter.StopDiscoveryAsync(); ``` -------------------------------- ### Start and Stop Bluetooth Discovery Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Starts Bluetooth device scanning on the adapter and stops it after a specified duration. It uses `WatchDevicesAddedAsync` to react to newly discovered devices during the scan. ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; int newDeviceCount = 0; // Watch for newly discovered devices during scanning using (await adapter.WatchDevicesAddedAsync(async device => { newDeviceCount++; var props = await device.GetAllAsync(); Console.WriteLine($"[NEW] {props.Alias} ({props.Address})"); })) { await adapter.StartDiscoveryAsync(); await Task.Delay(TimeSpan.FromSeconds(15)); await adapter.StopDiscoveryAsync(); } Console.WriteLine($"Scan complete. {newDeviceCount} new device(s) found."); ``` -------------------------------- ### Get a Bluetooth Adapter Source: https://github.com/hashtagchris/dotnet-bluez/blob/main/README.md Retrieve the default Bluetooth adapter or a specific one by name. ```csharp using HashtagChris.DotNetBlueZ; ... IAdapter1 adapter = (await BlueZManager.GetAdaptersAsync()).FirstOrDefault(); ``` ```csharp IAdapter1 adapter = await BlueZManager.GetAdapterAsync(adapterName: "hci0"); ``` -------------------------------- ### Get All Bluetooth Adapters Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves all available Bluetooth adapters on the system. Use this when the adapter name is unknown. Ensure at least one adapter is found. ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; // Get all adapters and pick the first one IReadOnlyList adapters = await BlueZManager.GetAdaptersAsync(); if (adapters.Count == 0) { throw new Exception("No Bluetooth adapters found."); } Adapter adapter = adapters.First(); var adapterPath = adapter.ObjectPath.ToString(); var adapterName = adapterPath.Substring(adapterPath.LastIndexOf("/") + 1); Console.WriteLine($"Using Bluetooth adapter: {adapterName}"); // Output: Using Bluetooth adapter: hci0 ``` -------------------------------- ### Adapter.StartDiscoveryAsync / StopDiscoveryAsync Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Starts and stops Bluetooth device scanning on the adapter. This can be combined with device discovery events to react to newly found devices. ```APIDOC ## Adapter.StartDiscoveryAsync / StopDiscoveryAsync ### Description Starts and stops Bluetooth device scanning on the adapter. Combine with `DeviceFound` events or `WatchDevicesAddedAsync` to react to discovered devices. ### Usage Example ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; int newDeviceCount = 0; // Watch for newly discovered devices during scanning using (await adapter.WatchDevicesAddedAsync(async device => { newDeviceCount++; var props = await device.GetAllAsync(); Console.WriteLine($"[NEW] {props.Alias} ({props.Address})"); })) { await adapter.StartDiscoveryAsync(); await Task.Delay(TimeSpan.FromSeconds(15)); await adapter.StopDiscoveryAsync(); } Console.WriteLine($"Scan complete. {newDeviceCount} new device(s) found."); ``` ``` -------------------------------- ### Scan for Bluetooth Devices Source: https://github.com/hashtagchris/dotnet-bluez/blob/main/README.md Start and stop scanning for Bluetooth devices. Subscribe to the DeviceFound event to be notified of discovered devices. ```csharp adapter.DeviceFound += adapter_DeviceFoundAsync; await adapter.StartDiscoveryAsync(); ... await adapter.StopDiscoveryAsync(); ``` -------------------------------- ### Get Existing Bluetooth Devices Source: https://github.com/hashtagchris/dotnet-bluez/blob/main/README.md Retrieve a list of currently known Bluetooth devices. This can be used in conjunction with or as an alternative to scanning. ```csharp IReadOnlyList devices = await adapter.GetDevicesAsync(); ``` -------------------------------- ### Handle Adapter Power Events Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Listens for adapter power state changes. The PoweredOn event fires immediately if the adapter is already on. Starts discovery when the adapter powers on. ```csharp using HashtagChris.DotNetBlueZ; adapter.PoweredOn += async (Adapter sender, BlueZEventArgs e) => { Console.WriteLine(e.IsStateChange ? "Adapter powered on." : "Adapter already on."); await sender.StartDiscoveryAsync(); }; adapter.PoweredOff += async (Adapter sender, BlueZEventArgs e) => { Console.WriteLine("Adapter powered off."); }; ``` -------------------------------- ### Get All Known Bluetooth Devices Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves a list of all devices currently known to BlueZ under the specified adapter. This does not initiate a scan but reflects devices cached from prior scans or connections. ```csharp using HashtagChris.DotNetBlueZ.Extensions; IReadOnlyList devices = await adapter.GetDevicesAsync(); Console.WriteLine($"{devices.Count} device(s) already known."); foreach (var device in devices) { var props = await device.GetAllAsync(); Console.WriteLine($" {props.Alias} - {props.Address} (Connected: {props.Connected})"); } ``` -------------------------------- ### Get Specific Bluetooth Adapter Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves a specific Bluetooth adapter by its name (e.g., "hci0"). Throws an exception if the adapter is not found. ```csharp using HashtagChris.DotNetBlueZ; // Get a specific adapter by name Adapter adapter = await BlueZManager.GetAdapterAsync("hci0"); Console.WriteLine($"Adapter address: {await adapter.GetAddressAsync()}"); // Output: Adapter address: AA:BB:CC:DD:EE:FF ``` -------------------------------- ### Get GATT Service by UUID Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Looks up a GATT service on a connected device using its 128-bit UUID. Requires the device to be connected and its services to be resolved. Returns `null` if the service is not found. ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; // GATT Device Information Service IGattService1 service = await device.GetServiceAsync(GattConstants.DeviceInformationServiceUUID); // equivalent to: await device.GetServiceAsync("0000180a-0000-1000-8000-00805f9b34fb") if (service == null) { Console.WriteLine("Service not found. Pairing may be required."); return; } Console.WriteLine($"Service UUID: {await service.GetUUIDAsync()}"); ``` -------------------------------- ### Get Specific Bluetooth Device by MAC Address Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves a single cached `Device` by its MAC address. The lookup is case-insensitive. Returns `null` if the device is not found, suggesting a scan might be needed first. ```csharp using HashtagChris.DotNetBlueZ.Extensions; Device device = await adapter.GetDeviceAsync("AA:BB:CC:11:22:33"); if (device == null) { Console.WriteLine("Device not found. Scan first with bluetoothctl or adapter.StartDiscoveryAsync."); return; } Console.WriteLine($"Found device: {await device.GetAliasAsync()}"); ``` -------------------------------- ### Connect to a Bluetooth Device and Wait for Properties Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Initiates a connection to a remote Bluetooth device and then polls for `Connected` and `ServicesResolved` properties. Access to GATT services is safe only after these properties are true. ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; var timeout = TimeSpan.FromSeconds(15); await device.ConnectAsync(); // Polling approach: wait for property values await device.WaitForPropertyValueAsync("Connected", value: true, timeout); Console.WriteLine("Connected."); await device.WaitForPropertyValueAsync("ServicesResolved", value: true, timeout); Console.WriteLine("Services resolved."); // Then access GATT services... await device.DisconnectAsync(); Console.WriteLine("Disconnected."); ``` -------------------------------- ### Connect to a Bluetooth Device Source: https://github.com/hashtagchris/dotnet-bluez/blob/main/README.md Initiate a connection to a Bluetooth device and subscribe to connection-related events. Alternatively, wait for connection properties to become true. ```csharp device.Connected += device_ConnectedAsync; device.Disconnected += device_DisconnectedAsync; device.ServicesResolved += device_ServicesResolvedAsync; await device.ConnectAsync(); ``` ```csharp TimeSpan timeout = TimeSpan.FromSeconds(15); await device.ConnectAsync(); await device.WaitForPropertyValueAsync("Connected", value: true, timeout); await device.WaitForPropertyValueAsync("ServicesResolved", value: true, timeout); ``` -------------------------------- ### adapter.GetDevicesAsync (extension) Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves a list of all devices currently known to the BlueZ adapter. This method reflects devices cached from prior scans or connections and does not initiate a new scan. ```APIDOC ## adapter.GetDevicesAsync (extension) ### Description Returns all devices currently known to BlueZ under this adapter. Does not start a scan — it reflects devices cached by BlueZ from prior scans or connections. ### Usage Example ```csharp using HashtagChris.DotNetBlueZ.Extensions; IReadOnlyList devices = await adapter.GetDevicesAsync(); Console.WriteLine($"{devices.Count} device(s) already known."); foreach (var device in devices) { var props = await device.GetAllAsync(); Console.WriteLine($" {props.Alias} - {props.Address} (Connected: {props.Connected})"); } ``` ``` -------------------------------- ### BlueZManager.GetAdaptersAsync Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves all available Bluetooth adapters on the system. This is useful when the specific adapter name is unknown. ```APIDOC ## BlueZManager.GetAdaptersAsync ### Description Returns all Bluetooth adapters available on the system as a list of `Adapter` objects. Useful when the adapter name is not known in advance. ### Method `BlueZManager.GetAdaptersAsync()` ### Example ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; // Get all adapters and pick the first one IReadOnlyList adapters = await BlueZManager.GetAdaptersAsync(); if (adapters.Count == 0) { throw new Exception("No Bluetooth adapters found."); } Adapter adapter = adapters.First(); var adapterPath = adapter.ObjectPath.ToString(); var adapterName = adapterPath.Substring(adapterPath.LastIndexOf("/") + 1); Console.WriteLine($"Using Bluetooth adapter: {adapterName}"); // Output: Using Bluetooth adapter: hci0 ``` ``` -------------------------------- ### Adapter.DeviceFound Event Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Handles events for discovered Bluetooth devices. It fires for known devices upon subscription and for new devices during active scans. ```APIDOC ## Adapter.DeviceFound Event ### Description Raised for every known device when a handler is first subscribed, and then again (with `IsStateChange = true`) whenever a new device is detected during an active scan. Subscribing to this event automatically enumerates existing devices. ### Event Signature `adapter.DeviceFound += async (Adapter sender, DeviceFoundEventArgs e) => { ... };` ### Parameters - **sender** (Adapter) - The adapter that detected the device. - **e** (DeviceFoundEventArgs) - Contains information about the found device. - **e.Device** (Device) - The discovered device object. - **e.IsStateChange** (bool) - True if this is a new device detection during an active scan. ### Example ```csharp using HashtagChris.DotNetBlueZ; adapter.DeviceFound += async (Adapter sender, DeviceFoundEventArgs e) => { var device = e.Device; var props = await device.GetAllAsync(); if (e.IsStateChange) Console.WriteLine($"[NEW] {props.Alias} ({props.Address}) RSSI={props.RSSI}"); else Console.WriteLine($"[PRE] {props.Alias} ({props.Address})"); }; await adapter.StartDiscoveryAsync(); await Task.Delay(TimeSpan.FromSeconds(15)); await adapter.StopDiscoveryAsync(); ``` ``` -------------------------------- ### Device.ConnectAsync Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Initiates a connection to a remote Bluetooth device. After establishing a connection, it is recommended to monitor the `Connected` and `ServicesResolved` properties or events before accessing GATT services. ```APIDOC ## Device.ConnectAsync ### Description Initiates a connection to a remote Bluetooth device. After calling `ConnectAsync`, wait for the `Connected` and `ServicesResolved` properties or events before accessing GATT services. ### Usage Example ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; var timeout = TimeSpan.FromSeconds(15); await device.ConnectAsync(); // Polling approach: wait for property values await device.WaitForPropertyValueAsync("Connected", value: true, timeout); Console.WriteLine("Connected."); await device.WaitForPropertyValueAsync("ServicesResolved", value: true, timeout); Console.WriteLine("Services resolved."); // Then access GATT services... await device.DisconnectAsync(); Console.WriteLine("Disconnected."); ``` ``` -------------------------------- ### adapter.GetDeviceAsync (extension) Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves a specific cached `Device` object using its MAC address. The lookup is case-insensitive, and the method returns `null` if the device is not found in the cache. ```APIDOC ## adapter.GetDeviceAsync (extension) ### Description Retrieves a single cached `Device` by its MAC address (case-insensitive). Returns `null` if not found. ### Usage Example ```csharp using HashtagChris.DotNetBlueZ.Extensions; Device device = await adapter.GetDeviceAsync("AA:BB:CC:11:22:33"); if (device == null) { Console.WriteLine("Device not found. Scan first with bluetoothctl or adapter.StartDiscoveryAsync."); return; } Console.WriteLine($"Found device: {await device.GetAliasAsync()}"); ``` ``` -------------------------------- ### Handle Bluetooth Device Connection Events Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Provides an event-driven approach to manage Bluetooth device connection states. It subscribes to `Connected`, `Disconnected`, and `ServicesResolved` events, offering an alternative to polling `WaitForPropertyValueAsync`. ```csharp using HashtagChris.DotNetBlueZ; device.Connected += async (Device sender, BlueZEventArgs e) => { Console.WriteLine(e.IsStateChange ? $"Connected to {await sender.GetAddressAsync()}" : $"Already connected to {await sender.GetAddressAsync()}"); }; device.Disconnected += async (Device sender, BlueZEventArgs e) => { Console.WriteLine($"Disconnected from {await sender.GetAddressAsync()}. Reconnecting in 15s..."); await Task.Delay(TimeSpan.FromSeconds(15)); await sender.ConnectAsync(); }; device.ServicesResolved += async (Device sender, BlueZEventArgs e) => { Console.WriteLine($"Services resolved for {await sender.GetAddressAsync()}"); // Now safe to discover GATT services }; await device.ConnectAsync(); await Task.Delay(-1); // Keep running ``` -------------------------------- ### BlueZManager.GetAdapterAsync Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves a specific Bluetooth adapter by its name (e.g., "hci0"). Throws an exception if the adapter is not found. ```APIDOC ## BlueZManager.GetAdapterAsync ### Description Retrieves a specific Bluetooth adapter by name (e.g., `"hci0"`). Throws if the adapter is not found. ### Method `BlueZManager.GetAdapterAsync(string name)` ### Parameters #### Path Parameters - **name** (string) - Required - The name of the Bluetooth adapter (e.g., "hci0"). ### Example ```csharp using HashtagChris.DotNetBlueZ; // Get a specific adapter by name Adapter adapter = await BlueZManager.GetAdapterAsync("hci0"); Console.WriteLine($"Adapter address: {await adapter.GetAddressAsync()}"); // Output: Adapter address: AA:BB:CC:DD:EE:FF ``` ``` -------------------------------- ### GATT Constants for Standard UUIDs Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Provides pre-defined UUID constants for commonly used standard GATT services and characteristics, eliminating the need to hard-code UUID strings. ```csharp using HashtagChris.DotNetBlueZ; // Device Information Service Console.WriteLine(GattConstants.DeviceInformationServiceUUID); // => "0000180a-0000-1000-8000-00805f9b34fb" Console.WriteLine(GattConstants.ModelNameCharacteristicUUID); // => "00002a24-0000-1000-8000-00805f9b34fb" Console.WriteLine(GattConstants.ManufacturerNameCharacteristicUUID); // => "00002a29-0000-1000-8000-00805f9b34fb" // Current Time Service Console.WriteLine(GattConstants.CurrentTimeServiceUUID); // => "00001805-0000-1000-8000-00805f9b34fb" Console.WriteLine(GattConstants.CurrentTimeCharacteristicUUID); // => "00002a2b-0000-1000-8000-00805f9b34fb" // Apple Notification Center Service (ANCS) Console.WriteLine(GattConstants.ANCServiceUUID); // => "7905f431-b5ce-4e99-a40f-4b1e122d00d0" ``` -------------------------------- ### device.GetServiceAsync (extension) Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Retrieves a specific GATT service from a connected device based on its 128-bit UUID. Returns `null` if the service is not found. This operation requires the device to be connected and its services to be resolved. ```APIDOC ## device.GetServiceAsync (extension) ### Description Looks up a GATT service on a connected device by its full 128-bit UUID. Returns `null` if the service is not found. Requires the device to be connected and services to be resolved. ### Usage Example ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; // GATT Device Information Service IGattService1 service = await device.GetServiceAsync(GattConstants.DeviceInformationServiceUUID); // equivalent to: await device.GetServiceAsync("0000180a-0000-1000-8000-00805f9b34fb") if (service == null) { Console.WriteLine("Service not found. Pairing may be required."); return; } Console.WriteLine($"Service UUID: {await service.GetUUIDAsync()}"); ``` ``` -------------------------------- ### Subscribe to GATT Characteristic Notifications Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Subscribes to BLE characteristic notifications. Attaching a handler automatically calls StartNotifyAsync on the underlying BlueZ interface. The event provides GattCharacteristicValueEventArgs with the updated byte[] value. Ensure the process remains alive to receive notifications. ```csharp using HashtagChris.DotNetBlueZ; characteristic.Value += async (GattCharacteristic sender, GattCharacteristicValueEventArgs e) => { try { var uuid = await sender.GetUUIDAsync(); Console.WriteLine($"[{DateTime.Now:T}] [{uuid}] hex: {BitConverter.ToString(e.Value)}"); Console.WriteLine($"[{DateTime.Now:T}] [{uuid}] utf8: \"{System.Text.Encoding.UTF8.GetString(e.Value)}\" "); } catch (Exception ex) { Console.Error.WriteLine(ex); } }; // Keep the process alive to receive notifications await Task.Delay(-1); ``` -------------------------------- ### Device.Connected / Disconnected / ServicesResolved events Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Provides an event-driven mechanism to monitor device connection status and service resolution. These events can be used as an alternative to polling properties like `Connected` and `ServicesResolved`. ```APIDOC ## Device.Connected / Disconnected / ServicesResolved events ### Description Event-driven alternative to polling `WaitForPropertyValueAsync`. `Connected` and `ServicesResolved` also fire immediately if already true when the handler is added. ### Usage Example ```csharp using HashtagChris.DotNetBlueZ; device.Connected += async (Device sender, BlueZEventArgs e) => { Console.WriteLine(e.IsStateChange ? $ ``` -------------------------------- ### Wait for Device Property Value Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Asynchronously waits until a named D-Bus property on a Device reaches the specified value, with a timeout. Returns immediately if the property is already at the target value. This is useful for ensuring connection and service resolution before proceeding. ```csharp using HashtagChris.DotNetBlueZ.Extensions; var timeout = TimeSpan.FromSeconds(15); try { await device.ConnectAsync(); await device.WaitForPropertyValueAsync("Connected", value: true, timeout); Console.WriteLine("Connected!"); await device.WaitForPropertyValueAsync("ServicesResolved", value: true, timeout); Console.WriteLine("GATT services are ready."); } catch (TimeoutException ex) { Console.Error.WriteLine($"Timed out: {ex.Message}"); } ``` -------------------------------- ### Write Value to GATT Characteristic Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Writes a byte array to a writable GATT characteristic. Options can be passed as an IDictionary; pass an empty dictionary for defaults. ```csharp using System.Collections.Generic; using HashtagChris.DotNetBlueZ; // Write a command byte to a custom control-point characteristic byte[] command = new byte[] { 0x01, 0x02, 0x03 }; var options = new Dictionary(); await characteristic.WriteValueAsync(command, options); Console.WriteLine("Write complete."); ``` -------------------------------- ### Adapter.PoweredOn / PoweredOff Events Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Fires when the Bluetooth adapter's power state changes. `PoweredOn` also triggers if the adapter is already on when the handler is added. ```APIDOC ## Adapter.PoweredOn / PoweredOff Events ### Description Fired when the adapter power state changes. `PoweredOn` also fires immediately (with `IsStateChange = false`) if the adapter is already powered on at the time the handler is added. ### Event Signatures - `adapter.PoweredOn += async (Adapter sender, BlueZEventArgs e) => { ... };` - `adapter.PoweredOff += async (Adapter sender, BlueZEventArgs e) => { ... };` ### Parameters - **sender** (Adapter) - The adapter whose power state changed. - **e** (BlueZEventArgs) - Event arguments. - **e.IsStateChange** (bool) - Indicates if the event is due to a state change (true) or initial state reporting (false for `PoweredOn`). ### Example ```csharp using HashtagChris.DotNetBlueZ; adapter.PoweredOn += async (Adapter sender, BlueZEventArgs e) => { Console.WriteLine(e.IsStateChange ? "Adapter powered on." : "Adapter already on."); await sender.StartDiscoveryAsync(); }; adapter.PoweredOff += async (Adapter sender, BlueZEventArgs e) => { Console.WriteLine("Adapter powered off."); }; ``` ``` -------------------------------- ### Retrieve GATT Service and Characteristic Source: https://github.com/hashtagchris/dotnet-bluez/blob/main/README.md Access a specific GATT service and characteristic on a connected device using their UUIDs. Ensure the device is connected and services are resolved. ```csharp 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); ``` -------------------------------- ### device.WaitForPropertyValueAsync Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Asynchronously waits until a named D-Bus property on a Device reaches the specified value, with a timeout. Returns immediately if the property is already at the target value. ```APIDOC ## device.WaitForPropertyValueAsync (extension) ### Description Asynchronously waits until a named D-Bus property on a `Device` reaches the specified value, with a timeout. Returns immediately if the property is already at the target value. ### Usage ```csharp var timeout = TimeSpan.FromSeconds(15); try { await device.ConnectAsync(); await device.WaitForPropertyValueAsync("Connected", value: true, timeout); await device.WaitForPropertyValueAsync("ServicesResolved", value: true, timeout); } catch (TimeoutException ex) { Console.Error.WriteLine($"Timed out: {ex.Message}"); } ``` ``` -------------------------------- ### BlueZManager.NormalizeUUID Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Expands short UUIDs (16-bit or 32-bit) to their full 128-bit canonical form. 128-bit UUIDs are returned as-is. ```APIDOC ## BlueZManager.NormalizeUUID ### Description Expands a 16-bit (4 hex chars) or 32-bit (8 hex chars) Bluetooth UUID to its full 128-bit canonical lowercase form. 128-bit UUIDs are returned lowercased as-is. ### Method `BlueZManager.NormalizeUUID(string uuid)` ### Parameters #### Path Parameters - **uuid** (string) - Required - The Bluetooth UUID string to normalize. ### Example ```csharp using HashtagChris.DotNetBlueZ; string uuid16 = BlueZManager.NormalizeUUID("180a"); // => "0000180a-0000-1000-8000-00805f9b34fb" string uuid32 = BlueZManager.NormalizeUUID("0000180a"); // => "0000180a-0000-1000-8000-00805f9b34fb" string uuid128 = BlueZManager.NormalizeUUID("0000180a-0000-1000-8000-00805f9b34fb"); // => "0000180a-0000-1000-8000-00805f9b34fb" ``` ``` -------------------------------- ### Normalize Bluetooth UUID Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Expands 16-bit or 32-bit Bluetooth UUIDs to their full 128-bit canonical lowercase form. 128-bit UUIDs are returned as-is. ```csharp using HashtagChris.DotNetBlueZ; string uuid16 = BlueZManager.NormalizeUUID("180a"); // => "0000180a-0000-1000-8000-00805f9b34fb" string uuid32 = BlueZManager.NormalizeUUID("0000180a"); // => "0000180a-0000-1000-8000-00805f9b34fb" string uuid128 = BlueZManager.NormalizeUUID("0000180a-0000-1000-8000-00805f9b34fb"); // => "0000180a-0000-1000-8000-00805f9b34fb" ``` -------------------------------- ### Find GATT Characteristic by UUID Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Use this to find a specific GATT characteristic within a service by its UUID. It returns a GattCharacteristic instance with events, simplifying interaction compared to the raw proxy. ```csharp using HashtagChris.DotNetBlueZ; using HashtagChris.DotNetBlueZ.Extensions; var service = await device.GetServiceAsync(GattConstants.DeviceInformationServiceUUID); GattCharacteristic modelChar = await service.GetCharacteristicAsync(GattConstants.ModelNameCharacteristicUUID); GattCharacteristic mfgrChar = await service.GetCharacteristicAsync(GattConstants.ManufacturerNameCharacteristicUUID); if (modelChar != null) { byte[] value = await modelChar.ReadValueAsync(TimeSpan.FromSeconds(15)); Console.WriteLine($"Model name: {System.Text.Encoding.UTF8.GetString(value)}"); // Output: Model name: iPhone12,1 } if (mfgrChar != null) { byte[] value = await mfgrChar.ReadValueAsync(TimeSpan.FromSeconds(15)); Console.WriteLine($"Manufacturer: {System.Text.Encoding.UTF8.GetString(value)}"); // Output: Manufacturer: Apple Inc. } ``` -------------------------------- ### GattCharacteristic.WriteValueAsync Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Writes a byte array to a writable GATT characteristic. Options can be passed as an IDictionary (pass an empty dictionary for defaults). ```APIDOC ## GattCharacteristic.WriteValueAsync ### Description Writes a byte array to a writable GATT characteristic. Options can be passed as an `IDictionary` (pass an empty dictionary for defaults). ### Usage ```csharp byte[] command = new byte[] { 0x01, 0x02, 0x03 }; var options = new Dictionary(); await characteristic.WriteValueAsync(command, options); ``` ``` -------------------------------- ### GattConstants Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Pre-defined UUID constants for commonly used standard GATT services and characteristics, removing the need to hard-code UUID strings. ```APIDOC ## GattConstants ### Description Pre-defined UUID constants for commonly used standard GATT services and characteristics, removing the need to hard-code UUID strings. ### Usage ```csharp // Device Information Service Console.WriteLine(GattConstants.DeviceInformationServiceUUID); // Model Name Characteristic Console.WriteLine(GattConstants.ModelNameCharacteristicUUID); // Manufacturer Name Characteristic Console.WriteLine(GattConstants.ManufacturerNameCharacteristicUUID); ``` ``` -------------------------------- ### GattCharacteristic.Value event Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Subscribes to BLE characteristic notifications. Attaching a handler automatically calls StartNotifyAsync on the underlying BlueZ interface. The event provides a GattCharacteristicValueEventArgs with the updated byte[] value. ```APIDOC ## GattCharacteristic.Value event (notifications) ### Description Subscribes to BLE characteristic notifications. Attaching a handler automatically calls `StartNotifyAsync` on the underlying BlueZ interface. The event provides a `GattCharacteristicValueEventArgs` with the updated `byte[]` value. ### Usage ```csharp characteristic.Value += async (GattCharacteristic sender, GattCharacteristicValueEventArgs e) => { // Handle received value }; // Keep the process alive to receive notifications await Task.Delay(-1); ``` ``` -------------------------------- ### Subscribe to GATT Characteristic Notifications Source: https://github.com/hashtagchris/dotnet-bluez/blob/main/README.md Subscribe to notifications for changes in a GATT characteristic's value. Handle incoming values in the Value event handler. ```csharp 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); } } ``` -------------------------------- ### Read GATT Characteristic Value with Timeout Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Reads the current value of a GATT characteristic with a specified timeout. This extension method simplifies the options-dictionary overload on the raw interface and throws a TimeoutException if the read operation does not complete in time. ```csharp using HashtagChris.DotNetBlueZ.Extensions; var timeout = TimeSpan.FromSeconds(15); try { byte[] raw = await characteristic.ReadValueAsync(timeout); Console.WriteLine($"Raw (hex): {BitConverter.ToString(raw)}"); Console.WriteLine($"UTF-8: {System.Text.Encoding.UTF8.GetString(raw)}"); } catch (TimeoutException) { Console.Error.WriteLine("Read timed out."); } ``` -------------------------------- ### service.GetCharacteristicAsync Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Finds a GATT characteristic within a service by UUID. Returns a GattCharacteristic instance (with events) rather than the raw IGattCharacteristic1 proxy. ```APIDOC ## service.GetCharacteristicAsync (extension) ### Description Finds a GATT characteristic within a service by UUID. Returns a `GattCharacteristic` instance (with events) rather than the raw `IGattCharacteristic1` proxy. ### Usage ```csharp var service = await device.GetServiceAsync(GattConstants.DeviceInformationServiceUUID); GattCharacteristic modelChar = await service.GetCharacteristicAsync(GattConstants.ModelNameCharacteristicUUID); ``` ``` -------------------------------- ### Read GATT Characteristic Value Source: https://github.com/hashtagchris/dotnet-bluez/blob/main/README.md Read the value of a GATT characteristic. The value is returned as a byte array and can be decoded into a string. ```csharp byte[] value = await characteristic.ReadValueAsync(timeout); string modelName = Encoding.UTF8.GetString(value); ``` -------------------------------- ### characteristic.ReadValueAsync Source: https://context7.com/hashtagchris/dotnet-bluez/llms.txt Reads the current value of a GATT characteristic with a TimeSpan timeout. Throws TimeoutException if the read does not complete in time. This extension simplifies the options-dictionary overload on the raw interface. ```APIDOC ## characteristic.ReadValueAsync (extension with timeout) ### Description Reads the current value of a GATT characteristic with a `TimeSpan` timeout. Throws `TimeoutException` if the read does not complete in time. This extension simplifies the options-dictionary overload on the raw interface. ### Usage ```csharp var timeout = TimeSpan.FromSeconds(15); try { byte[] raw = await characteristic.ReadValueAsync(timeout); } catch (TimeoutException) { Console.Error.WriteLine("Read timed out."); } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.