On my Linux machine I have successfully subscribed to a Timeular/ZEI Bluetooth LE Device using Java, the TinyB Library and BlueZ.
However I do need the same functionality for Windows 10 (1709). I am using the most recent Windows SDK with Visual Studio 2017.
My goal is to subscribe to a GattCharacteristic.ValueChanged
event, so whenever someone is "rolling the dice", the BTLE device will send a notification to the Windows App and call my DiceOrientationChangeHandler
.
What I got so far is:
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}");
}
The output looks like:
Found Bluetooth LE Device [ee:ab:17:be:37:20]: Connected
Service @ c7e70010-c847-11e6-8175-8c89a55d403c, found and accessed!
Characteristic @ c7e70012-c847-11e6-8175-8c89a55d403c found and accessed!
We have the following access to the characteristic: None Read Indicate
Subscribing to the Indication/Notification
The device is now: Disconnected
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.
After a short while, one last message will be printed to the console:
The Thread 0x2b40 has exited with code 0 (0x0).
What am I doing wrong subscribing to the Bluetooth LE device's notification?
I finally found the issue:
Using the linux library, it somehow automatically determined what type of notification the GATT Service is using.
Using the Windows SDK I had to explicitly specify that the type of notification is an indication by using GattClientCharacteristicConfigurationDescriptorValue.Indicate
.
Now the event is fired once I "roll the dice".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.