Skip to content

BleGattCallbackTimeoutException when writing a characteristic with different data payload many times in a short period of time. #855

@dquand91

Description

@dquand91

Describe the bug

I have a BLE device with several characteristics and all of them are working.

But when I try to write 1 characteristic many times with different data payload in a short period of time (for 10 request in 5 seconds) by using com.polidea.rxandroidble2:rxandroidble:1.18.1 library on Android, it leads to BleGattCallbackTimeoutException and then automatically disconnect bluetooth with device. But I have an IOS application connects to the same BLE device, it still works as expected in the same scenario.

To Reproduce
Steps to reproduce the behavior:

  1. Application on Android connects to BLE device.
  2. Write 1 characteristic many times by method "rxBleConnection.createNewLongWriteBuilder()". Please refer to source code below:
Disposable writeDisposable = connectionObservable.flatMap(rxBleConnection ->
  rxBleConnection.createNewLongWriteBuilder()
    .setCharacteristicUuid(UUID.fromString(characteristic))
    .setBytes(data)
    .setMaxBatchSize(MAX_PACKET_LENGTH)
    .build())
  .doOnError(throwable ->
  {
      throwable.printStackTrace();
  })
  .subscribe(bytes -> onWriteSuccess(characteristic, bytes), this::onWriteFailure);

Expected behavior

  • It should not disconnect the bluetooth
  • Do we have any workaround solution or tips in case of writing 1 characteristic many times in a short period of time?

Smartphone (please complete the following information):

  • Device: Samsung S23, S23 Ultra
  • OS: Android 13
  • Library version: 1.18.1

Logs from the application when bug occurs (this will greatly help in quick understanding the problem)
To turn on logs use:

57:53.574 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(91963927)
57:53.577 26010-32587 RxBle#ConnectionOperationQueue  D  STARTED  CharacteristicLongWriteOperation(91963927)

57:53.577 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(163186669)
57:53.580 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(132638899)
57:53.582 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(205922926)
57:53.590 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(49439132)
57:55.708 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(154431849)
57:58.596 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(35002628)
57:58.598 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(109101346)
57:58.600 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(241025392)
57:58.604 26010-26010 RxBle#ConnectionOperationQueue  D  QUEUED   CharacteristicLongWriteOperation(126733678)

