Saturday, 20 April 2019

How to write large amount of text to write characteristic

I am writing an Android application with Xamarin.Android, but an answer in native Android would be appreciated as well. In my Android application, I have a BLE Write Characteristic that devices can write to. It works, but I can't send more than 20 bytes, the rest gets cut off. My code to create and add the service/characteristic:

BluetoothGattService service = new BluetoothGattService(Java.Util.UUID.FromString(MyServiceUuid), GattServiceType.Primary);

// write characteristic (write-only, supports subscriptions)
BluetoothGattCharacteristic writeCharacteristic = new BluetoothGattCharacteristic(Java.Util.UUID.FromString(MyCharacteristicUuid), GattProperty.WriteNoResponse | GattProperty.Notify, GattPermission.Write);

service.AddCharacteristic(writeCharacteristic);

_bluetoothGattServer.AddService(service);

My code for on the side that writes to the characteristic:

public override void OnServicesDiscovered(BluetoothGatt gatt, [GeneratedEnum] GattStatus status)
{
    base.OnServicesDiscovered(gatt, status);

    characteristic = gatt.GetService(Java.Util.UUID.FromString(MyServiceUuid))
                         .GetCharacteristic(Java.Util.UUID.FromString(MyCharacteristicUuid));

    if(characteristic.Properties.HasFlag(GattProperty.WriteNoResponse))
    {
        Log?.Invoke("writing characteristic...");

        characteristic.SetValue(MyVeryLongString);
        characteristic.WriteType = GattWriteType.NoResponse;
        gatt.WriteCharacteristic(characteristic);
    }
}

And on the side that accepts the write request:

public override void OnCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, bool preparedWrite, bool responseNeeded, int offset, byte[] value)
{
    base.OnCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);

    Log?.Invoke("OnCharacteristicWriteRequest");

    string data = System.Text.Encoding.UTF8.GetString(value);

    Log?.Invoke(data);

    if(responseNeeded)
    {
        BluetoothGattServer.SendResponse(device, requestId, GattStatus.Success, 0, Encoding.ASCII.GetBytes("ok"));
    }
}

I see there is an offset, but this function only gets called once. I must be missing something on one side?

The funny thing is, that when I test this Android application with the iOS version of my application, I do not have this issue. I only have this issue when both devices are Androids.



from How to write large amount of text to write characteristic

No comments:

Post a Comment