diff --git a/src/Linux.Bluetooth/Adapter.cs b/src/Linux.Bluetooth/Adapter.cs index f70acd1..579cafe 100644 --- a/src/Linux.Bluetooth/Adapter.cs +++ b/src/Linux.Bluetooth/Adapter.cs @@ -80,6 +80,11 @@ public void Dispose() GC.SuppressFinalize(this); } + /// + /// Raised for each device found. Subscribing replays the devices already known to BlueZ. + /// The subscriber owns every it receives and must dispose it; each one + /// holds a D-Bus match rule until disposed. + /// public event DeviceChangeEventHandlerAsync DeviceFound { add @@ -332,10 +337,11 @@ private async void TrackDeviceForConnection(ObjectPath objectPath) _connTrackedDevices[objectPath] = null!; } + Device? device = null; try { var proxy = Connection.System.CreateProxy(BluezConstants.DbusService, objectPath); - var device = await Device.CreateAsync(proxy); + device = await Device.CreateAsync(proxy); // Device.Connected can fire twice (add-accessor replay + live change), so relay only // on an actual transition. @@ -372,6 +378,9 @@ private async void TrackDeviceForConnection(ObjectPath objectPath) _connTrackedDevices.Remove(objectPath); } + // The reserved slot is gone, so nothing else will ever dispose this device. + device?.Dispose(); + Console.WriteLine($"Error tracking device '{objectPath}' for connection: {ex.Message}"); } } diff --git a/src/Linux.Bluetooth/Extensions/AdapterExtensions.cs b/src/Linux.Bluetooth/Extensions/AdapterExtensions.cs index e5c6827..a9ff7bc 100644 --- a/src/Linux.Bluetooth/Extensions/AdapterExtensions.cs +++ b/src/Linux.Bluetooth/Extensions/AdapterExtensions.cs @@ -9,6 +9,11 @@ namespace Linux.Bluetooth.Extensions public static class AdapterExtensions { /// Get available devices. + /// + /// The caller owns the returned devices and must dispose each one. Every + /// holds a D-Bus match rule; an undisposed device keeps its rule until the connection closes, + /// and a connection is limited to max_match_rules_per_connection (2048 by default). + /// /// Adapter object. /// Collection of s. public static async Task> GetDevicesAsync(this IAdapter1 adapter) @@ -19,6 +24,7 @@ public static async Task> GetDevicesAsync(this IAdapter1 a } /// Get object from the specifed BLE address. + /// The caller owns the returned device and must dispose it. See . /// Adapter object. /// BLE Device Address. /// object or NULL if not found. @@ -52,6 +58,7 @@ public static async Task> GetDevicesAsync(this IAdapter1 a } /// Disposable object which waits for discovered devices. + /// The handler owns each device it receives and must dispose it. See . /// Adapter object. /// Action delegate with as a parameter. /// Disposable object.