Exemple #1
0
        private void OnDeviceConnectionStatusChanged(BluetoothLEDevice sender, object args)
        {
            if (_disposeCount != 0)
            {
                return;
            }

            BluetoothConnectionStatus status = _device.ConnectionStatus;

            Debug.WriteLine($"Connection status: {status}");
            if (status == BluetoothConnectionStatus.Connected)
            {
                Connected?.Invoke(this, EventArgs.Empty);
                try
                {
                    _connectionTimer.Change(Timeout.Infinite, Timeout.Infinite);
                }
                catch
                {
                }
            }
            else
            {
                Disconnected?.Invoke(this, EventArgs.Empty);
                try
                {
                    _connectionTimer.Change(30000, Timeout.Infinite);
                }
                catch
                {
                }
            }
        }
        private RadialGradientBrush UpdateMyoConnectionImage(BluetoothConnectionStatus newStatus)
        {
            RadialGradientBrush newBrush = new RadialGradientBrush();

            newBrush.GradientOrigin = new System.Windows.Point(0.5, 0.5);
            newBrush.Center         = new System.Windows.Point(0.5, 0.5);

            if (newStatus == BluetoothConnectionStatus.Connected)
            {
                GradientStop greenGS = new GradientStop();
                greenGS.Color  = Colors.Green;
                greenGS.Offset = 0.0;
                newBrush.GradientStops.Add(greenGS);
            }
            else if (newStatus == BluetoothConnectionStatus.Disconnected)
            {
                GradientStop greenGS = new GradientStop();
                greenGS.Color  = Colors.Red;
                greenGS.Offset = 0.0;
                newBrush.GradientStops.Add(greenGS);
            }

            GradientStop seethruGS = new GradientStop();

            seethruGS.Color  = Colors.Transparent;
            seethruGS.Offset = 1.0;
            newBrush.GradientStops.Add(seethruGS);

            return(newBrush);
        }
        public async Task <IGeolocator> GetGeolocator()
        {
            IGeolocator geoLocator = null;

            if (deviceCanonicalNames != null && deviceCanonicalNames.Length > 0)
            {
                var qstarsGeolocator = new QstarzGeolocator();
                foreach (string deviceName in deviceCanonicalNames)
                {
                    BluetoothConnectionStatus status = await qstarsGeolocator.ConnectToDevice(deviceName);

                    if (status == BluetoothConnectionStatus.BluetoothDisabled)
                    {
                        qstarsGeolocator.Dispose();
                        break;
                    }
                    if (status == BluetoothConnectionStatus.DeviceNotFound)
                    {
                        qstarsGeolocator.Dispose();
                        continue;
                    }
                    geoLocator = qstarsGeolocator;
                    break;
                }
            }
            if (geoLocator == null)
            {
                geoLocator = new InternalGeolocator();
            }

            return(geoLocator);
        }
Exemple #4
0
 private void Default_DeviceConnected(object sender, ulong e)
 {
     if (e == BluetoothAddress)
     {
         _connectionStatus = BluetoothConnectionStatus.Connected;
         RaiseConnectionStatusChanged();
     }
 }
Exemple #5
0
 public void BleCore_DeviceConnectionStatus(BluetoothConnectionStatus status)
 {
     //if (status == BluetoothConnectionStatus.Disconnected)
     //{
     //    deviceServices.Clear();
     //    writeCharacteristic.Clear();
     //    notifyCharacteristics.Clear();
     //}
 }
Exemple #6
0
 public static string GetDeviceSelectorFromConnectionStatus(BluetoothConnectionStatus connectionStatus)
 {
     if (connectionStatus == BluetoothConnectionStatus.Connected)
     {
         return(_deviceSelectorPrefix + "(System.Devices.Aep.IsConnected:=System.StructuredQueryType.Boolean#True OR " + _deviceSelectorIssueInquiry + "#False)");
     }
     else
     {
         return(_deviceSelectorPrefix + "(System.Devices.Aep.IsConnected:=System.StructuredQueryType.Boolean#False OR " + _deviceSelectorIssueInquiry + "#True)");
     }
 }
 private void Device_ConnectionStatusChanged(Device device, BluetoothConnectionStatus status)
 {
     if (status == BluetoothConnectionStatus.Connected)
     {
         HandleConnectedDevice(device);
     }
     else
     {
         HandleDisconnectedDevice(true, device);
     }
 }
