/// <summary>
        /// Executes when a device is updated
        /// </summary>
        /// <param name="sender">The device watcher.</param>
        /// <param name="deviceInfoUpdate">The update device information.</param>
        private async void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
        {
            ObservableBluetoothLEDevice device = null;

            device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);

            if (device != null)
            {
                await device.UpdateAsync(deviceInfoUpdate);
            }

            if (device == null)
            {
                if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(2)))
                {
                    var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);

                    if (unusedDevice != null)
                    {
                        _unusedDevices.Remove(unusedDevice);
                        unusedDevice.Update(deviceInfoUpdate);
                    }

                    _readerWriterLockSlim.ExitWriteLock();

                    // The update to the unknown device means we should move it to the Bluetooth LE Device collection.
                    await AddDeviceToList(unusedDevice);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Executes when a device is updated
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="deviceInfoUpdate"></param>
        private void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
        {
            DeviceInformation di = null;
            var addNewDI         = false;

            try
            {
                // Protect against race condition if the task runs after the app stopped the deviceWatcher.
                if (sender == _deviceWatcher)
                {
                    BluetoothLEDeviceWrapper dev;

                    // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices
                    lock (_bluetoothLeDevicesLock)
                    {
                        dev =
                            BluetoothLeDevices.FirstOrDefault(
                                device => device.DeviceInfo.Id == deviceInfoUpdate.Id);
                        if (dev != null)
                        {
                            // Found a device in the list, updating it
                            dev.Update(deviceInfoUpdate);
                        }
                        else
                        {
                            // Need to add this device. Can't do that here as we have the lock
                            addNewDI = true;
                        }
                    }

                    if (addNewDI)
                    {
                        lock (_bluetoothLeDevicesLock)
                        {
                            di = _unusedDevices.FirstOrDefault(device => device.Id == deviceInfoUpdate.Id);
                            if (di != null)
                            {
                                // We found this device before.
                                _unusedDevices.Remove(di);
                                di.Update(deviceInfoUpdate);
                            }
                        }

                        if (di != null)
                        {
                            AddDeviceToList(di);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("DeviceWatcher_Updated exception: " + ex.Message);
            }
        }
        /// <summary>
        /// Executes when a device is removed from enumeration
        /// </summary>
        /// <param name="sender">The device watcher.</param>
        /// <param name="deviceInfoUpdate">An update of the device.</param>
        private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
        {
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
                {
                    var device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
                    BluetoothLeDevices.Remove(device);

                    var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
                    _unusedDevices?.Remove(unusedDevice);

                    _readerWriterLockSlim.ExitWriteLock();
                }
            });
        }
Esempio n. 4
0
        /// <summary>
        /// Adds the new or updated device to the displayed or unused list
        /// </summary>
        /// <param name="deviceInfo"></param>
        /// <returns></returns>
        private void AddDeviceToList(DeviceInformation deviceInfo)
        {
            // Make sure device name isn't blank or already present in the list.
            if (deviceInfo.Name != string.Empty)
            {
                BluetoothLEDeviceWrapper dev = new BluetoothLEDeviceWrapper(deviceInfo);

                // Let's make it connectible by default, we have error handles in case it doesn't work
                var connectable = true;

                // If the connectible key exists then let's read it
                if (dev.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") == true)
                {
                    connectable = (bool)dev.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"];
                }

                if (connectable)
                {
                    // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices
                    lock (_bluetoothLeDevicesLock)
                    {
                        if (BluetoothLeDevices.Contains(dev) == false)
                        {
                            _BluetoothLeDevices.Add(dev);
                            _BluetoothLeDevicesAdded.Add(dev);
                            DevicesChanged = true;
                        }
                    }
                }
                else
                {
                    lock (_bluetoothLeDevicesLock)
                    {
                        // Found but not adding because it's not connectable
                        _unusedDevices.Add(deviceInfo);
                    }
                }
            }
            else
            {
                lock (_bluetoothLeDevicesLock)
                {
                    //Found device without a name
                    _unusedDevices.Add(deviceInfo);
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Executes when a device is removed from enumeration
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="deviceInfoUpdate"></param>
        private 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)
                {
                    BluetoothLEDeviceWrapper dev;

                    // Need to lock as another DeviceWatcher might be modifying BluetoothLEDevices
                    lock (_bluetoothLeDevicesLock)
                    {
                        // 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
                            var removed = _BluetoothLeDevices.Remove(dev);
                            _BluetoothLeDevicesRemoved.Add(dev);
                            DevicesChanged = true;
                            Debug.Assert(removed == true, "DeviceWatcher_Removed: Failed to remove device from list");
                        }
                        else
                        {
                            // Did not find in displayed list, let's check the unused list
                            var di = _unusedDevices.FirstOrDefault(device => device.Id == deviceInfoUpdate.Id);

                            if (di != null)
                            {
                                // Found in unused devices, remove it
                                var removed = _unusedDevices.Remove(di);
                                Debug.Assert(removed == true, "DeviceWatcher_Removed: Failed to remove device from unused");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("DeviceWatcher_Removed: " + ex.Message);
            }
        }
        /// <summary>
        /// Starts enumeration of bluetooth device
        /// </summary>
        public void StartEnumeration()
        {
            if (_advertisementWatcher?.Status == BluetoothLEAdvertisementWatcherStatus.Started || _deviceWatcher != null)
            {
                return;
            }

            // 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(
                BluetoothLeDeviceWatcherAqs,
                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;

            _advertisementWatcher           = new BluetoothLEAdvertisementWatcher();
            _advertisementWatcher.Received += AdvertisementWatcher_Received;

            BluetoothLeDevices.Clear();

            _deviceWatcher.Start();
            _advertisementWatcher.Start();
        }
        /// <summary>
        /// Executes when a device is removed from enumeration
        /// </summary>
        /// <param name="sender">The device watcher.</param>
        /// <param name="deviceInfoUpdate">An update of the device.</param>
        private async void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
        {
            // Protect against race condition if the task runs after the app stopped the deviceWatcher.
            if (sender == _deviceWatcher)
            {
                await DispatcherQueue.ExecuteOnUIThreadAsync(
                    () =>
                {
                    if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
                    {
                        var device = BluetoothLeDevices.FirstOrDefault(i => i.DeviceInfo.Id == deviceInfoUpdate.Id);
                        BluetoothLeDevices.Remove(device);

                        var unusedDevice = _unusedDevices.FirstOrDefault(i => i.Id == deviceInfoUpdate.Id);
                        _unusedDevices?.Remove(unusedDevice);

                        _readerWriterLockSlim.ExitWriteLock();
                    }
                }, DispatcherQueuePriority.Normal);
            }
        }
        /// <summary>
        /// Adds the new or updated device to the displayed or unused list
        /// </summary>
        /// <param name="deviceInfo">The device to add</param>
        /// <returns>The task being used to add a device to a list</returns>
        private async Task AddDeviceToList(DeviceInformation deviceInfo)
        {
            // Make sure device name isn't blank or already present in the list.
            if (!string.IsNullOrEmpty(deviceInfo?.Name))
            {
                var device      = new ObservableBluetoothLEDevice(deviceInfo);
                var connectable = true;

                if (device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable"))
                {
                    connectable = (bool)device.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"];
                }

                if (connectable)
                {
                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
                        CoreDispatcherPriority.Normal,
                        () =>
                    {
                        if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
                        {
                            if (!BluetoothLeDevices.Contains(device))
                            {
                                BluetoothLeDevices.Add(device);
                            }

                            _readerWriterLockSlim.ExitWriteLock();
                        }
                    });

                    return;
                }
            }

            if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
            {
                _unusedDevices.Add(deviceInfo);
                _readerWriterLockSlim.ExitWriteLock();
            }
        }
        /// <summary>
        /// Adds the new or updated device to the displayed or unused list
        /// </summary>
        /// <param name="deviceInfo">The device to add</param>
        /// <returns>The task being used to add a device to a list</returns>
        private async Task AddDeviceToList(DeviceInformation deviceInfo)
        {
            // Make sure device name isn't blank or already present in the list.
            if (!string.IsNullOrEmpty(deviceInfo?.Name))
            {
                var device      = new ObservableBluetoothLEDevice(deviceInfo, DispatcherQueue);
                var connectable = (device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.Bluetooth.Le.IsConnectable") &&
                                   (bool)device.DeviceInfo.Properties["System.Devices.Aep.Bluetooth.Le.IsConnectable"]) ||
                                  (device.DeviceInfo.Properties.Keys.Contains("System.Devices.Aep.IsConnected") &&
                                   (bool)device.DeviceInfo.Properties["System.Devices.Aep.IsConnected"]);

                if (connectable)
                {
                    await DispatcherQueue.ExecuteOnUIThreadAsync(
                        () =>
                    {
                        if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
                        {
                            if (!BluetoothLeDevices.Contains(device))
                            {
                                BluetoothLeDevices.Add(device);
                            }

                            _readerWriterLockSlim.ExitWriteLock();
                        }
                    }, DispatcherQueuePriority.Normal);

                    return;
                }
            }

            if (_readerWriterLockSlim.TryEnterWriteLock(TimeSpan.FromSeconds(1)))
            {
                _unusedDevices.Add(deviceInfo);
                _readerWriterLockSlim.ExitWriteLock();
            }
        }