How to respond to Bluetooth LE characteristic read request in UWP application

1

I am trying to follow the examples here for creating an UWP application that will act as a Bluetooth LE peripheral: https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/gatt-server but when trying to respond to the characteristic read request with request.RespondWithValue I get an exception: System.Exception: 'The object has been committed. (Exception from HRESULT: 0x8000001E)'

If I set a static value for the characteristic, the value is read correctly

 ReadParameters.StaticValue = (new byte[] { 0x21 }).AsBuffer();

I have tried the code both on a Windows 10 PC and Windows 10 IoT Core and get the same exception.

Is there anything else that is needed for responding to the read request?

public sealed partial class MainPage : Page
{
    GattLocalCharacteristic _readCharacteristic;
    GattServiceProvider _serviceProvider;
    public MainPage()
    {
        this.InitializeComponent();
        SetupBle();
    }
    public async Task<bool> SetupBle()
    {
        GattServiceProviderResult result = await GattServiceProvider.CreateAsync(GattServiceUuids.Battery);
        if (result.Error == BluetoothError.Success)
        {
            _serviceProvider = result.ServiceProvider;
            var ReadParameters = new GattLocalCharacteristicParameters();
            ReadParameters.CharacteristicProperties = GattCharacteristicProperties.Read;
            ReadParameters.UserDescription = "Battery service";
            //ReadParameters.StaticValue = (new byte[] { 0x21 }).AsBuffer(); //if this is uncommented the static battery level value is read correctly
            GattLocalCharacteristicResult characteristicResult = await _serviceProvider.Service.CreateCharacteristicAsync(GattCharacteristicUuids.BatteryLevel, 
                ReadParameters);
            if (characteristicResult.Error != BluetoothError.Success)
            {
                return false;
            }
            _readCharacteristic = characteristicResult.Characteristic;
            _readCharacteristic.ReadRequested += _readCharacteristic_ReadRequested;
            GattServiceProviderAdvertisingParameters advParameters = new GattServiceProviderAdvertisingParameters
            {
                IsDiscoverable = true,
                IsConnectable = true
            };
            _serviceProvider.StartAdvertising(advParameters);
            return true;
        }
        return false;
    }
    private async void _readCharacteristic_ReadRequested(GattLocalCharacteristic sender, GattReadRequestedEventArgs args)
    {
        var writer = new DataWriter();
        writer.WriteByte(0x21);
        var request = await args.GetRequestAsync();
        request.RespondWithValue(writer.DetachBuffer());//will throw System.Exception: 'The object has been committed. (Exception from HRESULT: 0x8000001E)'
    }
}
uwp
bluetooth-lowenergy
asked on Stack Overflow May 4, 2017 by jobencol

1 Answer

1

According to the comment here https://blogs.msdn.microsoft.com/btblog/2017/05/11/welcome-to-the-new-windows-bluetooth-core-team-blog/#comment-105 and the comments here https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/gatt-server the documentation was outdated and incorrect.

This code works for me:

    private async void _readCharacteristic_ReadRequested(GattLocalCharacteristic sender, GattReadRequestedEventArgs args)
    {
        var deferral = args.GetDeferral();
        var writer = new DataWriter();
        writer.WriteByte(0x21);
        var request = await args.GetRequestAsync();
        request.RespondWithValue(writer.DetachBuffer());
        deferral.Complete();
    }
answered on Stack Overflow May 19, 2017 by jobencol

User contributions licensed under CC BY-SA 3.0