// After about 30007 mili-seconds, it leads to timeout exception.
58:23.583 26010-26763 BLEManager                      E  write long error: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.585 26010-32587 RxBle#ConnectionOperationQueue  D  FINISHED CharacteristicLongWriteOperation(91963927) in 30007 ms
58:23.586 26010-26763 System.err                      W  com.polidea.rxandroidble2.exceptions.BleGattCallbackTimeoutException: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.586 26010-26763 System.err                      W  	at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation.protectedRun(CharacteristicLongWriteOperation.java:87)
58:23.587 26010-26763 System.err                      W  	at com.polidea.rxandroidble2.internal.QueueOperation$1.subscribe(QueueOperation.java:41)
58:23.587 26010-26763 System.err                      W  	at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
58:23.587 26010-26763 System.err                      W  	at io.reactivex.Observable.subscribe(Observable.java:12284)
58:23.587 26010-26763 System.err                      W  	at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn.subscribeActual(ObservableUnsubscribeOn.java:32)
58:23.587 26010-26763 System.err                      W  	at io.reactivex.Observable.subscribe(Observable.java:12284)
58:23.587 26010-26763 System.err                      W  	at com.polidea.rxandroidble2.internal.serialization.FIFORunnableEntry$1.run(FIFORunnableEntry.java:56)
58:23.587 26010-26763 System.err                      W  	at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
58:23.587 26010-26763 System.err                      W  	at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
58:23.587 26010-26763 System.err                      W  	at java.util.concurrent.FutureTask.run(FutureTask.java:264)
58:23.587 26010-26763 System.err                      W  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
58:23.588 26010-26763 System.err                      W  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
58:23.588 26010-32587 RxBle#ConnectionOperationQueue  D  STARTED  CharacteristicLongWriteOperation(163186669)
58:23.588 26010-26763 System.err                      W  	at java.lang.Thread.run(Thread.java:1012)
58:23.588 26010-26763 BLEManager                      E  BLECharacteristic write failed: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.588 26010-32587 RxBle#ConnectionOperationQueue  I  RUNNING  CharacteristicLongWriteOperation{MAC='XX:XX:XX:XX:XX:XX', characteristic=[uuid='...'], maxBatchSize=20}
58:23.589 26010-26763 System.err                      W  com.polidea.rxandroidble2.exceptions.BleGattCallbackTimeoutException: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.589 26010-26763 System.err                      W  	at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation.protectedRun(CharacteristicLongWriteOperation.java:87)
58:23.589 26010-26763 System.err                      W  	at com.polidea.rxandroidble2.internal.QueueOperation$1.subscribe(QueueOperation.java:41)
58:23.589 26010-26763 System.err                      W  	at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
58:23.590 26010-26763 System.err                      W  	at io.reactivex.Observable.subscribe(Observable.java:12284)
58:23.590 26010-26763 System.err                      W  	at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn.subscribeActual(ObservableUnsubscribeOn.java:32)
58:23.590 26010-26763 System.err                      W  	at io.reactivex.Observable.subscribe(Observable.java:12284)
58:23.590 26010-26763 System.err                      W  	at com.polidea.rxandroidble2.internal.serialization.FIFORunnableEntry$1.run(FIFORunnableEntry.java:56)
58:23.590 26010-26763 System.err                      W  	at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
58:23.590 26010-26517 RxBle#Characte...riteOperation  D  Writing batch #0000: [...]
58:23.590 26010-26763 System.err                      W  	at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
58:23.590 26010-26763 System.err                      W  	at java.util.concurrent.FutureTask.run(FutureTask.java:264)
58:23.590 26010-26763 System.err                      W  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
58:23.590 26010-26763 System.err                      W  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
58:23.590 26010-26763 System.err                      W  	at java.lang.Thread.run(Thread.java:1012)
58:23.592 26010-26517 BLEManager                      E  write long error: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.592 26010-32587 RxBle#ConnectionOperationQueue  D  FINISHED CharacteristicLongWriteOperation(163186669) in 6 ms
58:23.594 26010-32587 RxBle#ConnectionOperationQueue  D  STARTED  CharacteristicLongWriteOperation(132638899)
58:23.594 26010-26517 System.err                      W  com.polidea.rxandroidble2.exceptions.BleGattCannotStartException: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.594 26010-26517 System.err                      W  	at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation.writeData(CharacteristicLongWriteOperation.java:190)
58:23.594 26010-26517 System.err                      W  	at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation$3.subscribe(CharacteristicLongWriteOperation.java:165)
58:23.594 26010-26517 System.err                      W  	at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
58:23.594 26010-26517 System.err                      W  	at io.reactivex.Observable.subscribe(Observable.java:12284)
58:23.594 26010-26517 System.err                      W  	at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
58:23.594 26010-26517 System.err                      W  	at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
58:23.594 26010-26517 System.err                      W  	at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
58:23.595 26010-26517 System.err                      W  	at java.util.concurrent.FutureTask.run(FutureTask.java:264)
58:23.595 26010-26517 System.err                      W  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
58:23.595 26010-32587 RxBle#ConnectionOperationQueue  I  RUNNING  CharacteristicLongWriteOperation{MAC='XX:XX:XX:XX:XX:XX', characteristic=[uuid='...'], maxBatchSize=20}
58:23.595 26010-26517 System.err                      W  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
58:23.595 26010-26517 System.err                      W  	at java.lang.Thread.run(Thread.java:1012)
58:23.595 26010-26517 BLEManager                      E  BLECharacteristic write failed: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.596 26010-26517 System.err                      W  com.polidea.rxandroidble2.exceptions.BleGattCannotStartException: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.596 26010-26517 System.err                      W  	at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation.writeData(CharacteristicLongWriteOperation.java:190)
58:23.596 26010-26517 System.err                      W  	at com.polidea.rxandroidble2.internal.operations.CharacteristicLongWriteOperation$3.subscribe(CharacteristicLongWriteOperation.java:165)
58:23.596 26010-26517 System.err                      W  	at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
58:23.596 26010-26517 System.err                      W  	at io.reactivex.Observable.subscribe(Observable.java:12284)
58:23.596 26010-26517 System.err                      W  	at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
58:23.596 26010-26517 System.err                      W  	at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:38)
58:23.596 26010-26517 System.err                      W  	at io.reactivex.internal.schedulers.ScheduledDirectTask.call(ScheduledDirectTask.java:26)
58:23.596 26010-26517 System.err                      W  	at java.util.concurrent.FutureTask.run(FutureTask.java:264)
58:23.596 26010-26517 System.err                      W  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
58:23.596 26010-26517 System.err                      W  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
58:23.596 26010-26517 System.err                      W  	at java.lang.Thread.run(Thread.java:1012)
58:23.597 26010-26517 RxBle#Characte...riteOperation  D  Writing batch #0000: [...]
58:23.598 26010-26517 BLEManager                      E  write long error: GATT exception from MAC address XX:XX:XX:XX:XX:XX, with type BleGattOperation{description='CHARACTERISTIC_LONG_WRITE'}
58:23.598 26010-32587 RxBle#ConnectionOperationQueue  D  FINISHED CharacteristicLongWriteOperation(132638899) in 6 ms



