/// <summary> /// Release all resources without clearing all devices /// </summary> public void ReleaseAllResources() { try { BluetoothLEDevicesLock.Wait(); BluetoothLEDevices.Dispose(); } finally { BluetoothLEDevicesLock.Release(); } }
/// <summary> /// Clears all devices /// </summary> public void ClearAllDevices() { try { BluetoothLEDevicesLock.Wait(); BluetoothLEDevices.Clear(); } finally { BluetoothLEDevicesLock.Release(); } }
/// <summary> /// Adds the new or updated device to the displayed or unused list /// </summary> /// <param name="deviceInfo"></param> /// <returns></returns> private async Task AddDeviceToList(DeviceInformation deviceInfo) { ObservableBluetoothLEDevice dev = new ObservableBluetoothLEDevice(deviceInfo); // Let's make it connectable by default, we have error handles in case it doesn't work bool shouldDisplay = ((dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") && (bool)dev.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"])) || ((dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsConnected") && (bool)dev.DeviceInfo.Properties["System.Devices.Aep.IsConnected"])); if (shouldDisplay) { // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices try { await BluetoothLEDevicesLock.WaitAsync(); await UpdateBatteryLevel(dev); if ((dev.Name.Length != 0) && (!BluetoothLEDevices.Contains(dev))) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, () => { Log.WriteLine("~~~Finding device: " + dev.Name); BluetoothLEDevices.Add(dev); OnPropertyChanged(new PropertyChangedEventArgs("DeviceList")); }); } } finally { BluetoothLEDevicesLock.Release(); } } else { try { await BluetoothLEDevicesLock.WaitAsync(); unusedDevices.Add(deviceInfo); } finally { BluetoothLEDevicesLock.Release(); } } }
/// <summary> /// Adds the new or updated device to the displayed or unused list /// </summary> /// <param name="deviceInfo"></param> /// <returns></returns> private async Task AddDeviceToList(DeviceInformation deviceInfo) { ObservableBluetoothLEDevice dev = new ObservableBluetoothLEDevice(deviceInfo); // Let's make it connectable by default, we have error handles in case it doesn't work bool shouldDisplay = ((dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") && (bool)dev.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"])) || ((dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsConnected") && (bool)dev.DeviceInfo.Properties["System.Devices.Aep.IsConnected"])) || ((dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsPaired") && (bool)dev.DeviceInfo.Properties["System.Devices.Aep.IsPaired"])); if (shouldDisplay) { // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices try { await BluetoothLEDevicesLock.WaitAsync(); if (!BluetoothLEDevices.Contains(dev)) { await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, () => { BluetoothLEDevices.Add(dev); }); } } finally { BluetoothLEDevicesLock.Release(); } } else { try { await BluetoothLEDevicesLock.WaitAsync(); unusedDevices.Add(deviceInfo); dev.Dispose(); } finally { BluetoothLEDevicesLock.Release(); } } }
/// <summary> /// Adds the new or updated device to the displayed or unused list /// </summary> /// <param name="deviceInfo"></param> /// <returns></returns> private async Task AddDeviceToList(DeviceInformation deviceInfo) { ObservableBluetoothLEDevice dev = new ObservableBluetoothLEDevice(deviceInfo); // Let's make it connectable by default, we have error handles in case it doesn't work bool shouldDisplay = ((dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") && (bool)dev.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"])) || ((dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsConnected") && (bool)dev.DeviceInfo.Properties["System.Devices.Aep.IsConnected"])) || ((dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsPaired") && (bool)dev.DeviceInfo.Properties["System.Devices.Aep.IsPaired"])); if (shouldDisplay) { // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices try { await BluetoothLEDevicesLock.WaitAsync(); UpdateBatteryLevel(dev); if (!BluetoothLEDevices.Contains(dev)) { BluetoothLEDevices.Add(dev); OnDeviceEnumEvent(new BLTEEnumEventArgs() { Notify = BLTEEnumEvent.Add, Device = dev }); } } finally { BluetoothLEDevicesLock.Release(); } } else { try { await BluetoothLEDevicesLock.WaitAsync(); unusedDevices.Add(deviceInfo); } finally { BluetoothLEDevicesLock.Release(); } } }
/// <summary> /// Executes when a device is removed from enumeration /// </summary> /// <param name="sender"></param> /// <param name="deviceInfoUpdate"></param> private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { try { // Protect against race condition if the task runs after the app stopped the deviceWatcher. if (sender == deviceWatcher) { ObservableBluetoothLEDevice dev; try { // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices await BluetoothLEDevicesLock.WaitAsync(); // Find the corresponding DeviceInformation in the collection and remove it. dev = BluetoothLEDevices.FirstOrDefault(device => device.DeviceInfo.Id == deviceInfoUpdate.Id); if (dev != null) { // Found it in our displayed devices await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, () => { Debug.Assert(BluetoothLEDevices.Remove(dev), "DeviceWatcher_Removed: Failed to remove device from list"); }); } else { // Did not find in diplayed list, let's check the unused list DeviceInformation di = unusedDevices.FirstOrDefault(device => device.Id == deviceInfoUpdate.Id); if (di != null) { // Found in unused devices, remove it Debug.Assert(unusedDevices.Remove(di), "DeviceWatcher_Removed: Failed to remove device from unused"); } } } finally { BluetoothLEDevicesLock.Release(); } } } catch (Exception ex) { Debug.WriteLine("DeviceWatcher_Removed: " + ex.Message); } }
/// <summary> /// Executes when a device is removed from enumeration /// </summary> /// <param name="sender"></param> /// <param name="deviceInfoUpdate"></param> private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { try { // Protect against race condition if the task runs after the app stopped the deviceWatcher. if (sender == deviceWatcher) { ObservableBluetoothLEDevice dev; try { // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices await BluetoothLEDevicesLock.WaitAsync(); // Find the corresponding DeviceInformation in the collection and remove it. dev = BluetoothLEDevices.FirstOrDefault(device => device.DeviceInfo.Id == deviceInfoUpdate.Id); if (dev != null) { // Found it in our displayed devices OnDeviceEnumEvent(new BLTEEnumEventArgs() { Notify = BLTEEnumEvent.Remove, Device = dev }); Debug.Assert(BluetoothLEDevices.Remove(dev), "DeviceWatcher_Removed: Failed to remove device from list"); } else { // Did not find in diplayed list, let's check the unused list DeviceInformation di = unusedDevices.FirstOrDefault(device => device.Id == deviceInfoUpdate.Id); if (di != null) { // Found in unused devices, remove it Debug.Assert(unusedDevices.Remove(di), "DeviceWatcher_Removed: Failed to remove device from unused"); } } } finally { BluetoothLEDevicesLock.Release(); } } } catch (Exception ex) { Debug.WriteLine("DeviceWatcher_Removed: " + ex.Message); } }
/// <summary> /// Starts enumeration of bluetooth device /// </summary> public void StartEnumeration() { // Additional properties we would like about the device. string[] requestedProperties = { "System.Devices.Aep.Category", "System.Devices.Aep.ContainerId", "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.IsPaired", "System.Devices.Aep.IsPresent", "System.Devices.Aep.ProtocolId", "System.Devices.Aep.Bluetooth.Le.IsConnectable", "System.Devices.Aep.SignalStrength" }; // BT_Code: Currently Bluetooth APIs don't provide a selector to get ALL devices that are both paired and non-paired. deviceWatcher = DeviceInformation.CreateWatcher( BTLEDeviceWatcherAQSString, requestedProperties, DeviceInformationKind.AssociationEndpoint); // Register event handlers before starting the watcher. deviceWatcher.Added += DeviceWatcher_Added; deviceWatcher.Updated += DeviceWatcher_Updated; deviceWatcher.Removed += DeviceWatcher_Removed; deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted; deviceWatcher.Stopped += DeviceWatcher_Stopped; advertisementWatcher = new BluetoothLEAdvertisementWatcher(); advertisementWatcher.ScanningMode = BluetoothLEScanningMode.Active; advertisementWatcher.Received += AdvertisementWatcher_Received; BluetoothLEDevices.Clear(); deviceWatcher.Start(); advertisementWatcher.Start(); IsEnumerating = true; EnumerationFinished = false; }
/// <summary> /// Executes when a device is updated /// </summary> /// <param name="sender"></param> /// <param name="deviceInfoUpdate"></param> private async void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { DeviceInformation di = null; bool addNewDI = false; try { // Protect against race condition if the task runs after the app stopped the deviceWatcher. if (sender == deviceWatcher) { ObservableBluetoothLEDevice dev; // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices try { await BluetoothLEDevicesLock.WaitAsync(); dev = BluetoothLEDevices.FirstOrDefault(device => device.DeviceInfo.Id == deviceInfoUpdate.Id); if (dev != null) { // Found a device in the list, updating it await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { dev.Update(deviceInfoUpdate); }); } else { // Need to add this device. Can't do that here as we have the lock addNewDI = true; } } finally { BluetoothLEDevicesLock.Release(); } if (addNewDI == true) { try { await BluetoothLEDevicesLock.WaitAsync(); di = unusedDevices.FirstOrDefault(device => device.Id == deviceInfoUpdate.Id); if (di != null) { // We found this device before. unusedDevices.Remove(di); di.Update(deviceInfoUpdate); } } finally { BluetoothLEDevicesLock.Release(); } if (di != null) { await AddDeviceToList(di); } } } } catch (Exception ex) { Debug.WriteLine("DeviceWatcher_Updated: " + ex.Message); } }