Exemple #8
0
        public static ConnectionStatus ToConnectionStatus(this BluetoothConnectionStatus status)
        {
            switch (status)
            {
            case BluetoothConnectionStatus.Connected:
                return(ConnectionStatus.Connected);

            case BluetoothConnectionStatus.Disconnected:
                return(ConnectionStatus.Disconnected);

            default:
                return(ConnectionStatus.Unknow);
            }
        }
        public static BLE_ConnectStatus Convert(this BluetoothConnectionStatus status)
        {
            switch (status)
            {
            case BluetoothConnectionStatus.Disconnected:
                return(BLE_ConnectStatus.Disconnected);

            case BluetoothConnectionStatus.Connected:
                return(BLE_ConnectStatus.Connected);

            default:
                // Just for compiler. Only 2 enums
                return(BLE_ConnectStatus.Disconnected);
            }
        }
Exemple #10
0
        private async void OnConnectionTimerCallback(object state)
        {
            if (_disposeCount != 0)
            {
                return;
            }
            try
            {
                BluetoothConnectionStatus status = _device.ConnectionStatus;
                if (status == BluetoothConnectionStatus.Connected)
                {
                    return;
                }

                await _deviceSemaphore.WaitAsync();

                try
                {
                    if (_characteristic != null)
                    {
                        await UnsubscribeFromDevice();
                    }
                    _device.Dispose();
                    _device = null;
                    if (!await SubscribeToNotificationsInternal(_externalReadCallback, sync: false) && _disposeCount == 0)
                    {
                        // Failed to reconnect
                        try
                        {
                            _connectionTimer.Change(60000, Timeout.Infinite);
                        }
                        catch (ObjectDisposedException)
                        {
                        }
                    }
                }
                finally
                {
                    _deviceSemaphore.Release();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }
        private void CONNECTION_STATUS_CALLBACK(short wServiceClass, IntPtr lpBdAddr, NativeMethods.CONNECTION_STATUS ucStatus, int dwConnetionHandle)
        {
            BluetoothConnection connection;

            if (!lookupConnections.TryGetValue(dwConnetionHandle, out connection))
            {
                return;
            }
            BluetoothConnectionStatus newStatus = BluetoothConnectionStatus.Connected;

            if (ucStatus == NativeMethods.CONNECTION_STATUS.STATUS_INCOMING_DISCONNECT || ucStatus == NativeMethods.CONNECTION_STATUS.STATUS_OUTGOING_DISCONNECT)
            {
                newStatus = BluetoothConnectionStatus.Disconnected;
            }
            connection.Status = newStatus;

            lookupConnections.Remove(connection.ConnectionHandle);
            connections.Remove(connection);

            if (newStatus == BluetoothConnectionStatus.Disconnected)
            {
                OnConnectionClosed(new BluetoothConnectionEventArgs(connection));
            }
        }
Exemple #12
0
 /// <summary>
 /// Creates a filter string that contains a query for Bluetooth LE devices with the indicated BluetoothConnectionStatus.
 /// The string is passed into the CreateWatcher method to return a collection of DeviceInformation objects with the indicated Bluetooth connection status.
 /// </summary>
 /// <param name="connectionStatus">The connection status used for constructing the AQS string.</param>
 /// <returns></returns>
 public static string GetDeviceSelectorFromConnectionStatus(BluetoothConnectionStatus connectionStatus)
 {
     return(GetDeviceSelectorFromConnectionStatusImpl(connectionStatus));
 }
 //////////////////////////////////////////////////////////////////////////
 // Bluetooth Event Handlers
 private void BtConnectionStatusChanged(Earbuds sener, BluetoothDevice btDevice, BluetoothConnectionStatus connectionStatus)
 {
     UpdateMenu();
 }
Exemple #14
0
 private static string GetDeviceSelectorFromConnectionStatusImpl(BluetoothConnectionStatus connectionStatus)
 {
     return(string.Empty);
 }
 private static string GetDeviceSelectorFromConnectionStatusImpl(BluetoothConnectionStatus connectionStatus)
 {
     return("connected:" + (connectionStatus == BluetoothConnectionStatus.Connected ? "true" : "false"));
 }
 //////////////////////////////////////////////////////////////////////////
 // Bluetooth LE Event Handlers
 private void BleConnectionStatusChanged(Earbuds sener, BluetoothLEDevice bleDevice, BluetoothConnectionStatus connectionStatus)
 {
     Log.D($"BleConnectionStatusChanged(DeviceID:{bleDevice.DeviceId}\nStatus:{connectionStatus})");
     UpdateMenu();
 }
 private static string GetDeviceSelectorFromConnectionStatusImpl(BluetoothConnectionStatus connectionStatus)
 {
     return(Windows.Devices.Bluetooth.BluetoothLEDevice.GetDeviceSelectorFromConnectionStatus((Windows.Devices.Bluetooth.BluetoothConnectionStatus)connectionStatus));
 }
		public DeviceInformationItem(BluetoothLEDevice device)
			: base()
		{
			this.Device = device;
			this.DeviceAddress = GattServiceHelper.ToStringAddress(device.BluetoothAddress);
			try
			{
				foreach (var service in device.GattServices)
				{
					switch (service.Uuid.ToString())
					{
						case "00001811-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.ALERT_NOTIFICATION, service);
							break;
						case "0000180f-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.BATTERY, service);
							break;
						case "00001810-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.BLOOD_PRESSURE, service);
							break;
						case "00001805-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.CURRENT_TIME, service);
							break;
						case "00001818-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.CYCLING_POWER, service);
							break;
						case "00001816-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.CYCLING_SPEED_AND_CADENCE, service);
							break;
						case "0000180a-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.DEVICE_INFORMATION, service);
							break;
						case "00001800-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.GENERIC_ACCESS, service);
							break;
						case "00001801-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.GENERIC_ATTRIBUTES, service);
							break;
						case "00001808-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.GLUCOSE, service);
							break;
						case "00001809-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.HEALTH_THERMOMETER, service);
							break;
						case "0000180d-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.HEART_RATE, service);
							break;
						case "00001812-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.HUMAN_INTERFACE_DEVICE, service);
							break;
						case "00001802-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.IMMEDIATE_ALERT, service);
							break;
						case "00001803-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.LINK_LOSS, service);
							break;
						case "00001819-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.LOCATION_AND_NAVIGATION, service);
							break;
						case "00001807-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.NEXT_DST_CHANGE, service);
							break;
						case "0000180e-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.PHONE_ALERT_STATUS, service);
							break;
						case "00001806-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.REFERENCE_TIME_UPDATE, service);
							break;
						case "00001814-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.RUNNING_SPEED_AND_CADENCE, service);
							break;
						case "00001813-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.SCAN_PARAMETERS, service);
							break;
						case "00001804-0000-1000-8000-00805f9b34fb":
							Services.Add(ToolboxIdentifications.GattServiceNames.TX_POWER, service);
							break;
						case "00001530-1212-efde-1523-785feabcd123":
							Services.Add(ToolboxIdentifications.GattServiceNames.DEVICE_FIRMWARE_UPDATE, service);
							break;
						case "6e400001-b5a3-f393-e0a9-e50e24dcca9e":
							Services.Add(ToolboxIdentifications.GattServiceNames.NORDIC_UART, service);
							break;
						default:
							break;
					}

				}
			}
			catch (Exception e)
			{
				//Catch any exceptions and make alert to phone or user
			}
			if (LocalSettings.Values.ContainsKey(DeviceAddress))
			{
				string[] values = ((string)LocalSettings.Values[DeviceAddress]).Split(',');
				AlertOnPhone = bool.Parse(values[0]);
				AlertOnDevice = bool.Parse(values[1]);
				//alertLevel = (AlertLevel)Enum.Parse(typeof(AlertLevel), values[2]);
			}
			this.CompleteDeviceName = device.Name;
			this.DeviceID = device.DeviceId;
			this.ConnectionStatus = device.ConnectionStatus;
		}
        /// <summary>
        /// Initialize the device.
        /// </summary>
        /// <param name="deviceInformation">An instance of DeviceInformation class corresponding to the BluetoothLEDevice.</param>
        /// <param name="bluetoothAddress">The bluetooth address of the device.</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task Initialize(DeviceInformation deviceInformation, ulong bluetoothAddress, CancellationToken cancellationToken)
        {
            if (deviceInformation.Pairing.IsPaired)
            {
                // If the device is paired, all we have to do is just getting BluetoothLEDevice object by its ID.
                this.bleDevice = (await BluetoothLEDevice.FromIdAsync(deviceInformation.Id)).AddTo(this.disposables);
                this.service   = this.bleDevice.GetGattService(ServiceUuid).AddTo(this.disposables);
            }
            else
            {
                // If the device is not paired, pair with the device.
                var result = await deviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);

                switch (result.Status)
                {
                case DevicePairingResultStatus.Paired:
                    // The device has been paired successfully.
                    break;

                default:
                    throw new ImbleOperationException("Failed to pair with the device.");
                }

                // After the PairAsync method returns, we have to wait until the device paired is registered to the system.
                var selector        = BluetoothLEDevice.GetDeviceSelectorFromBluetoothAddress(bluetoothAddress);
                var watcher         = DeviceInformation.CreateWatcher(selector);
                var deviceAddedTask = EventSubscription.ReceiveFirst <DeviceWatcher, DeviceInformation>(handler => watcher.Added += handler, handler => watcher.Added -= handler, cancellationToken);
                watcher.Start();
                var bleDeviceInformation = await deviceAddedTask;   // Wait until the target device is added.
                watcher.Stop();

                this.bleDevice = (await BluetoothLEDevice.FromIdAsync(bleDeviceInformation.Id)).AddTo(this.disposables);
                var gattServiceChangedTask = EventSubscription.ReceiveFirst <BluetoothLEDevice, object>(handler => this.bleDevice.GattServicesChanged += handler, handler => this.bleDevice.GattServicesChanged -= handler, cancellationToken);

                this.service = this.bleDevice.GetGattService(ServiceUuid);
                if (this.service == null)
                {
                    // If the GATT services have not been enumerated yet, wait until the enumeration completes.
                    await gattServiceChangedTask;
                    this.service = this.bleDevice.GetGattService(ServiceUuid);
                }
            }

            // Get the READ characteristic in the IMBLE service.
            this.readCharacteristic = this.service.GetCharacteristics(ReadCharacteristicUuid).Single();
            EventSubscription.Subscribe <GattCharacteristic, GattValueChangedEventArgs>(
                handler => this.readCharacteristic.ValueChanged += handler,
                handler => this.readCharacteristic.ValueChanged -= handler,
                (sender, args) =>
            {
                if (args.CharacteristicValue.Length < 4)
                {
                    return;                                          // The length of data is too short.
                }
                var data   = args.CharacteristicValue.ToArray();
                var length = data[0] + 1;
                if (data.Length < length)
                {
                    return;                           // The length field is invalid. Ignore this data.
                }
                var body = new byte[length - 4];
                Array.Copy(data, 4, body, 0, body.Length);
                this.DataArrived?.Invoke(this, new DataArrivedEventArgs(body, args.Timestamp));
            })
            .AddTo(this.disposables);

            // Enable notification of the READ characteristic.
            var readCccdResult = await this.readCharacteristic.ReadClientCharacteristicConfigurationDescriptorAsync().AsTask(cancellationToken);

            var readCccd = readCccdResult.ClientCharacteristicConfigurationDescriptor | GattClientCharacteristicConfigurationDescriptorValue.Notify;

            for (var retryCount = 0;; retryCount++)
            {
                try
                {
                    using (var timeoutCancel = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
                        using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCancel.Token))
                        {
                            await this.readCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(readCccd).AsTask(linkedTokenSource.Token);
                        }
                    break;
                }
                catch (Exception ex)
                {
                    if (retryCount > 3)
                    {
                        throw new ImbleOperationException("Failed to configure the device.", ex);
                    }
                }
            }

            this.writeCharacteristic = this.service.GetCharacteristics(WriteCharacteristicUuid).Single();

            EventSubscription.Subscribe <TypedEventHandler <BluetoothLEDevice, object> >(
                handler => this.bleDevice.ConnectionStatusChanged += handler,
                handler => this.bleDevice.ConnectionStatusChanged -= handler,
                (device, _) =>
            {
                this.ConnectionStatus = device.ConnectionStatus;
            })
            .AddTo(this.disposables);

            this.ConnectionStatus = this.service.Device.ConnectionStatus;

            this.Status = ImbleDeviceStatus.Running;
        }
        /// <summary>
        /// Initialize the device.
        /// </summary>
        /// <param name="deviceInformation">An instance of DeviceInformation class corresponding to the BluetoothLEDevice.</param>
        /// <param name="bluetoothAddress">The bluetooth address of the device.</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task Initialize(DeviceInformation deviceInformation, ulong bluetoothAddress, CancellationToken cancellationToken)
        {
            if (deviceInformation.Pairing.IsPaired)
            {
                // If the device is paired, all we have to do is just getting BluetoothLEDevice object by its ID.
                this.bleDevice = (await BluetoothLEDevice.FromIdAsync(deviceInformation.Id)).AddTo(this.disposables);
                this.service = this.bleDevice.GetGattService(ServiceUuid).AddTo(this.disposables);
            }
            else
            {
                // If the device is not paired, pair with the device.
                var result = await deviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
                switch(result.Status)
                {
                    case DevicePairingResultStatus.Paired:
                        // The device has been paired successfully.
                        break;
                    default:
                        throw new ImbleOperationException("Failed to pair with the device.");
                }

                // After the PairAsync method returns, we have to wait until the device paired is registered to the system.
                var selector = BluetoothLEDevice.GetDeviceSelectorFromBluetoothAddress(bluetoothAddress);
                var watcher = DeviceInformation.CreateWatcher(selector);
                var deviceAddedTask = EventSubscription.ReceiveFirst<DeviceWatcher, DeviceInformation>(handler => watcher.Added += handler, handler => watcher.Added -= handler, cancellationToken);
                watcher.Start();
                var bleDeviceInformation = await deviceAddedTask;   // Wait until the target device is added.
                watcher.Stop();

                this.bleDevice = (await BluetoothLEDevice.FromIdAsync(bleDeviceInformation.Id)).AddTo(this.disposables);
                var gattServiceChangedTask = EventSubscription.ReceiveFirst<BluetoothLEDevice, object>(handler => this.bleDevice.GattServicesChanged += handler, handler => this.bleDevice.GattServicesChanged -= handler, cancellationToken);

                this.service = this.bleDevice.GetGattService(ServiceUuid);
                if(this.service == null)
                {
                    // If the GATT services have not been enumerated yet, wait until the enumeration completes.
                    await gattServiceChangedTask;
                    this.service = this.bleDevice.GetGattService(ServiceUuid);
                }
            }
            
            // Get the READ characteristic in the IMBLE service.
            this.readCharacteristic = this.service.GetCharacteristics(ReadCharacteristicUuid).Single();
            EventSubscription.Subscribe<GattCharacteristic, GattValueChangedEventArgs>(
                handler => this.readCharacteristic.ValueChanged += handler,
                handler => this.readCharacteristic.ValueChanged -= handler,
                (sender, args) =>
                {
                    if (args.CharacteristicValue.Length < 4) return; // The length of data is too short.

                    var data = args.CharacteristicValue.ToArray();
                    var length = data[0] + 1;
                    if (data.Length < length) return; // The length field is invalid. Ignore this data.

                    var body = new byte[length - 4];
                    Array.Copy(data, 4, body, 0, body.Length);
                    this.DataArrived?.Invoke(this, new DataArrivedEventArgs(body, args.Timestamp));
                })
                .AddTo(this.disposables);

            // Enable notification of the READ characteristic.
            var readCccdResult = await this.readCharacteristic.ReadClientCharacteristicConfigurationDescriptorAsync().AsTask(cancellationToken);
            var readCccd = readCccdResult.ClientCharacteristicConfigurationDescriptor | GattClientCharacteristicConfigurationDescriptorValue.Notify;
            for (var retryCount = 0;; retryCount++)
            {
                try
                {
                    using (var timeoutCancel = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
                    using(var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCancel.Token))
                    {
                        await this.readCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(readCccd).AsTask(linkedTokenSource.Token);
                    }
                    break;
                }
                catch (Exception ex)
                {
                    if (retryCount > 3) throw new ImbleOperationException("Failed to configure the device.", ex);
                }
            }

            this.writeCharacteristic = this.service.GetCharacteristics(WriteCharacteristicUuid).Single();

            EventSubscription.Subscribe<TypedEventHandler<BluetoothLEDevice, object>>(
                handler => this.bleDevice.ConnectionStatusChanged += handler,
                handler => this.bleDevice.ConnectionStatusChanged -= handler,
                (device, _) =>
                {
                    this.ConnectionStatus = device.ConnectionStatus;
                })
                .AddTo(this.disposables);

            this.ConnectionStatus = this.service.Device.ConnectionStatus;
            
            this.Status = ImbleDeviceStatus.Running;
            
        }
