[UWP][BLE][C#]How to identify last packet for large data in BLE Write and Notify in Win10

Angela Yan 1 Reputation point
2020-12-02T03:31:44.797+00:00

I have a Windows class library that uses UWP BLE APIs. The setup is:
BLE Host: Win 10 laptop
BLE peripheral: Win 10 laptop or Android

I need to send large file (a few K to a few M) to and from peripheral (using Write/WriteWithoutResponse and Notify) using custom Service and Characteristics.

For Win-Win, everything seems to be handled by OS. The host just call this once

writeResult = await characteristic.WriteValueAsync(buffer, GattWriteOption.WriteWithResponse);

with large data and OS seems will auto negotiate for the max MTU (517 bytes on Android) and split the data into smaller chunk and send out. However, on the receiving side,

 private async void Characteristic_WriteRequestedAsync(GattLocalCharacteristic sender, GattWriteRequestedEventArgs args)        {

            var deferral = args.GetDeferral();
            using (deferral)
            {
                GattWriteRequest request = await args.GetRequestAsync();
                if (request == null)
                {
                    Log(LOG_ERR, $"No access allowed to the device");
                    return;
                }
                var reader = DataReader.FromBuffer(request.Value);
                string mystring = reader.ReadString(request.Value.Length);
                Log(LOG_VERBOSE, $"Receiving data value length: {request.Value.Length}");
                Log(LOG_VERBOSE, $"Receiving data write offset: {request.Offset}");
                Log(LOG_VERBOSE, $"Receiving data write state: {request.State}");


                if (request.Option == GattWriteOption.WriteWithResponse)
                {
                    request.Respond();
                }
                deferral.Complete();
            }
        }

Receiver will have multiple callbacks but in each callback, it only has value, Offset and state info. How would the receiver know which packet is the last packet and it can start processing the data? I don't think checking value length < max PDU size is a good way. And Android and Windows peripheral seems to receive different size of data per packet. (Android 517, Windows 522)

Same for Notify on Win host, it basically has nothing that could tell whether this is the last packet of the whole message.

private void NotifyCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
  Log(LOG_VERBOSE, $"Receiving value length from Notify: {args.CharacteristicValue.Length}");
}

I though this is very basic requirement and should have implemented by Windows. Am I missing anything here? If there is no Windows native implementation, I need to implement my own mechanism. Using a terminator char at the end of the actual data? Any suggestion?

In addition, I am not sure if it is suitable to use 'reliable write' in this case. But this function seems to be available in C++ only and not in C#.

Thank you,
Angela

Universal Windows Platform (UWP)
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,364 questions
{count} votes