// After a lot of exceptions, the Bluetooth is disconnected.
58:23.662 26010-26789 RxBle#GattCallback              I  MAC='XX:XX:XX:XX:XX:XX'    onCharacteristicWrite(), status=133, value=[uuid='...']
58:23.662 26010-26789 BluetoothGatt                   D  onClientConnectionState() - status=22 clientIf=6 device=XX:XX:XX:XX:XX:XX
58:23.669 26010-26789 RxBle#GattCallback              I  MAC='XX:XX:XX:XX:XX:XX'  onConnectionStateChange(), status=22, value=0
58:23.671 26010-26789 RxBle#ConnectionOperationQueue  D  Connection operations queue to be terminated (MAC='XX:XX:XX:XX:XX:XX')
                                                                       com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 22 (GATT_CONN_TERMINATE_LOCAL_HOST)
                                                                       	at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:85)
                                                                       	at android.bluetooth.BluetoothGatt$1$4.run(BluetoothGatt.java:381)
                                                                       	at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:1068)
                                                                       	at android.bluetooth.BluetoothGatt.-$$Nest$mrunOrQueueCallback(Unknown Source:0)
                                                                       	at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:376)
                                                                       	at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:226)
                                                                       	at android.os.Binder.execTransactInternal(Binder.java:1380)
                                                                       	at android.os.Binder.execTransact(Binder.java:1311)
58:23.672 26010-32587 RxBle#ConnectionOperationQueue  V  Terminated (MAC='XX:XX:XX:XX:XX:XX')
58:23.672 26010-26789 RxBle#ClientOperationQueue      D  QUEUED   DisconnectOperation(23872671)
58:23.673 26010-26762 BLEManager                      E  notification error: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 22 (GATT_CONN_TERMINATE_LOCAL_HOST)
58:23.673 26010-26147 RxBle#ClientOperationQueue      D  STARTED  DisconnectOperation(23872671)
58:23.673 26010-26789 BluetoothGatt                   D  setCharacteristicNotification() - uuid: 2738cac5-a508-82b7-8c48-4356f52c4720 enable: false
58:23.673 26010-26147 RxBle#ClientOperationQueue      I  RUNNING  DisconnectOperation{MAC='XX:XX:XX:XX:XX:XX'}
58:23.674 26010-26762 System.err                      W  com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 22 (GATT_CONN_TERMINATE_LOCAL_HOST)
58:23.674 26010-26762 System.err                      W  	at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onConnectionStateChange(RxBleGattCallback.java:85)
58:23.674 26010-26762 System.err                      W  	at android.bluetooth.BluetoothGatt$1$4.run(BluetoothGatt.java:381)
58:23.674 26010-26762 System.err                      W  	at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:1068)
58:23.674 26010-26762 System.err                      W  	at android.bluetooth.BluetoothGatt.-$$Nest$mrunOrQueueCallback(Unknown Source:0)
58:23.674 26010-26762 System.err                      W  	at android.bluetooth.BluetoothGatt$1.onClientConnectionState(BluetoothGatt.java:376)
58:23.674 26010-26762 System.err                      W  	at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:226)
58:23.674 26010-26762 System.err                      W  	at android.os.Binder.execTransactInternal(Binder.java:1380)
58:23.674 26010-26762 System.err                      W  	at android.os.Binder.execTransact(Binder.java:1311)

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    awaiting feedbackbug-model specificBug that is caused by a flawed, model specific BLE stack implementation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions