Skip to content
This repository has been archived by the owner on Aug 30, 2022. It is now read-only.

Is it possible to set the connection priority or the connection interval value? #94

Closed
virgil85 opened this issue Dec 2, 2020 · 10 comments
Assignees
Milestone

Comments

@virgil85
Copy link

virgil85 commented Dec 2, 2020

Is it possible to tweak connection settings like the interval value?
I saw that normally that is done using
boolean requestConnectionPriority (int connectionPriority)
which I cannot get to work with able.
Even better would be to set the connection time intervals to specific values.
The nRF app does log
Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
when performing such connection parameter changes.

If this is possible, can you provide any code snipped on how to do that?

@twyatt
Copy link
Member

twyatt commented Dec 2, 2020

I'll try to find some time soon to expose that API.


Out of curiosity, do you simply want the connection to always have the desired priority, or do you sometimes need to adjust it while connected?

Asking to determine the best way to integrate the same functionality in Kable (which will soon supersede Able).

@twyatt twyatt self-assigned this Dec 2, 2020
@twyatt twyatt added this to the 0.8.1 milestone Dec 2, 2020
@virgil85
Copy link
Author

virgil85 commented Dec 2, 2020

Thanks 👍

I guess it would suffice to always have the desired priority.

@twyatt
Copy link
Member

twyatt commented Dec 4, 2020

@virgil85 from what I can tell, there isn't a BluetoothGattCallback function to monitor when the connection priority request has completed, so I presume it must be a fire-and-forget style call?

I've add a function that passes through the request, but did not test it.

If you could, give it a try and let me know if it works for you.

repositories {
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}

dependencies {
    implementation("com.juul.able:core:0.8.1-SNAPSHOT")
}

After you're connected you should be able to call:

gatt.requestConnectionPriority(Priority.Low) // or Priority.Balanced, or Priority.High

Thanks!

@virgil85
Copy link
Author

virgil85 commented Dec 7, 2020

First of all thank you for the quick update. I did test it and it works properly. At least the connection priority part.

In my setup I connect to a GPS module which is sending me position updates with 10Hz frequency (via notify).
When I don't increase the MTU and use the default MTU the data I get is split into multiple data segments (which is normal).
And when I set the connection priority flag I don't seem to miss any data, at least when I look at the logs from the able library.

But when I collect the data using the onCharacteristicChanged I often get duplicate data instead of the data that seems to be available when I look at the able logs in verbose mode. This may be due to the preview version of the Kotlin Flow and the error does not occur when I increase the MTU - but perhaps this may be an interesting bug - perhaps really related to the FlowPreview and not the able library but I'm not sure - might be a delay or race condition thing.

But thank you again for integrating the connection priority flag.

@twyatt
Copy link
Member

twyatt commented Dec 8, 2020

But when I collect the data using the onCharacteristicChanged I often get duplicate data instead of the data that seems to be available when I look at the able logs in verbose mode.

What version of Android are you trying this on?

This may be due to the preview version of the Kotlin Flow

Despite Flow being marked experimental, it should be reliable and unfortunately (for me) the bug is more likely in Able than Flow. 😄

the error does not occur when I increase the MTU

This is interesting, can you provide a snippet of some of your logs, might help me understand the problem a little better.

@virgil85
Copy link
Author

virgil85 commented Dec 10, 2020

Sorry for the delay.

I did test it on Android 9 (Huawei Mate 20X 5G) and on Android 10 (Huawei P20). On Android 9 the error seems to occur a bit more frequent than on Android 10 - but maybe I just had more luck on the Android 10 device 😄

