I am trying to read all the records stored in a glucometer using rxAndroidBle library. According to several resources that I have found the process consist of three main steps after pairing/bonding and connecting to the device:
- Setup indications in the Record Access Control Point characteristic (RACP)
- Setup notifications on the Glucose measurement characteristic
- Write on the RACP characteristic two bytes 0x01, 0x01.
Then the notifications should flow if there are any records.
Now, this flow has worked fine some times in an LG G5 with android 7.0, but on other phones that I have access to it just won't work. It will throw a gruesome GATT_INTERNAL_ERROR (status 129), which is kind of ambiguous. I found this article which describes kind of what I may be facing.
My concern is that this works but it may be firmware related, which is weird because I've seen it work flawlessly on other application that connects to the glucometer without issue in any device.
Here's what how my test code for this seems like right now:
fun loadRecords(rxBleDevice: RxBleDevice){
...
...
rxBleDevice.establishConnection(false)
.flatMap { rxBleConnection: RxBleConnection ->
rxBleConnection.setupIndication(racpUUID)
.flatMapSingle {
Single.just(rxBleConnection)
}
}
.flatMap { rxBleConnection ->
writeAndReadOnNotification(racpUUID,
glucoseUUID,
byteArrayOf(0x01, 0x01),
false,
rxBleConnection)
}
.subscribe(
{ it:ByteArray ->
decodeReading(it)
},Logger::logException)
}
private fun writeAndReadOnNotification(writeTo: UUID, readOn: UUID,
bytes: ByteArray,
isIndication: Boolean,
rxBleConnection:RxBleConnection)
: Observable<ByteArray> {
val notifObservable = if (isIndication)
rxBleConnection.setupIndication(readOn)
else
rxBleConnection.setupNotification(readOn)
return notifObservable.flatMap { notificationObservable ->
Observable.combineLatest(
notificationObservable,
rxBleConnection.writeCharacteristic(writeTo, bytes).toObservable(),
BiFunction { readBytes: ByteArray, writeBytes: ByteArray -> readBytes })
}
}
and here's what the log looks like for that piece of code:
18:28:58.058 D/BluetoothGatt: connect() - device: E0:7D:EA:FF:38:AB, auto: false
18:28:58.058 D/BluetoothGatt: registerApp()
18:28:58.058 D/BluetoothGatt: registerApp() - UUID=cca42db0-a88f-4b1c-acd0-f7fbe7be536d
18:28:58.065 D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
18:28:58.518 D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=7 device=E0:7D:EA:FF:38:AB
18:28:58.527 D/BluetoothGatt: discoverServices() - device: E0:7D:EA:FF:38:AB
18:28:58.532 D/BluetoothGatt: onSearchComplete() = Device=E0:7D:EA:FF:38:AB Status=0
18:28:58.873 D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a52-0000-1000-8000-00805f9b34fb enable: true
18:28:58.965 D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a18-0000-1000-8000-00805f9b34fb enable: true
18:28:59.057 D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a18-0000-1000-8000-00805f9b34fb enable: false
18:28:59.061 D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a52-0000-1000-8000-00805f9b34fb enable: false
18:28:59.066 E/None: com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException: GATT exception from MAC='XX:XX:XX:XX:XX:XX', status 129 (GATT_INTERNAL_ERROR), type BleGattOperation{description='CHARACTERISTIC_WRITE'}. (Look up status 0x81 here https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-5.1.0_r1/stack/include/gatt_api.h)
at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback.propagateErrorIfOccurred(RxBleGattCallback.java:243)
at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback.access$800(RxBleGattCallback.java:35)
at com.polidea.rxandroidble2.internal.connection.RxBleGattCallback$2.onCharacteristicWrite(RxBleGattCallback.java:125)
at android.bluetooth.BluetoothGatt$1$7.run(BluetoothGatt.java:438)
at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:770)
at android.bluetooth.BluetoothGatt.access$200(BluetoothGatt.java:39)
at android.bluetooth.BluetoothGatt$1.onCharacteristicWrite(BluetoothGatt.java:433)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:137)
at android.os.Binder.execTransact(Binder.java:731)
18:28:59.067 D/BluetoothManager: getConnectionState()
18:28:59.067 D/BluetoothManager: getConnectedDevices
18:28:59.074 D/BluetoothGatt: cancelOpen() - device: E0:7D:EA:FF:38:AB
18:28:59.080 D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=7 device=E0:7D:EA:FF:38:AB
18:28:59.083 D/BluetoothGatt: close()
18:28:59.084 D/BluetoothGatt: unregisterApp() - mClientIf=7
18:28:59.507 V/FA: Inactivity, disconnecting from the service
Did I missed something in my code? Why does it work on some phones?