none
How do I use the WinRT BLE API to handle characteristic writes > 20 bytes? RRS feed

  • Question

  • I am attempting to write a C++ app that uses the WinRT Bluetooth LE APIs (the Windows.Devices.Bluetooth namespace).

    The app is a Windows Classic Desktop application that communicates with a BLE device using the Nordic UART service. The following code works fine if I send 20 bytes or less:

    // Set the RX characteristic property to notify.

    ...

    // Read RX characteristic when notified. rxc.ValueChanged([](GattCharacteristic const& characteristic, GattValueChangedEventArgs const& args) { std::vector<uint8_t> bytes; bytes.resize(args.CharacteristicValue().Length()); DataReader::FromBuffer(args.CharacteristicValue()).ReadBytes(bytes); // Bytes received are pushed into a threadsafe FIFO.... ); // Write data array to TX characterisitic. Datawriter = DataWriter(); writer.WriteBytes(data); auto status = co_await txc.WriteValueWithResultAsync(writer.DetachBuffer(), GattWriteOption::WriteWithoutResponse);

    Problem comes if I try to write more than 20 bytes - no data comes back.

    I've tried chunking the data into 20 bytes packets and sending it, and this works, but not all the time. It gets stuck every now and again. So simple question:

    How do I use the WinRT BLE API to handle characteristic writes > 20 bytes (in my case)?

    Any pointers would be appreciated.




    • Edited by Ev1lC Thursday, November 7, 2019 11:35 AM
    Thursday, November 7, 2019 11:32 AM

Answers

  • Sadly not acceptable solution for customer.

    As a workaround I'm going to modify the protocol to send packets < 20 bytes so there's no need to split them. I like WinRT, it's just the complete lack of detailed documentation around the BlueoothLE APIs. I know nobody reads anything anymore, but sometimes you can't dumb down this stuff.

    • Marked as answer by Ev1lC Monday, November 11, 2019 9:24 AM
    Monday, November 11, 2019 9:24 AM

All replies

  • Can you clarify? Do you send from the Nordic UART connected BLE and receive on a built-in bluetooth on the same PC, using the Windows API? 

    If so, is your Windows Bluetooth controller capable of large MTUs? Can you try another newer controller (on USB) instead of the built-in one?

    -- pa

    Thursday, November 7, 2019 1:28 PM
  • Thanks for replying.

    I send from a (new) USB Bluetooth dongle on my PC to the external BLE device which implements the Nordic UART service. The device has a max MTU of 20. I was under the impression Windows auto negotiates this size as part of the connection process?

    My question is - should my app split the data into chunks or will Windows do it for me and if so, do I have any control over the MTU if Windows gets it wrong?


    • Edited by Ev1lC Friday, November 8, 2019 9:11 AM
    Thursday, November 7, 2019 2:12 PM
  • TL;DR for any non-trivial BLE project, my recommendation is to bypass the Windows stack entirely.

    Use an external BLE module from Nordic or Silicon labs or others. The API will be proprietary, but easy to understand and this will work with any Windows version/update, no matter what BLE quirks they fix or introduce. 
    And this will work without bizarre WinRT, or C++ at all.

    -- pa



    • Edited by Pavel A Sunday, November 10, 2019 3:21 AM
    Sunday, November 10, 2019 3:00 AM
  • Sadly not acceptable solution for customer.

    As a workaround I'm going to modify the protocol to send packets < 20 bytes so there's no need to split them. I like WinRT, it's just the complete lack of detailed documentation around the BlueoothLE APIs. I know nobody reads anything anymore, but sometimes you can't dumb down this stuff.

    • Marked as answer by Ev1lC Monday, November 11, 2019 9:24 AM
    Monday, November 11, 2019 9:24 AM