c# Bluetooth LE - ValueChanged never called - additional configuration necessary?

1

My question is kinda an update to my last question: c# Bluetooth LE - write configuration error - ValueChanged never called

The problem is, I connect my WPF c#-Application to my BLE device, but characteristic.ValueChanged is never called. Maybe I miss something with the configuration or need to send additionall configuration to the device, idk.

Here is the method connecting the application to the device:

private async Task ConnectToWatcher(DeviceInformation deviceInfo) {
    try {
        // get the device
        BluetoothLEDevice device = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);

        // get the GATT service
        Thread.Sleep(150);
        var gattServicesResult = await device.GetGattServicesForUuidAsync(new Guid(RX_SERVICE_UUID));
        service = gattServicesResult.Services[0];

        // get the GATT characteristic
        Thread.Sleep(150);
        var gattCharacteristicsResult = await service.GetCharacteristicsForUuidAsync(new Guid(RX_CHAR_UUID));
        characteristic = gattCharacteristicsResult.Characteristics[0];

        // register for notifications
        Thread.Sleep(150);

        characteristic.ValueChanged += (sender, args) => {
            Debug.WriteLine($"[{device.Name}] Received notification containing {args.CharacteristicValue.Length} bytes");
        };

        enableTXNotification();

    } catch (Exception ex) when ((uint)ex.HResult == 0x800710df) {
        Debug.WriteLine("bluetooth error 1");
        // ERROR_DEVICE_NOT_AVAILABLE because the Bluetooth radio is not on.
    }
}

And here's the method sending the configuration:

public async void enableTXNotification()
    {
        Debug.WriteLine("enableTXNotification");

        var gattCharacteristicsResult = await service.GetCharacteristicsForUuidAsync(new Guid(TX_CHAR_UUID));
        if (gattCharacteristicsResult == null
                || gattCharacteristicsResult.Status != GattCommunicationStatus.Success
                || gattCharacteristicsResult.Characteristics == null
                || gattCharacteristicsResult.Characteristics?.Count < 1)
        {
            Debug.WriteLine(" Failed to find GATT characteristic.");
            return;
        }
        txCharacteristic = gattCharacteristicsResult.Characteristics[0];

        txCharacteristic.ValueChanged += (sender, args) => {
            Debug.WriteLine("[{device.Name}] Received notification containing {args.CharacteristicValue.Length} bytes");
        };

        Debug.WriteLine(" Writing CCCD...");
        GattWriteResult result =
            await txCharacteristic.WriteClientCharacteristicConfigurationDescriptorWithResultAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
        Debug.WriteLine($" Characteristics write result: status={result.Status}, protocolError={result.ProtocolError}");
}

The last line creates the output status=success. Still no ValueChanged Method (I suspect the second one to be unnecassary) is being called when I use the device. I'm running out of ideas. Can someone help?

c#
wpf
bluetooth
bluetooth-lowenergy
asked on Stack Overflow Sep 12, 2017 by murkr

1 Answer

0

you should first verify that the CharacteristicConfigurationDescriptor is "Notify", if not you should set it to notify and then define the ValueChanged listener. try to change "ConnectToWatcher" with the following code:

private async Task ConnectToWatcher(DeviceInformation deviceInfo) {
try {
    // get the device
    BluetoothLEDevice device = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);

    // get the GATT service
    Thread.Sleep(150);
    var gattServicesResult = await device.GetGattServicesForUuidAsync(new Guid(RX_SERVICE_UUID));
    service = gattServicesResult.Services[0];

    // get the GATT characteristic
    Thread.Sleep(150);
    var gattCharacteristicsResult = await service.GetCharacteristicsForUuidAsync(new Guid(RX_CHAR_UUID));
    characteristic = gattCharacteristicsResult.Characteristics[0];

    // check Characteristic Configuration Descriptor
    var currentDescriptorValue = await characteristic.ReadClientCharacteristicConfigurationDescriptorAsync();

    if (currentDescriptorValue.ClientCharacteristicConfigurationDescriptor != GattClientCharacteristicConfigurationDescriptorValue.Notify)
    {
         var status = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
    }

    // register for notifications
    Thread.Sleep(150);

    characteristic.ValueChanged += (sender, args) => {
        Debug.WriteLine($"[{device.Name}] Received notification containing {args.CharacteristicValue.Length} bytes");
    };

    enableTXNotification();

} catch (Exception ex) when ((uint)ex.HResult == 0x800710df) {
    Debug.WriteLine("bluetooth error 1");
    // ERROR_DEVICE_NOT_AVAILABLE because the Bluetooth radio is not on.
}

}

hope it helped

answered on Stack Overflow Sep 12, 2017 by Michael Gabbay

User contributions licensed under CC BY-SA 3.0