Logs
2020-12-10 14:29:19.387 4898-4898/com.test.testpositioningevaluation E/BLE helper:  discover services successful
2020-12-10 14:29:19.387 4898-4898/com.test.testpositioningevaluation E/BLE helper: Gatt services: [android.bluetooth.BluetoothGattService@a38e88a, android.bluetooth.BluetoothGattService@5d13efb, android.bluetooth.BluetoothGattService@c6a7b18]
2020-12-10 14:29:19.387 4898-4898/com.test.testpositioningevaluation E/BLE helper try:  got service android.bluetooth.BluetoothGattService@c6a7b18
2020-12-10 14:29:19.387 4898-4898/com.test.testpositioningevaluation E/BLE helper try: Got characteristic: android.bluetooth.BluetoothGattCharacteristic@767e971
2020-12-10 14:29:19.388 4898-4898/com.test.testpositioningevaluation I/Able: setCharacteristicNotification → uuid=15555555-5555-5555-5555-555555550001, enable=true
2020-12-10 14:29:19.388 4898-4898/com.test.testpositioningevaluation E/BLE notify: enabled
2020-12-10 14:29:19.389 4898-4898/com.test.testpositioningevaluation E/BLE Descriptors: descriptors : [android.bluetooth.BluetoothGattDescriptor@ec50356, android.bluetooth.BluetoothGattDescriptor@b6acfd7]
2020-12-10 14:29:19.389 4898-4898/com.test.testpositioningevaluation V/Able: writeDescriptor → withContext ThreadPoolDispatcher[1, Gatt@B8:27:EB:7D:21:04]
2020-12-10 14:29:19.392 4898-4898/com.test.testpositioningevaluation V/Able: writeDescriptor ← Waiting for BluetoothGattCallback
2020-12-10 14:29:19.419 4898-4966/com.test.testpositioningevaluation V/Able: ← OnDescriptorWrite(uuid=00002902-0000-1000-8000-00805f9b34fb, status=GATT_SUCCESS(0))
2020-12-10 14:29:19.421 4898-4898/com.test.testpositioningevaluation I/Able: writeDescriptor ← OnDescriptorWrite(uuid=00002902-0000-1000-8000-00805f9b34fb, status=GATT_SUCCESS(0))
2020-12-10 14:29:19.421 4898-4898/com.test.testpositioningevaluation E/BLE Descriptors: updated descriptor
2020-12-10 14:29:19.621 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@f1830c4(size=20))
2020-12-10 14:29:19.623 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:19.623 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@7c0abad(size=20))
2020-12-10 14:29:19.623 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:19.624 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@625fee2(size=20))
2020-12-10 14:29:19.626 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:19.626 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@6a29273(size=20))
2020-12-10 14:29:19.626 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:19.627 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@3c99530(size=20))
2020-12-10 14:29:19.628 4898-4898/com.test.testpositioningevaluation E/Partial position message: 022,"head":57.05819,
2020-12-10 14:29:19.629 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@b6955a9(size=20))
2020-12-10 14:29:19.629 4898-4898/com.test.testpositioningevaluation E/Partial position message: "hAcc":0.015,"vAcc":
2020-12-10 14:29:19.629 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@da9272e(size=20))
2020-12-10 14:29:19.631 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@689e2cf(size=20))
2020-12-10 14:29:19.631 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:19.631 4898-4898/com.test.testpositioningevaluation E/Partial position message: diffM":"DGNSS-fixed"
2020-12-10 14:29:19.632 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@6ead45c(size=20))
2020-12-10 14:29:19.632 4898-4898/com.test.testpositioningevaluation E/Partial position message: diffM":"DGNSS-fixed"
2020-12-10 14:29:19.633 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@9d8a365(size=2))
2020-12-10 14:29:19.634 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:19.635 4898-4898/com.test.testpositioningevaluation E/currentJSON: was just not working
2020-12-10 14:29:19.817 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@824883a(size=20))
2020-12-10 14:29:19.819 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@febdceb(size=20))
2020-12-10 14:29:19.819 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:19.819 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:19.820 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@d7eda48(size=20))
2020-12-10 14:29:19.821 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@13510e1(size=20))
2020-12-10 14:29:19.822 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:19.822 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:19.822 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@dc2ee06(size=20))
2020-12-10 14:29:19.823 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@f295cc7(size=20))
2020-12-10 14:29:19.824 4898-4898/com.test.testpositioningevaluation E/Partial position message: "hAcc":0.015,"vAcc":
2020-12-10 14:29:19.824 4898-4898/com.test.testpositioningevaluation E/Partial position message: 0.022,"sAcc":0.067,"
2020-12-10 14:29:19.824 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@7cb52f4(size=20))
2020-12-10 14:29:19.825 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@190da1d(size=20))
2020-12-10 14:29:19.825 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:19.825 4898-4898/com.test.testpositioningevaluation E/Partial position message: diffM":"DGNSS-fixed"
2020-12-10 14:29:19.825 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@c8fe492(size=20))
2020-12-10 14:29:19.826 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@bd4fe63(size=2))
2020-12-10 14:29:19.827 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:19.827 4898-4898/com.test.testpositioningevaluation E/currentJSON: was just not working
2020-12-10 14:29:19.827 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:19.827 4898-4898/com.test.testpositioningevaluation E/currentJSON: was just not working
2020-12-10 14:29:20.020 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@2c4aa60(size=20))
2020-12-10 14:29:20.021 4898-4898/com.test.testpositioningevaluation E/Partial position message: {"utc":1606342753800
2020-12-10 14:29:20.022 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@fe5fb19(size=20))
2020-12-10 14:29:20.022 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:20.023 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@5c3b7de(size=20))
2020-12-10 14:29:20.023 4898-4898/com.test.testpositioningevaluation E/Partial position message: on":13.5799071,"hMSL
2020-12-10 14:29:20.024 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@a0f1dbf(size=20))
2020-12-10 14:29:20.024 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:20.024 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@43a0c8c(size=20))
2020-12-10 14:29:20.025 4898-4898/com.test.testpositioningevaluation E/Partial position message: 022,"head":57.05819,
2020-12-10 14:29:20.025 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@cd22fd5(size=20))
2020-12-10 14:29:20.026 4898-4898/com.test.testpositioningevaluation E/Partial position message: "hAcc":0.015,"vAcc":
2020-12-10 14:29:20.026 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@3cf73ea(size=20))
2020-12-10 14:29:20.026 4898-4898/com.test.testpositioningevaluation E/Partial position message: 0.022,"sAcc":0.067,"
2020-12-10 14:29:20.026 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@5a1d6db(size=20))
2020-12-10 14:29:20.027 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:20.027 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@dc16578(size=20))
2020-12-10 14:29:20.027 4898-4898/com.test.testpositioningevaluation E/Partial position message: diffM":"DGNSS-fixed"
2020-12-10 14:29:20.028 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@b12f451(size=2))
2020-12-10 14:29:20.029 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:20.031 4898-4898/com.test.testpositioningevaluation E/currentJSON: {"utc":1606342753800,"lat":48.8867201,"lon":13.5799071,"hMSL":909.055,"speed":0.022,"head":57.05819,"hAcc":0.015,"vAcc":0.022,"sAcc":0.067,"headAcc":135.14376,"diffM":"DGNSS-fixed"}
2020-12-10 14:29:20.036 4898-4898/com.test.testpositioningevaluation W/oningevaluatio: Accessing hidden field Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe; (light greylist, reflection)
2020-12-10 14:29:20.218 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@1c1848d(size=20))
2020-12-10 14:29:20.220 4898-4898/com.test.testpositioningevaluation E/Partial position message: {"utc":1606342754000
2020-12-10 14:29:20.221 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@7d69642(size=20))
2020-12-10 14:29:20.223 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:20.224 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@1324653(size=20))
2020-12-10 14:29:20.225 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@b076b90(size=20))
2020-12-10 14:29:20.225 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:20.225 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:20.226 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@64edc89(size=20))
2020-12-10 14:29:20.227 4898-4898/com.test.testpositioningevaluation E/Partial position message: 022,"head":57.05819,
2020-12-10 14:29:20.227 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@1bbd48e(size=20))
2020-12-10 14:29:20.228 4898-4898/com.test.testpositioningevaluation E/Partial position message: "hAcc":0.015,"vAcc":
2020-12-10 14:29:20.229 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@b90f4af(size=20))
2020-12-10 14:29:20.230 4898-4898/com.test.testpositioningevaluation E/Partial position message: 0.022,"sAcc":0.067,"
2020-12-10 14:29:20.231 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@59fb0bc(size=20))
2020-12-10 14:29:20.232 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:20.232 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@a3fb845(size=20))
2020-12-10 14:29:20.233 4898-4898/com.test.testpositioningevaluation E/Partial position message: diffM":"DGNSS-fixed"
2020-12-10 14:29:20.234 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@1a4ab9a(size=2))
2020-12-10 14:29:20.235 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:20.236 4898-4898/com.test.testpositioningevaluation E/currentJSON: was just not working
2020-12-10 14:29:20.418 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@2822ccb(size=20))
2020-12-10 14:29:20.419 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@b151ca8(size=20))
2020-12-10 14:29:20.420 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:20.420 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:20.430 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@8a893c1(size=20))
2020-12-10 14:29:20.430 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@511e766(size=20))
2020-12-10 14:29:20.431 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:20.431 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@c04caa7(size=20))
2020-12-10 14:29:20.431 4898-4898/com.test.testpositioningevaluation E/Partial position message: 022,"head":57.05819,
2020-12-10 14:29:20.431 4898-4898/com.test.testpositioningevaluation E/Partial position message: 022,"head":57.05819,
2020-12-10 14:29:20.431 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@7f35b54(size=20))
2020-12-10 14:29:20.431 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@f69aafd(size=20))
2020-12-10 14:29:20.432 4898-4898/com.test.testpositioningevaluation E/Partial position message: 0.022,"sAcc":0.067,"
2020-12-10 14:29:20.432 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:20.432 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@ec513f2(size=20))
2020-12-10 14:29:20.432 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:20.432 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@5296a43(size=20))
2020-12-10 14:29:20.433 4898-4898/com.test.testpositioningevaluation E/Partial position message: diffM":"DGNSS-fixed"
2020-12-10 14:29:20.467 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@3d4d8c0(size=2))
2020-12-10 14:29:20.468 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:20.469 4898-4898/com.test.testpositioningevaluation E/currentJSON: was just not working
2020-12-10 14:29:20.618 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@2af9f9(size=20))
2020-12-10 14:29:20.620 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@a0c7d3e(size=20))
2020-12-10 14:29:20.620 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:20.621 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:20.621 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@16e679f(size=20))
2020-12-10 14:29:20.622 4898-4898/com.test.testpositioningevaluation E/Partial position message: on":13.5799071,"hMSL
2020-12-10 14:29:20.623 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@38ec0ec(size=20))
2020-12-10 14:29:20.624 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:20.625 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@5183cb5(size=20))
2020-12-10 14:29:20.625 4898-4898/com.test.testpositioningevaluation E/Partial position message: 022,"head":57.05819,
2020-12-10 14:29:20.626 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@6cf2f4a(size=20))
2020-12-10 14:29:20.627 4898-4898/com.test.testpositioningevaluation E/Partial position message: "hAcc":0.015,"vAcc":
2020-12-10 14:29:20.627 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@3dbdebb(size=20))
2020-12-10 14:29:20.628 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@21cffd8(size=20))
2020-12-10 14:29:20.628 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:20.628 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:20.629 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@55cef31(size=20))
2020-12-10 14:29:20.629 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:20.630 4898-4943/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@a58f616(size=2))
2020-12-10 14:29:20.630 4898-4898/com.test.testpositioningevaluation E/currentJSON: was just not working
2020-12-10 14:29:20.630 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:20.630 4898-4898/com.test.testpositioningevaluation E/currentJSON: was just not working
2020-12-10 14:29:20.818 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@ddfab97(size=20))
2020-12-10 14:29:20.820 4898-4898/com.test.testpositioningevaluation E/Partial position message: {"utc":1606342754600
2020-12-10 14:29:20.820 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@c4e4184(size=20))
2020-12-10 14:29:20.821 4898-4898/com.test.testpositioningevaluation E/Partial position message: ,"lat":48.8867201,"l
2020-12-10 14:29:20.822 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@5604d6d(size=20))
2020-12-10 14:29:20.823 4898-4898/com.test.testpositioningevaluation E/Partial position message: on":13.5799071,"hMSL
2020-12-10 14:29:20.824 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@e65da2(size=20))
2020-12-10 14:29:20.824 4898-4898/com.test.testpositioningevaluation E/Partial position message: ":909.055,"speed":0.
2020-12-10 14:29:20.825 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@fe96a33(size=20))
2020-12-10 14:29:20.825 4898-4898/com.test.testpositioningevaluation E/Partial position message: 022,"head":57.05819,
2020-12-10 14:29:20.826 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@b2ff1f0(size=20))
2020-12-10 14:29:20.827 4898-4898/com.test.testpositioningevaluation E/Partial position message: "hAcc":0.015,"vAcc":
2020-12-10 14:29:20.827 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@ec15369(size=20))
2020-12-10 14:29:20.828 4898-4898/com.test.testpositioningevaluation E/Partial position message: 0.022,"sAcc":0.067,"
2020-12-10 14:29:20.829 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@bf0b1ee(size=20))
2020-12-10 14:29:20.829 4898-4898/com.test.testpositioningevaluation E/Partial position message: headAcc":135.14376,"
2020-12-10 14:29:20.830 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@7c6768f(size=20))
2020-12-10 14:29:20.831 4898-4898/com.test.testpositioningevaluation E/Partial position message: diffM":"DGNSS-fixed"
2020-12-10 14:29:20.831 4898-4966/com.test.testpositioningevaluation V/Able: ← OnCharacteristicChanged(uuid=15555555-5555-5555-5555-555555550001, value=[B@93a3d1c(size=2))
2020-12-10 14:29:20.832 4898-4898/com.test.testpositioningevaluation E/Partial position message: }
2020-12-10 14:29:20.835 4898-4898/com.test.testpositioningevaluation E/currentJSON: {"utc":1606342754600,"lat":48.8867201,"lon":13.5799071,"hMSL":909.055,"speed":0.022,"head":57.05819,"hAcc":0.015,"vAcc":0.022,"sAcc":0.067,"headAcc":135.14376,"diffM":"DGNSS-fixed"}

