From ee75b3dca2404194c387cf2d2f4d040a4477dad8 Mon Sep 17 00:00:00 2001 From: Steven Moy Date: Tue, 12 May 2015 17:05:15 -0700 Subject: [PATCH] Fix phantom delegate trying to use its referenced gatt instance Prior to the change, when one disconnect a connected device in Android, Device instance inserts a delegate to GattCallback instance to cache discovered Services. However, when one disconnects such device, the delegate is not removed. So upon next device connection, that delegate will attempt to reference a disposed Gatt instance and cause a crash. To reproduce this bug, you can try the following sequence: 1) Scan for Devices 2) Connect to Device A 3) Discovers Service of Device A 4) Dsiconnect Device A 5) Connect to Device A again 6) Discovers Service of Device A 7) Crash --- .../Bluetooth/LE/Device.cs | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Source/Platform Stacks/Robotics.Mobile.Core.Droid/Bluetooth/LE/Device.cs b/Source/Platform Stacks/Robotics.Mobile.Core.Droid/Bluetooth/LE/Device.cs index 0e8cb5a..bb74899 100644 --- a/Source/Platform Stacks/Robotics.Mobile.Core.Droid/Bluetooth/LE/Device.cs +++ b/Source/Platform Stacks/Robotics.Mobile.Core.Droid/Bluetooth/LE/Device.cs @@ -33,17 +33,20 @@ public Device (BluetoothDevice nativeDevice, BluetoothGatt gatt, // when the services are discovered on the gatt callback, cache them here if (this._gattCallback != null) { - this._gattCallback.ServicesDiscovered += (s, e) => { - var services = this._gatt.Services; - this._services = new List (); - foreach (var item in services) { - this._services.Add (new Service (item, this._gatt, this._gattCallback)); - } - this.ServicesDiscovered (this, e); - }; + this._gattCallback.ServicesDiscovered += this.OnServiceDiscovered; } } + public void OnServiceDiscovered(object sender, ServicesDiscoveredEventArgs args) + { + var services = this._gatt.Services; + this._services = new List (); + foreach (var item in services) { + this._services.Add (new Service (item, this._gatt, this._gattCallback)); + } + this.ServicesDiscovered (this, args); + } + public override Guid ID { get { //TODO: verify - fix from Evolve player @@ -104,7 +107,11 @@ public override void DiscoverServices () public void Disconnect () { this._gatt.Disconnect (); - this._gatt.Dispose (); + if (this._gattCallback != null) { + this._gattCallback.ServicesDiscovered -= this.OnServiceDiscovered; + } + this._gatt.Close (); + this._gatt = null; } #endregion