2

I have the following code that is working perfectly on Android 12 and below, but that is crashing on Android 13 for no apparent reason.

I'm implementing ObservableBleManager and calling:

        writeCharacteristic(characteristic, data)
                .done {
                    // emit success
                }
                .fail { _, _ ->
                    // emit error
                }
                .enqueue()

but it's crashing like this:

2022-09-13 11:30:54.265 23853-23853/com V/Android-BLE-Library: Writing characteristic <custom characteristic> (WRITE REQUEST)
2022-09-13 11:30:54.265 23853-23853/com D/Android-BLE-Library: gatt.writeCharacteristic(<custom characteristic>)
2022-09-13 11:30:55.003 23853-23867/com D/BluetoothAdapter: onBluetoothServiceDown
2022-09-13 11:30:55.007 23853-23869/com D/BluetoothAdapter: onBluetoothServiceDown
2022-09-13 11:30:55.013 23853-23853/com D/Android-BLE-Library: [Broadcast] Action received: android.bluetooth.adapter.action.STATE_CHANGED, state changed to TURNING OFF
2022-09-13 11:30:55.013 23853-23853/com I/Android-BLE-Library: Disconnected
2022-09-13 11:30:55.035 23853-23853/com D/Android-BLE-Library: gatt.close()
2022-09-13 11:30:55.035 23853-23853/com D/BluetoothGatt: close()
2022-09-13 11:30:55.035 23853-23853/com D/BluetoothGatt: unregisterApp() - mClientIf=6
2022-09-13 11:30:55.036 23853-23853/com E/BluetoothGatt: android.os.DeadObjectException
        at android.os.BinderProxy.transactNative(Native Method)
        at android.os.BinderProxy.transact(BinderProxy.java:584)
        at android.bluetooth.IBluetoothGatt$Stub$Proxy.unregisterClient(IBluetoothGatt.java:1506)
        at android.bluetooth.BluetoothGatt.unregisterApp(BluetoothGatt.java:941)
        at android.bluetooth.BluetoothGatt.close(BluetoothGatt.java:799)
        at no.nordicsemi.android.ble.BleManagerHandler.close(BleManagerHandler.java:422)
        at no.nordicsemi.android.ble.BleManagerHandler.notifyDeviceDisconnected(BleManagerHandler.java:1520)

Please note that the read instead is working fine. We found out that there is a crash with this error message:

A/libc: FORTIFY: memcpy: prevented 546-byte write into 513-byte buffer

Seems that the payload is too big. However I can't understand why on Android 13 is so tiny and on Android 12 and below is working :(

Filnik
  • 352
  • 1
  • 12
  • 33
  • If the Bluetooth service is crashing when you write a characteristic, it's a bug in the Bluetooth stack which you should report to the phone manufacturer. – Emil Sep 19 '22 at 23:05
  • We found out that the reason why is crashing is that the payload is over 513 bytes and the buffer is of 513 instead. However, using split stuff doesn't work. I don't know why on Android 13 we have this issue :( – Filnik Sep 20 '22 at 20:26
  • Are you sure this message is related to the crash? How big value are you trying to write? – Emil Sep 21 '22 at 19:32
  • Yes, because sending a smaller message does work. The message is quite big indeed because there are some user data. The issue is that we cannot make it smaller since it's data inserted by the user and the length can vary. However until Android 12 everything just worked perfectly :( – Filnik Sep 22 '22 at 08:16
  • 1
    It's still a bug if it crashes. You should report the issue to the manufacturer. – Emil Sep 22 '22 at 11:13

1 Answers1

1

Until Android 12, we are allowing long writes over 512 bytes, but in Android 13 (Android’s new Gabeldorsche Bluetooth stack) it's limited for some reason. Either way, it doesn't seem like something that can be fixed in this library.

This works for me:

 val writeType = if (VERSION.SDK_INT >= 33) BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE else BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
 val writeData = writeCharacteristic(rxCharacteristic, payload, writeType)

 writeData.with(rxCallback)

 if (VERSION.SDK_INT >= 33) writeData.split()
K. Donon
  • 254
  • 2
  • 13
  • I forgot to update, but unfortunately yes you're right :) I said unfortunately because changing the protocol on the host is a massive pain and cost for us – Filnik Oct 18 '22 at 12:36
  • @K. Donon So if Android SDK is greater than 33, we are waiting for response? and in the last line we have split the response? Shouldn't we split, before writing the data? Sorry I am not an Android native dev, a Flutter developer trying to fix BLE Provisoning issue. – sakina Feb 16 '23 at 04:11
  • 1
    @sakina yes you should split the write not the read. Also I would suggest to do it also with Android 12. It must be said that the chuncked read should be available in the client. For example, we were communicating with an external device and we had to update it's software to make it able to received chunked write. – Filnik Feb 17 '23 at 22:24