繁体   English   中英

如何在Windows UWP App中正确订阅蓝牙低能耗设备的GattCharacteristic.ValueChanged通知(指示)?

[英]How do I correctly subscribe to a bluetooth low energy device's GattCharacteristic.ValueChanged notification (indication) in a Windows UWP App?

在我的Linux机器上,我已经使用Java, TinyB库和BlueZ成功订阅了Timeular / ZEI蓝牙LE设备。

但是我确实需要Windows 10(1709)的相同功能。 我在Visual Studio 2017中使用最新的Windows SDK。

我的目标是订阅GattCharacteristic.ValueChanged事件,因此无论何时有人“掷骰子”,BTLE设备都会向Windows应用程序发送通知并调用我的DiceOrientationChangeHandler

到目前为止,我得到的是:

    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}");
    }

输出如下:

找到了蓝牙LE设备[ee:ab:17:be:37:20]:已连接

找到并访问了服务@ c7e70010-c847-11e6-8175-8c89a55d403c!

找到并访问了@ c7e70012-c847-11e6-8175-8c89a55d403c特征!

我们可以通过以下方式访问该特征:无阅读指示

订阅指示/通知

设备现已:断开连接

但是,每当我更改设备的方向时,都不会发生任何事情。 服务uuid​​和特征uuid与我在Linux程序中使用的相同,方向更改处理程序正在其中工作。

片刻之后,最后一条消息将被打印到控制台:

线程0x2b40已退出,代码为0(0x0)。

订阅Bluetooth LE设备的通知时我做错了什么?

我终于找到了问题:

使用linux库,它将以某种方式自动确定GATT服务正在使用哪种通知类型。

使用Windows SDK,我必须通过使用GattClientCharacteristicConfigurationDescriptorValue.Indicate明确指定通知的类型是一种指示。

现在,一旦我“掷骰子”,便会触发该事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM