androidbluetoothandroid-bluetoothandroid-ble-library

BluetoothGattCharacteristic > write crashes with Android 13


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 :(


Solution

  • 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()