Exemple #21
0
 public BleDeviceConnectionStatusChangedEventArgs(BluetoothConnectionStatus status)
 {
     ConnectionStatus = status;
 }
        public DeviceInformationItem(BluetoothLEDevice device)
        {
            this.Device        = device;
            this.DeviceAddress = ConvertingTools.GetBLEMacAddress(device.BluetoothAddress);
            try
            {
                foreach (var service in device.GattServices)
                {
                    switch (service.Uuid.ToString())
                    {
                    case "00001811-0000-1000-8000-00805f9b34fb":
                        Services.Add("AlertNotification", service);
                        break;

                    case "0000180f-0000-1000-8000-00805f9b34fb":
                        Services.Add("Battery", service);
                        break;

                    case "00001810-0000-1000-8000-00805f9b34fb":
                        Services.Add("BloodPressure", service);
                        break;

                    case "00001805-0000-1000-8000-00805f9b34fb":
                        Services.Add("CurrentTime", service);
                        break;

                    case "00001818-0000-1000-8000-00805f9b34fb":
                        Services.Add("CyclingPower", service);
                        break;

                    case "00001816-0000-1000-8000-00805f9b34fb":
                        Services.Add("CyclingSpeedAndCadence", service);
                        break;

                    case "0000180a-0000-1000-8000-00805f9b34fb":
                        Services.Add("DeviceInformation", service);
                        break;

                    case "00001800-0000-1000-8000-00805f9b34fb":
                        Services.Add("GenericAccess", service);
                        break;

                    case "00001801-0000-1000-8000-00805f9b34fb":
                        Services.Add("GenericAttribute", service);
                        break;

                    case "00001808-0000-1000-8000-00805f9b34fb":
                        Services.Add("Glucose", service);
                        break;

                    case "00001809-0000-1000-8000-00805f9b34fb":
                        Services.Add("HealthThermometer", service);
                        break;

                    case "0000180d-0000-1000-8000-00805f9b34fb":
                        Services.Add("HeartRate", service);
                        break;

                    case "00001812-0000-1000-8000-00805f9b34fb":
                        Services.Add("HumanInterfaceDevice", service);
                        break;

                    case "00001802-0000-1000-8000-00805f9b34fb":
                        Services.Add("ImmediateAlert", service);
                        break;

                    case "00001803-0000-1000-8000-00805f9b34fb":
                        Services.Add("LinkLoss", service);
                        break;

                    case "00001819-0000-1000-8000-00805f9b34fb":
                        Services.Add("LocationAndNavigation", service);
                        break;

                    case "00001807-0000-1000-8000-00805f9b34fb":
                        Services.Add("NextDstChange", service);
                        break;

                    case "0000180e-0000-1000-8000-00805f9b34fb":
                        Services.Add("PhoneAlertStatus", service);
                        break;

                    case "00001806-0000-1000-8000-00805f9b34fb":
                        Services.Add("ReferenceTimeUpdate", service);
                        break;

                    case "00001814-0000-1000-8000-00805f9b34fb":
                        Services.Add("RunningSpeedAndCadence", service);
                        break;

                    case "00001813-0000-1000-8000-00805f9b34fb":
                        Services.Add("ScanParameters", service);
                        break;

                    case "00001804-0000-1000-8000-00805f9b34fb":
                        Services.Add("TxPower", service);
                        break;

                    case "00001530-1212-efde-1523-785feabcd123":
                        Services.Add(GATTServiceIdentification.DEVICE_FIRMWARE_UPDATE, service);
                        break;

                    //case "00001531-1212-efde-1523-785feabcd123":
                    //	Services.Add("Packet", service);
                    //	break;
                    //case "00001532-1212-efde-1523-785feabcd123":
                    //	Services.Add("ControlPoint", service);
                    //	break;
                    //case "00001534-1212-efde-1523-785feabcd123":
                    //	Services.Add("DFUVersion", service);
                    //	break;
                    default:
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                //Catch any exceptions and make alert to phone or user
            }
            if (LocalSettings.Values.ContainsKey(DeviceAddress))
            {
                string[] values = ((string)LocalSettings.Values[DeviceAddress]).Split(',');
                AlertOnPhone  = bool.Parse(values[0]);
                AlertOnDevice = bool.Parse(values[1]);
                //alertLevel = (AlertLevel)Enum.Parse(typeof(AlertLevel), values[2]);
            }
            this.CompleteDeviceName = device.Name;
            this.DeviceID           = device.DeviceId;
            this.ConnectionStatus   = device.ConnectionStatus;
        }
        private async void OnBtConnectionStateChangedObservers(Earbuds sendor, BluetoothDevice bluetoothDevice, BluetoothConnectionStatus connectionStatus)
        {
            if (sendor != null)
            {
                bool result;
                result = await sendor.ConnectSpp();

                Log.D($"PairWithMac(): Request to connect Spp with {LocalBtAddress}, result = {result}");

                // FIXME: Retry if failed to connect A2DP over SPP
                for (int i = 0; i < 10; ++i)
                {
                    result = await sendor.SppConnectA2DP(LocalBtAddress);

                    Log.D($"PairWithMac(): Request to connect A2DP with {LocalBtAddress}, try={i}, result = {result}");
                    if (result)
                    {
                        break;
                    }
                }

                sendor.DisconnectSpp();
                Log.D($"PairWithMac(): Request to Disconnect SPP with {LocalBtAddress}");

                sendor.BtConnectionStateChangedObservers -= OnBtConnectionStateChangedObservers;
                sendor.DisableSppConnection();
            }
        }
		public DeviceInformationItem(BluetoothLEDevice device)
		{
			this.Device = device;
			this.DeviceAddress = ConvertingTools.GetBLEMacAddress(device.BluetoothAddress);
			try
			{
				foreach (var service in device.GattServices)
				{
					switch (service.Uuid.ToString())
					{
						case "00001811-0000-1000-8000-00805f9b34fb":
							Services.Add("AlertNotification", service);
							break;
						case "0000180f-0000-1000-8000-00805f9b34fb":
							Services.Add("Battery", service);
							break;
						case "00001810-0000-1000-8000-00805f9b34fb":
							Services.Add("BloodPressure", service);
							break;
						case "00001805-0000-1000-8000-00805f9b34fb":
							Services.Add("CurrentTime", service);
							break;
						case "00001818-0000-1000-8000-00805f9b34fb":
							Services.Add("CyclingPower", service);
							break;
						case "00001816-0000-1000-8000-00805f9b34fb":
							Services.Add("CyclingSpeedAndCadence", service);
							break;
						case "0000180a-0000-1000-8000-00805f9b34fb":
							Services.Add("DeviceInformation", service);
							break;
						case "00001800-0000-1000-8000-00805f9b34fb":
							Services.Add("GenericAccess", service);
							break;
						case "00001801-0000-1000-8000-00805f9b34fb":
							Services.Add("GenericAttribute", service);
							break;
						case "00001808-0000-1000-8000-00805f9b34fb":
							Services.Add("Glucose", service);
							break;
						case "00001809-0000-1000-8000-00805f9b34fb":
							Services.Add("HealthThermometer", service);
							break;
						case "0000180d-0000-1000-8000-00805f9b34fb":
							Services.Add("HeartRate", service);
							break;
						case "00001812-0000-1000-8000-00805f9b34fb":
							Services.Add("HumanInterfaceDevice", service);
							break;
						case "00001802-0000-1000-8000-00805f9b34fb":
							Services.Add("ImmediateAlert", service);
							break;
						case "00001803-0000-1000-8000-00805f9b34fb":
							Services.Add("LinkLoss", service);
							break;
						case "00001819-0000-1000-8000-00805f9b34fb":
							Services.Add("LocationAndNavigation", service);
							break;
						case "00001807-0000-1000-8000-00805f9b34fb":
							Services.Add("NextDstChange", service);
							break;
						case "0000180e-0000-1000-8000-00805f9b34fb":
							Services.Add("PhoneAlertStatus", service);
							break;
						case "00001806-0000-1000-8000-00805f9b34fb":
							Services.Add("ReferenceTimeUpdate", service);
							break;
						case "00001814-0000-1000-8000-00805f9b34fb":
							Services.Add("RunningSpeedAndCadence", service);
							break;
						case "00001813-0000-1000-8000-00805f9b34fb":
							Services.Add("ScanParameters", service);
							break;
						case "00001804-0000-1000-8000-00805f9b34fb":
							Services.Add("TxPower", service);
							break;
						case "00001530-1212-efde-1523-785feabcd123":
							Services.Add(GATTServiceIdentification.DEVICE_FIRMWARE_UPDATE, service);
							break;
						//case "00001531-1212-efde-1523-785feabcd123":
						//	Services.Add("Packet", service);
						//	break;
						//case "00001532-1212-efde-1523-785feabcd123":
						//	Services.Add("ControlPoint", service);
						//	break;
						//case "00001534-1212-efde-1523-785feabcd123":
						//	Services.Add("DFUVersion", service);
						//	break;
						default:
							break;
					}

				}
			}
			catch (Exception e)
			{
				//Catch any exceptions and make alert to phone or user
			}
			if (LocalSettings.Values.ContainsKey(DeviceAddress))
			{
				string[] values = ((string)LocalSettings.Values[DeviceAddress]).Split(',');
				AlertOnPhone = bool.Parse(values[0]);
				AlertOnDevice = bool.Parse(values[1]);
				//alertLevel = (AlertLevel)Enum.Parse(typeof(AlertLevel), values[2]);
			}
			this.CompleteDeviceName = device.Name;
			this.DeviceID = device.DeviceId;
			this.ConnectionStatus = device.ConnectionStatus;
		}