title: How do I correctly subscribe to a bluetooth low energy device's GattCharacteristic.ValueChanged notification (indication) in a Windows UWP App?
body: <p>On my Linux machine I have successfully subscribed to a <a href="https://timeular.com/" rel="nofollow noreferrer">Timeular/ZEI</a> Bluetooth LE Device using Java, the <a href="https://github.com/intel-iot-devkit/tinyb" rel="nofollow noreferrer">TinyB Library</a> and BlueZ.</p>
  
  <p>However I do need the same functionality for Windows 10 (1709). I am using the most recent Windows SDK with Visual Studio 2017.</p>
  
  <p>My goal is to subscribe to a <code>GattCharacteristic.ValueChanged</code> event, so whenever someone is "rolling the dice", the BTLE device will send a notification to the Windows App and call my <code>DiceOrientationChangeHandler</code>.</p>
  
  <p>What I got so far is:</p>
  
  <pre><code>    const string DEVICE_MAC_ADDRESS = "ee:ab:17:be:37:20"; //Timeular's MAC address
      const string BLUETOOTH_LE_SERVICE_UUID = "c7e70010-c847-11e6-8175-8c89a55d403c"; //the service which contains Timeular's orientation change characteristic
      const string BLUETOOTH_LE_CHARACTERISTIC_UUID = "c7e70012-c847-11e6-8175-8c89a55d403c"; //the characteristic that allows subscription to notification (indication) for orientation change
  
  
      public async void SubscribeToOrientationChangeNotification()
      {
          BluetoothLEDevice bluetoothLEDevice = null;
  
          //loop through bluetooth devices until we found our desired device by mac address
          DeviceInformationCollection deviceInformationCollection = await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector());
          foreach (var deviceInformation in deviceInformationCollection)
          {
              String deviceInformationId = deviceInformation.Id;
              String mac = deviceInformationId.Substring(deviceInformationId.Length - 17);
              if (mac.Equals(DEVICE_MAC_ADDRESS))
              {
                  bluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(deviceInformation.Id);
                  Debug.WriteLine($"Found Bluetooth LE Device [{mac}]: {bluetoothLEDevice.ConnectionStatus}");
                  break;
              }
          }
  
          //Subscribe to the connection status change event
          bluetoothLEDevice.ConnectionStatusChanged += ConnectionStatusChangeHandler;
  
          //get the desired service
          Guid serviceGuid = Guid.Parse(BLUETOOTH_LE_SERVICE_UUID);
          GattDeviceServicesResult serviceResult = await bluetoothLEDevice.GetGattServicesForUuidAsync(serviceGuid);
          if (serviceResult.Status == GattCommunicationStatus.Success)
          {
              GattDeviceService service = serviceResult.Services[0];
              Debug.WriteLine($"Service @ {service.Uuid}, found and accessed!");
  
              //get the desired characteristic
              Guid characteristicGuid = Guid.Parse(BLUETOOTH_LE_CHARACTERISTIC_UUID);
              GattCharacteristicsResult characteristicResult = await service.GetCharacteristicsForUuidAsync(characteristicGuid);
              if (characteristicResult.Status == GattCommunicationStatus.Success)
              {
                  GattCharacteristic characteristic = characteristicResult.Characteristics[0];
                  Debug.WriteLine($"Characteristic @ {characteristic.Uuid} found and accessed!");
  
                  //check access to the characteristic
                  Debug.Write("We have the following access to the characteristic: ");
                  GattCharacteristicProperties properties = characteristic.CharacteristicProperties;
                  foreach (GattCharacteristicProperties property in Enum.GetValues(typeof(GattCharacteristicProperties)))
                  {
                      if (properties.HasFlag(property))
                      {
                          Debug.Write($"{property} ");
                      }
                  }
                  Debug.WriteLine("");
  
                  //subscribe to the GATT characteristic's notification
                  GattCommunicationStatus status = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(
                      GattClientCharacteristicConfigurationDescriptorValue.Notify);
                  if (status == GattCommunicationStatus.Success)
                  {
                      Debug.WriteLine("Subscribing to the Indication/Notification");
                      characteristic.ValueChanged += DiceOrientationChangeHandler;
                  }
                  else
                  {
                      Debug.WriteLine($"ERR1: {status}");
                  }
              } else
              {
                  Debug.WriteLine($"ERR2: {characteristicResult.Status}");
              }
          } else
          {
              Debug.WriteLine($"ERR3: {serviceResult.Status}");
          }
  
      }
  
      public void DiceOrientationChangeHandler(GattCharacteristic sender, GattValueChangedEventArgs eventArgs)
      {
          Debug.WriteLine($"Dice rolled...");
      }
  
  
      public void ConnectionStatusChangeHandler(BluetoothLEDevice bluetoothLEDevice, Object o)
      {
          Debug.WriteLine($"The device is now: {bluetoothLEDevice.ConnectionStatus}");
      }
  </code></pre>
  
  <p>The output looks like:</p>
  
  <blockquote>
    <p>Found Bluetooth LE Device [ee:ab:17:be:37:20]: Connected</p>
    
    <p>Service @ c7e70010-c847-11e6-8175-8c89a55d403c, found and accessed!</p>
    
    <p>Characteristic @ c7e70012-c847-11e6-8175-8c89a55d403c found and
    accessed!</p>
    
    <p>We have the following access to the characteristic: None Read Indicate</p>
    
    <p>Subscribing to the Indication/Notification</p>
    
    <p>The device is now: Disconnected</p>
  </blockquote>
  
  <p>But whenever I change the device's orientation, nothing happens. The service uuid and characteristic uuid are the same that I am using in the Linux program, where the orientation change handler is working.</p>
  
  <p>After a short while, one last message will be printed to the console:</p>
  
  <blockquote>
    <p>The Thread 0x2b40 has exited with code 0 (0x0).</p>
  </blockquote>
  
  <p>What am I doing wrong subscribing to the Bluetooth LE device's notification?</p>