I switched to Verbose mode before creating the log so the able logs as well as my logs are present.
Every partial characteristic I receive is labeled "Partial position message". I concatenate all those messages until I receive a delimiter "\n" which tells me that I now got the complete position message. Then I try to parse the message with gson and either I get a result which is labled "currentJSON" with json content or the result is not a valid JSON (due to duplicate messages) where the result is "was just not working".

I also attached a simplified version of my onCharacteristicChanged.collect.

gatt.onCharacteristicChanged.collect { data ->
    val tmpPos = data.characteristic.getStringValue(0)
    Log.e("Partial position message", tmpPos)

    // add tmpPos to position string
	
    // check position string when delimiter \n was found
    try {
        val currentJSON = JSONObject(posStr)
        Log.e("currentJSON", "$currentJSON")                    
    }
    catch (e: Exception){
        Log.e("currentJSON", "was just not working")
    }
    // reset position string
}

I also did not increase the MTU beforehand - so it's the default value.

@twyatt
Copy link
Member

twyatt commented Dec 10, 2020

Thanks for all the details!

Can you change the first line of your onCharacteristicChanged.collect to:

val tmpPos = data.value.toString(Charsets.UTF_8)

...and let me know if that resolves your issue, please?

@virgil85
Copy link
Author

Wow - that really resolved the problem 😄

