none
WriteWithoutResponse WriteRequested event raised out of order on GattLocalCharacteristic Windows.Devices.Bluetooth UWP RRS feed

  • Question

  • With a BLE GattLocalService on Windows.Devices.Bluetooth while acting as the Peripheral with a characteristic with only a WriteWithoutResponse property and Plain protection level we are seeing GattLocalCharacteristic event WriteRequested is raised out of order as compared to the bytes being sent. We must only use the WriteWithoutResponse property on the characteristic and cannot use Notify, which seems to work fine. The trouble comes that we are sending around 10K over BLE with an MTU of 20 through this characteristic and need to reassemble them in order once all bytes are received. While many of the functions are asynchronous we can't seem to determine the order in which the bytes were originally sent. When this is setup on either Android or iOS natively this it works perfectly fine but on the UWP implementation for Windows 10 we are notified out of order. Understandably, UWP is using several Async functions - but not being able to reassemble the bytes in the order received is quite problematic - and would seem to mean there would be issues with rapidly writing to any characteristic.

    While researching Microsoft's github examples they only show receiving about 4 bytes on a single characteristic - order here wouldn't really matter. We have looked at using the Offset property on the GattWriteRequest, which appears to always be 0. We have monitored the calls to the GattLocalCharacteristic and determined they are notified out of order.

    We've attempted to adapt from Microsoft's UWP GATT-Server Write example. Our VB.net adaptation of this prior example:

    Private Async Sub InitializePerihperal()
        Dim serviceResult As GattServiceProviderResult = Await GattServiceProvider.CreateAsync(New Guid(peripheralServiceUUID))
        If serviceResult.Error <> BluetoothError.Success Then
            peripheralResponseReceived = True
            peripheralResponseError = "GattServiceError"
            Exit Sub
        End If
    
        serviceProvider = serviceResult.ServiceProvider
    
        Dim characResult As GattLocalCharacteristicResult
        Dim propCentralToPeripheral As New GattLocalCharacteristicParameters
        propCentralToPeripheral.CharacteristicProperties = GattCharacteristicProperties.WriteWithoutResponse
        propCentralToPeripheral.WriteProtectionLevel = GattProtectionLevel.Plain
        characResult = Await serviceProvider.Service.CreateCharacteristicAsync(New Guid(CentralToPeripheralUUID), propCentralToPeripheral)
        characCentralToPeripheral = characResult.Characteristic
    End Sub
    Private Async Sub CentralResponseReceived(sender As GattLocalCharacteristic, args As GattWriteRequestedEventArgs) Handles characCentralToPeripheral.WriteRequested
        Dim sequence As Int32 = Threading.Interlocked.Increment(PerihperalWriteSequence)
        Using requestDeferral As Windows.Foundation.Deferral = args.GetDeferral
            Dim request As GattWriteRequest = Await args.GetRequestAsync
            Dim requestReader As DataReader = DataReader.FromBuffer(request.Value)
            Dim response(CType(requestReader.UnconsumedBufferLength - 1, Int32)) As Byte
            requestReader.ReadBytes(response)
            'peripheralBlocks is a global ConcurrentDictionary
            peripheralBlocks(sequence) = response
            requestDeferral.Complete()
        End Using
    End Sub

    We might be missing something, but it seems like the function should be called in sequence. Above we have attempted to eliminate issues with GetRequestAsync delays by immediately capturing a call sequence. Maybe we are just missing something on the API to force these to come in sequentially - but we can't seem to find anything.
    Saturday, June 22, 2019 9:18 PM

All replies

  • Hi,

    I'm asking the team about this issue. There might be some time delay. Thank you for your patience.

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 24, 2019 7:27 AM
    Moderator
  • Roy,

    Has anyone had the opportunity to look into this?

    After re-structuring the code it appears that we might be reliably getting the values in the correct order, however none of the changes should have modified the behavior. We are more careful to properly remove all references to characteristics between creating new services and stopping advertising on the GattServiceProvider which appears to have made a difference. Ultimately, we are not incredibly comfortable without a root cause to the issue - but don't have anyway to identify what it might have been.

    However, as soon as I created this post and re-tested the scenario the issue popped up again, though was fine on the next attempt. Additionally it is worth noting that the speed at which the data transfer happens is quite erratic and unpredictable on the Windows side - Android and iOS are providing a much more consistent behavior.

    Thanks


    • Edited by OutOfTownerJD Sunday, July 14, 2019 3:09 AM re-test failed.
    Sunday, July 14, 2019 3:01 AM