private async void Disconnect()
        {
            if (_disconnecting)
            {
                return;
            }
            _connectedDevice = null;
            _disconnecting   = true;
            await this.UnregisterAllValueChangeEvents();

            if (_service != null)
            {
                // bugbug: if we call _service.Dispose below then the app will get System.ObjectDisposedException'
                // next time it tries to reconnect to the device because the Windows BLE stack gives us back the
                // disposed object next time we call GattDeviceService.FromIdAsync and there is no workaround
                // besides this.  The downside to this is that the phone will not "disconnect" from the BLE
                // device.  Not even after the app is closed.
                //try
                //{
                //    _service.Dispose();
                //}
                //catch { }

                Debug.WriteLine("_service disconnected: " + this.GetType().Name);
                _service = null;
            }
            _disconnecting = false;
            _connected     = false;

            if (DisconnectFinished != null)
            {
                DisconnectFinished(this, EventArgs.Empty);
            }
        }
        private SensorTag(BleGattDeviceInfo deviceInfo)
        {
            this.deviceInfo = deviceInfo;
            this.version    = 1;
            string name = deviceInfo.DeviceInformation.Name;

            Debug.WriteLine("Found sensor tag: [{0}]", name);
            if (name == "CC2650 SensorTag" || name == "SensorTag 2.0")
            {
                this.version    = 2;
                this.deviceName = "CC2650";
            }
            else
            {
                this.deviceName = "CC2541";
            }
        }
        /// <summary>
        /// Initialize the new service
        /// </summary>
        /// <param name="serviceGuid">One of GattServiceUuids</param>
        /// <param name="deviceContainerId">The device you are interested in or null if you want any device </param>
        /// <param name="radioAddress">Optional radio address to match</param>
        /// <returns></returns>
        protected async Task <bool> ConnectAsync(Guid serviceGuid, string deviceContainerId, long radioAddress = -1)
        {
            _disconnecting = false;

            this._requestedServiceGuid = serviceGuid;

            _connectedDevice = null;

            var devices = await FindMatchingDevices(serviceGuid);

            if (!devices.Any())
            {
                _connected = false;
                OnError("no devices found, try using bluetooth settings to pair your device");
                return(false);
            }

            BleGattDeviceInfo matchingDevice = null;

            foreach (var device in devices)
            {
                string id = device.ContainerId;
                if (deviceContainerId == null || string.Compare(id, deviceContainerId, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (radioAddress == -1 || device.Address == (ulong)radioAddress)
                    {
                        DeviceContainerId = id;
                        matchingDevice    = device;
                        break;
                    }
                }
            }

            if (matchingDevice == null)
            {
                _connected = false;
                OnError("requested device not found");
                return(false);
            }

            DeviceName = matchingDevice.DeviceInformation.Name;

            _service = await GattDeviceService.FromIdAsync(matchingDevice.DeviceInformation.Id);

            if (_service == null)
            {
                _connected = false;
                throw new Exception("Service not available, is another app still running that is using the service?");
            }

            _connected       = true;
            _connectedDevice = matchingDevice;

            // don't wait on this, async is fine.
            var nowait = RegisterForConnectionEvents();

            OnConnectionChanged(_connected);

            // in case the event handlers were added before Connect().
            ReregisterAllValueChangeEvents();

            if (_service != null)
            {
                Debug.WriteLine("Service connected: " + this.GetType().Name);
            }
            return(true);
        }