Perhaps you just add an example to your documentation detailing the onCharacteristicChanged.collect (and maybe also the other Flow function onConnectionStatusChanged). To avoid that anybody else does the same error as I did.

Thank you for solving this issue 😃

@twyatt
Copy link
Member

twyatt commented Dec 15, 2020

Thanks for confirming the fix @virgil85.

Quick explanation of why it fixed your issue (if you're curious):

The problem is that Android re-uses characteristic objects, so accessing data from a characteristic object directly is not thread-safe, as Android may be updating the characteristic data under your feet.

Able quickly copies the ByteArray reference of the characteristic data when it gets a characteristic notification, so later when you ultimately get the onCharacteristicChanged event through your Flow, then you have a copied reference to the ByteArray data (via the value property I suggested) — the reference on the characteristic may change but you'll get the correct value ByteArray.

The fact that onCharacteristicChanged Flow provides the characteristic associated with the change is definitely a footgun.

Kable, which will be superseding Able soon (#91), only provides the changed data (not the characteristic), so should eliminate accidental misuse of the API. Kable doesn't yet have support for connection priority, but it's on the roadmap (JuulLabs/kable#36).

@twyatt twyatt closed this as completed Dec 15, 2020
@twyatt
Copy link
Member

twyatt commented Dec 15, 2020

@virgil85 Able 0.8.1 has been released which includes the connection priority support. Exactly the same as the SNAPSHOT version you tried, but is now versioned. Definitely give Kable a try when you have a chance, since it will be replacing Able soon. 😄

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants