Open graphefruit opened 1 year ago
Update: I just digged some more. When restarting my Android device, and trying to autoConnect on the pressure device, its not connection at all. But when I ble.startScanWithOptions, and search the id and after that connect, it works.
When I disable the code again, and don't restart my phone, the auto connect is working again aswell (still with the mentioned delay above)
Hi @graphefruit
Quite a lot of things going on there!
So... firstly, I can say confidently the plugin will give you all the bits you need to achieve this... but there'll be a bit of work to get there 🙂
- On iOS I have the "issue" that I need to startScan and wait until i've found all device-ids I've stored, before I can ble.autoconnect to them.
Is this because you don't know the device id (guid)? Or because the guid doesn't successfully connect if you just call connect directly? The scanning should not be needed if the phone has previously seen the device, and the mac address is unchanged (or the phone has bonded with the device).
One thing to note is that you can safely scan while connecting to a Bluetooth device. In a similar app I've worked on, I basically run the scan after app launch until I've found all devices, but I immediately connect and process each device as it's found. It's pretty power efficient overall, and no major down sides.
- On Android the connection to the pressure-sensor takes about 5-6 seconds, which means ble.autoConnect fires the "success"-method. Whats really strange is that on iOS the connection is about 0-1 second - so much much faster.
This is a known effect of using autoConnect
on android. It runs much lower power, and takes longer to connect. If you need a faster connect, you'll need to use ble.connect
instead. Having said that, iOS is always much faster to connect than Android in my experience.
2.1. Also I've encountered when I stored the device id, and I autoConnect to the pressure device it sometimes never connects, and I need to disconnect (forget the id), restart the app and start searching again.
Does the mac address of the device remain constant? Some devices use a private randomised mac address for privacy/security reasons. Does the device id remain constant between scans too, or does it change?
2.2 Also I've encountered, when I search the device, connect to it on Android, disconnect and connect again, the device sometimes is not found anymore. (Funny that on iOS this works like without no issues)
Are you scanning between disconnect or connect? Sometimes Android itself will hold the connection open without telling the app. This is especially common when the device is bonded. If you call connect
, that should always work as long as no other phone is connected to the device.
To help debugging, I'd highly recommend getting nrf Connect on a second Android phone so you can confirm the device you're trying to connect to is actually broadcasting. I've experienced issues in the past where a BLE device does not properly resume broadcasting... and I've also had issues where other phones in my room were fighting to connect to the device and I had forgotten about it 😅 .
On Android I also scanWithOptions
legacy: false
is default... Depending on how long the app is running, aggressive scanning can cause your app to be throttled or marked as high battery usage. Just something to be aware of!
Hello @peitschie ,
thank you for this enormous & fast feedback!
Let me try to get into detail:
Is this because you don't know the device id (guid)? Or because the guid doesn't successfully connect if you just call connect directly? The scanning should not be needed if the phone has previously seen the device, and the mac address is unchanged (or the phone has bonded with the device).
The ble.connect
or ble.autoConnect
on iOS don't work when I didn't scan the devices before and they got found.
Thats specifically needed when I start/restart the app, once its connected, the search was already done and the connecting is working, because like you wrote the device has been seen.
And what I stated in my second post, this is needed on my Pixel 2 XL aswell, without searching, it can't connect to the pressure-device but funny enough to the scale it works without the search for it.
One thing to note is that you can safely scan while connecting to a Bluetooth device. In a similar app I've worked on, I basically run the scan after app launch until I've found all devices, but I immediately connect and process each device as it's found. It's pretty power efficient overall, and no major down sides.
Thats awesome to know! I gonna rewrite my code to this changes, because it takes me some awaits less, and less ui-blockings in the end.
This is a known effect of using autoConnect on android. It runs much lower power, and takes longer to connect. If you need a faster connect, you'll need to use ble.connect instead. Having said that, iOS is always much faster to connect than Android in my experience.
Thats strange because autoConnect
and connect
are identically fast on my side when it comes to connecting to a scale e.g..
The pressure device took nearly the same time aswell.
What I don't understand here, why the Bluetooth-Scale connect is about 1 second on Android, and the Pressure-Device is about 5 second on Android - same logic?
Even when I don't connect the bluetooth scale and just want to connect the pressure device its taking this time.
Also the question: does the connect
has a specific timeout, when it doesn't find any device?
Because maybe it'd look like that when the connect
function triggers the disconnect/timeout event I'd go and try to connect again so.
In my mind it would look like this:
function connectDevice() {
ble.connect(xyz, () => {
//Success
}, () => {
//Disconnect triggered, reconnect again
this.connectDevice();
}
}
If this would work that easy, I think I'll go test with the .connect
solution and see if its faster, and rewrite the code passages to it.
Does the mac address of the device remain constant? Some devices use a private randomised mac address for privacy/security reasons. Does the device id remain constant between scans too, or does it change?
The device id remains (gladly) the same, thats why I can store it in the indexDB/localstorage.
Are you scanning between disconnect or connect? Sometimes Android itself will hold the connection open without telling the app. This is especially common when the device is bonded. If you call connect, that should always work as long as no other phone is connected to the device.
I just implemented yesterday, when disconnect, I search for the device again, before triggering the connect - just to make sure.
I don't bond the devices, after these devices would not offer a popup with a code e.g.
To help debugging, I'd highly recommend getting nrf Connect on a second Android phone so you can confirm the device you're trying to connect to is actually broadcasting. I've experienced issues in the past where a BLE device does not properly resume broadcasting... and I've also had issues where other phones in my room were fighting to connect to the device and I had forgotten about it 😅 .
Thanks for the tip! Gonna test it out after I've changed all my codes like mentioned above
legacy: false is default... Depending on how long the app is running, aggressive scanning can cause your app to be throttled or marked as high battery usage. Just something to be aware of!
Oh thank you! Thats very good to know, I just did it for testing purpose to diminish everything, but its better to remove it so again!
Thanks again for your help in this case Best Lars
The ble.connect or ble.autoConnect on iOS don't work when I didn't scan the devices before and they got found. Thats specifically needed when I start/restart the app, once its connected, the search was already done and the connecting is working, because like you wrote the device has been seen. And what I stated in my second post, this is needed on my Pixel 2 XL aswell, without searching, it can't connect to the pressure-device but funny enough to the scale it works without the search for it.
Interesting. On Android it's a bit inconsistent between manufacturers and versions (some manufacturers require you to scan before you can connect). For iOS, have you looked at turning on the BLUETOOTH_RESTORE_STATE
flag in this plugin? You theoretically don't need the background scanning behaviours. Putting the restore state value on means the app remembers the associations with an ID, and might allow you to skip the scan.
Having said that, for my own uses, I pretty much always scan then connect when working with unbonded devices 🙂
What I don't understand here, why the Bluetooth-Scale connect is about 1 second on Android, and the Pressure-Device is about 5 second on Android - same logic?
Basically, there's a lot of variables that can be tuned by the peripheral, including things like advertising intervals, max/min connection intervals, etc. Because it's an unbonded device, BLE service discovery must be performed on every connect, which is a fairly expensive operation to perform. Large variations between peripheral classes is fairly normal (though worth talking to the peripheral manufacturer about if you notice a discrepancy between iOS and Android).
Also the question: does the connect has a specific timeout, when it doesn't find any device?
This is manufacturer-dependent on Android, and infinite on iOS.
If this would work that easy, I think I'll go test with the .connect solution and see if its faster, and rewrite the code passages to it.
Worth trying this! You'll also need to subscribe to adapter state changes, because disabling the Bluetooth adapter may not always fire the onPeripheralDisconnected
callback there.
I just implemented yesterday, when disconnect, I search for the device again, before triggering the connect - just to make sure.
Worth being aware that if Android has the connection still open behind your back, you won't see the device in a scan. I usually call connect
for a know peripheral, and then launch a scan that runs until the peripheral connects once. It's finicky... but unfortunately there's no easy way around it in Android land.
Hey @peitschie, thanks for all the great input again!
I've basically fixed many things with your input here.
One issue I've encountered and I could reproduce now over again is:
When I restart my Android-Phone, and i call ble.connect()
the pressure-device does NOT get connect in the first round, after the disconnect
-calllback is triggered, and I run ble.connect()
again, the device gets connected.
Again, thats just with the pressure device, which runs with a simple 2032 battery, not any aa/aaa onces.
I've tried it with the original app, there the connection is established without any problems, and nearly instant. (This app is written in flutter).
I've tried a workaround to go with the first iteration, set a timeout for 10 seconds, and after 10 seconds I call disconnect, and call the connect function again -> with this its working.
I've tried to go to like 1 second -> this is not working.
This is not a great solution, but atleast something that is working.
Maybe you got some more insights here
Thanks Lars
Edit:
I didn't try BLUETOOTH_RESTORE_STATE
on iOS, but I think I'll just stick to the scan alternative.
Also I've tried NRFC-Tool while rebooting the phone: the device is found wihle rebooting, so the disconnect is real, and the device is advertising normaly again.
@graphefruit are you able to try v1.7.0-alpha.1 and see if that helps anything?
npm install cordova-plugin-ble-central@alpha
should do it.
I've added a hardcoded 1s delay after connect before running service discovery just to see if that makes any impacts.
It would be good to capture some adb logs showing both the bad initial connection, and the follow-up good connection. Something like adb logcat > debug.logs
should give you useful information.
Hey @peitschie, thanks for the new alpha sadly this doesn't had any impact on my side. I've run the ADB Logcat, is there anything specific I should watch out?
To be honest it looks like a big mess for me as a non familiar
To be honest it looks like a big mess for me as a non familiar
Yep... Usually looks the same to me too 😆
I'm interested about the log snippet from the start of the connect call through to the disconnect reporting.
As a quick side question, what error object do you get when the disconnect is called on that first connect attempt?
I've tried it with the original app, there the connection is established without any problems, and nearly instant. (This app is written in flutter)
Do you have the source code for this app? I wonder what Bluetooth library they're using?
As a quick side question, what error object do you get when the disconnect is called on that first connect attempt?
{"name":"PRS31074","id":"EC:D4:69:87:79:62","errorMessage":"Peripheral Disconnected"}
Do you have the source code for this app? I wonder what Bluetooth library they're using?
No but I'm in contact with the manufacturer, I'll ask him.
I'm interested about the log snippet from the start of the connect call through to the disconnect reporting.
I'll crawl the logs this evening and post them here!
Btw: If you want to have a look at my sourcecode here we go: https://github.com/graphefruit/Beanconqueror/tree/feature/graph
Where all the magic starts: https://github.com/graphefruit/Beanconqueror/blob/2ddcec39f7d551ee0ca2d9beccded6dabc4b09e8/src/app/app.component.ts#L609
And here where to connection logic than grabs to the pressure sensor: https://github.com/graphefruit/Beanconqueror/blob/2ddcec39f7d551ee0ca2d9beccded6dabc4b09e8/src/services/coffeeBluetoothDevices/coffee-bluetooth-devices.service.ts#L954
Thanks again for your efforts & helping hands Realy appreciate it!
Hey @peitschie ,
here we go:
Do you have the source code for this app? I wonder what Bluetooth library they're using?
https://github.com/pauldemarco/flutter_blue
Also I did the logs, and copy & pasted the necessary things - I hope those helps.
The connecting id is EC:D4:69:87:79:62
Booting phase...
05-05 20:50:30.014 2558 6080 D BluetoothAdapter: isLeEnabled(): ON
05-05 20:50:30.066 1884 2601 I bt_stack: [INFO:gatt_api.cc(947)] GATT_Register 3e449778-d6bc-b453-4f7c-c748e0a17872
05-05 20:50:30.066 1884 2601 I bt_stack: [INFO:gatt_api.cc(967)] allocated gatt_if=6
05-05 20:50:30.066 2558 4775 D BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=6 mScannerId=0
05-05 20:50:32.823 2558 6452 D BluetoothAdapter: isLeEnabled(): ON
05-05 20:50:32.826 2558 6452 I Nearby : [MBleClient] M hardware scan: 1 clients, scanMode= OPPORTUNISTIC, filters size = 5 [CONTEXT service_id=49 ]
05-05 20:50:32.827 2558 6452 D BluetoothAdapter: isLeEnabled(): ON
05-05 20:50:32.828 2558 4691 W ProviderHelper: Unknown dynamite feature providerinstaller.dynamite
05-05 20:50:32.829 1884 2601 I bt_stack: [INFO:gatt_api.cc(947)] GATT_Register daaf11b5-f4ac-4fb0-6df2-c27379dc8521
05-05 20:50:32.829 1884 2601 I bt_stack: [INFO:gatt_api.cc(967)] allocated gatt_if=7
05-05 20:50:32.831 2558 4691 D BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=7 mScannerId=0
05-05 20:50:32.861 5904 6482 I ...ntity.auth.device.aa: Returning Default multiple profile settings
05-05 20:50:32.887 1884 2601 E bt_btm : BTM_BleObserve Observe Already Active
05-05 20:50:32.887 1884 2601 W bt_btif : bta_dm_ble_observe BTM_BleObserve failed. status 6
Here the first log is to connect inside the app:
05-05 20:50:54.180 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["AutoConnectPressureDevice - We can start to connect to the id EC:D4:69:87:79:62 and type PRS"]"
05-05 20:50:54.190 7360 7992 D BLEPlugin: action = connect
05-05 20:50:54.195 7360 7992 D Peripheral: Creating un-scanned peripheral entry for address: EC:D4:69:87:79:62
05-05 20:50:54.198 7360 7992 D BluetoothGatt: connect() - device: EC:D4:69:87:79:62, auto: false
05-05 20:50:54.198 7360 7992 D BluetoothGatt: registerApp()
05-05 20:50:54.198 7360 7992 D BluetoothGatt: registerApp() - UUID=191a6046-8af8-46b2-ac37-3fc86e8f11f7
05-05 20:50:54.210 7360 7992 W PluginManager: THREAD WARNING: exec() call to BLE.connect blocked the main thread for 25ms. Plugin should use CordovaInterface.getThreadPool().
05-05 20:50:54.217 1884 2601 I bt_stack: [INFO:gatt_api.cc(947)] GATT_Register 47c23bb6-e24d-6197-cc5b-e793507edd4b
05-05 20:50:54.217 1884 2601 I bt_stack: [INFO:gatt_api.cc(967)] allocated gatt_if=8
05-05 20:50:54.218 7360 7404 D BluetoothGatt: onClientRegistered() - status=0 clientIf=8
05-05 20:50:54.218 1884 2601 I bt_stack: [INFO:gatt_api.cc(1105)] GATT_Connectgatt_if=8, address=ec:d4:69:87:79:62
05-05 20:50:54.893 1884 1884 I bt_stack: [INFO:avrcp_service.cc(346)] virtual void bluetooth::avrcp::AvrcpService::SendMediaUpdate(bool, bool, bool) track_changed=0 : play_state=0 : queue=0
Here I try to just scan as long to find all the id's (this I do like you mentioned meanwhile the connecting phase)
05-05 20:50:55.179 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["findDeviceWithDirectIds - Try to get bluetooth state"]"
05-05 20:50:55.179 7360 7992 D BLEPlugin: action = isEnabled
05-05 20:50:55.182 7360 7992 D BLEPlugin: action = startScanWithOptions
05-05 20:50:55.183 7360 7992 D BLEPlugin: Not removing connecting device: EC:D4:69:87:79:62
05-05 20:50:55.183 7360 7992 D BluetoothAdapter: isLeEnabled(): ON
05-05 20:50:55.185 1884 2601 I bt_stack: [INFO:gatt_api.cc(947)] GATT_Register 45e220cb-9242-0c22-7c35-21f4e48f7bdb
05-05 20:50:55.185 1884 2601 I bt_stack: [INFO:gatt_api.cc(967)] allocated gatt_if=9
05-05 20:50:55.186 7360 7385 D BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=9 mScannerId=0
...done until we found all:
05-05 20:51:03.089 7360 7360 W BLEPlugin: Scan Result
05-05 20:51:03.092 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["Fri May 05 2023 20:51:03 GMT+0200 (Mitteleuropäische Sommerzeit)Device found {\"name\":\"PRS31074\",\"id\":\"EC:D4:69:87:79:62\",\"advertising\":{},\"rssi\":-90}"]", source: https://beanconqueror.com/main.js (37780)
05-05 20:51:03.092 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["findDeviceWithDirectIds - we found the exact searched device {\"name\":\"PRS31074\",\"id\":\"EC:D4:69:87:79:62\",\"advertising\":{},\"rssi\":-90}"]",
05-05 20:51:03.093 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["findDeviceWithDirectIds - we found ALL to searching devices "]"
05-05 20:51:03.098 7360 7992 D BLEPlugin: action = stopScan
05-05 20:51:03.098 7360 7992 D BLEPlugin: Stopping Scan
05-05 20:51:03.098 7360 7992 D BluetoothAdapter: isLeEnabled(): ON
05-05 20:51:16.467 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=3 connected=0 conn_id=0x0003 reason=0x00ff
05-05 20:51:16.467 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=4 connected=0 conn_id=0x0004 reason=0x00ff
05-05 20:51:16.468 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=5 connected=0 conn_id=0x0005 reason=0x00ff
05-05 20:51:16.468 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=6 connected=0 conn_id=0x0006 reason=0x00ff
05-05 20:51:16.468 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=7 connected=0 conn_id=0x0007 reason=0x00ff
05-05 20:51:16.468 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=8 connected=0 conn_id=0x0008 reason=0x00ff
05-05 20:51:16.468 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(340)] bta_gattc_open_fail: Cannot establish Connection. conn_id=000000. Return GATT_ERROR(133)
05-05 20:51:24.224 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=3 connected=0 conn_id=0x0103 reason=0x00ff
05-05 20:51:24.224 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=4 connected=0 conn_id=0x0104 reason=0x00ff
05-05 20:51:24.224 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=5 connected=0 conn_id=0x0105 reason=0x00ff
05-05 20:51:24.225 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=6 connected=0 conn_id=0x0106 reason=0x00ff
05-05 20:51:24.225 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=7 connected=0 conn_id=0x0107 reason=0x00ff
05-05 20:51:24.225 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(1044)] bta_gattc_conn_cback: cif=8 connected=0 conn_id=0x0108 reason=0x00ff
05-05 20:51:24.227 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(340)] bta_gattc_open_fail: Cannot establish Connection. conn_id=000000. Return GATT_ERROR(133)
05-05 20:51:24.251 7360 7385 D BluetoothGatt: onClientConnectionState() - status=133 clientIf=8 device=EC:D4:69:87:79:62
05-05 20:51:24.251 7360 7385 D Peripheral: onConnectionStateChange DISCONNECTED
05-05 20:51:24.251 7360 7385 D BluetoothGatt: cancelOpen() - device: EC:D4:69:87:79:62
05-05 20:51:24.252 7360 7385 D BluetoothGatt: close()
05-05 20:51:24.252 7360 7385 D BluetoothGatt: unregisterApp() - mClientIf=8
05-05 20:51:24.254 1884 2601 E bt_stack: [ERROR:bta_gattc_act.cc(293)] No such connection need to be cancelled
05-05 20:51:24.254 1884 2601 E bt_stack: [ERROR:bta_gattc_utils.cc(433)] bta_gattc_mark_bg_conn unable to find the bg connection mask for bd_addr=ec:d4:69:87:79:62
Here the disconnect is triggered.
05-05 20:51:24.257 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["AutoConnectPressureDevice - Pressure device disconnected."]"
05-05 20:51:24.257 7360 7360 I chromium: [INFO:CONSOLE(33010)] "{"name":"PRS31074","id":"EC:D4:69:87:79:62","errorMessage":"Peripheral Disconnected"}"
And then I try to reconnect again.
05-05 20:51:24.261 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["AutoConnectPressureDevice - We can start to connect to the id EC:D4:69:87:79:62 and type PRS"]", source: https://beanconqueror.com/main.js (37780)
05-05 20:51:24.262 7360 7992 D BLEPlugin: action = connect
05-05 20:51:24.264 7360 7992 D BluetoothGatt: connect() - device: EC:D4:69:87:79:62, auto: false
05-05 20:51:24.264 7360 7992 D BluetoothGatt: registerApp()
05-05 20:51:24.264 7360 7992 D BluetoothGatt: registerApp() - UUID=ac0cf207-29b1-42e3-8fba-c740e73bc14e
05-05 20:51:24.264 1884 2601 I bt_stack: [INFO:gatt_api.cc(947)] GATT_Register 7ed82c64-7479-1dca-9c28-abff006c9782
05-05 20:51:24.264 1884 2601 I bt_stack: [INFO:gatt_api.cc(967)] allocated gatt_if=8
05-05 20:51:24.265 7360 7385 D BluetoothGatt: onClientRegistered() - status=0 clientIf=8
05-05 20:51:24.265 1884 2036 D bt_btif_config: btif_get_address_type: Device [ec:d4:69:87:79:62] address type 1
05-05 20:51:24.265 1884 2036 D bt_btif_config: btif_get_device_type: Device [ec:d4:69:87:79:62] type 2
05-05 20:51:24.265 1884 2601 I bt_stack: [INFO:gatt_api.cc(1105)] GATT_Connectgatt_if=8, address=ec:d4:69:87:79:62
05-05 20:51:30.295 1884 2601 I bt_stack: [INFO:gatt_sr.cc(753)] MTU request PDU with MTU size 247
05-05 20:51:30.295 1884 2601 E bt_btm : BTM_SetBleDataLength failed, peer does not support request
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=3
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=4
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=5
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=6
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=7
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=8
05-05 20:51:30.296 1884 2601 W bt_btif : bta_dm_acl_change info: 0x0
05-05 20:51:30.296 1884 2036 D bt_btif_dm: remote version info [ec:d4:69:87:79:62]: 0, 0, 0
05-05 20:51:30.297 1884 2601 E bt_stack: [ERROR:bta_gattc_cache.cc(717)] bta_gattc_cache_load: can't open GATT cache file /data/misc/bluetooth/gatt_cache_ecd469877962 for reading, error: No such file or directory
05-05 20:51:30.297 1884 2601 I bt_stack: [INFO:hearing_aid.cc(1811)] GetDeviceCount: Not initialized yet
05-05 20:51:30.297 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=1, s_handle=0x0001, e_handle=0xffff
05-05 20:51:30.299 1494 1694 D ContextHubService: Added callback, total callbacks 5
05-05 20:51:30.301 1494 1694 D ContextHubClientManager: Registered client with host endpoint ID 4
05-05 20:51:30.301 1884 1884 E BluetoothPhonePolicy: Received unexpected intent, action=android.bluetooth.device.action.ACL_CONNECTED
05-05 20:51:30.301 1884 1884 I BluetoothPhonePolicy: processDeviceConnected, device=EC:D4:69:87:79:62
05-05 20:51:30.301 1884 1884 D BluetoothDatabase: setConnection: device=EC:D4:69:87:79:62 and isA2dpDevice=false
05-05 20:51:30.301 1884 1884 D BluetoothDatabase: setConnection: Creating new metadata entry for device: EC:D4:69:87:79:62
05-05 20:51:30.302 1905 2070 W BluetoothEventManager: AclStateChangedHandler: activeDevice is null
05-05 20:51:30.303 7360 7385 D BluetoothGatt: onClientConnectionState() - status=0 clientIf=8 device=EC:D4:69:87:79:62
05-05 20:51:30.303 7360 7385 D Peripheral: onConnectionStateChange CONNECTED
05-05 20:51:30.303 7360 7385 D BluetoothGatt: discoverServices() - device: EC:D4:69:87:79:62
05-05 20:51:30.303 1884 1884 D BluetoothDatabase: updateDatabase EC:D4:69:87:79:62
05-05 20:51:30.564 1884 2036 D bt_btif_config: btif_get_device_type: Device [ec:d4:69:87:79:62] type 2
05-05 20:51:30.565 1884 2036 D bt_btif_config: btif_get_device_type: Device [ec:d4:69:87:79:62] type 2
05-05 20:51:30.565 1884 2036 I bt_btif_dm: get_cod remote_cod = 0x00001f00
05-05 20:51:30.565 1884 2036 I BluetoothBondStateMachine: bondStateChangeCallback: Status: 0 Address: EC:D4:69:87:79:62 newState: 1
05-05 20:51:30.565 1884 2036 D bt_btif_config: btif_get_device_type: Device [ec:d4:69:87:79:62] type 2
05-05 20:51:30.565 1884 2036 I BluetoothBondStateMachine: sspRequestCallback: [B@fd2eb95 name: [B@ad3e4aa cod: 7936 pairingVariant 2 passkey: 0
05-05 20:51:30.568 1884 2397 I BluetoothBondStateMachine: Bond State Change Intent:EC:D4:69:87:79:62 BOND_NONE => BOND_BONDING
05-05 20:51:30.569 1905 2070 W BluetoothEventManager: Got bonding state changed for EC:D4:69:87:79:62, but we have no record of that device.
05-05 20:51:30.569 1884 1884 D A2dpService: Bond state changed for device: EC:D4:69:87:79:62 state: 11
05-05 20:51:30.571 1884 2397 I BluetoothBondStateMachine: Entering PendingCommandState State
05-05 20:51:30.601 1494 1552 I ActivityManager: Start proc 10959:com.android.settings/1000 for broadcast {com.android.settings/com.android.settings.bluetooth.BluetoothPairingRequest}
05-05 20:51:30.726 3344 3945 I BistoWorker: (REDACTED) bluetoothConnectionStateChanged. Action: %s
05-05 20:51:30.920 10959 10959 D LocalBluetoothProfileManager: LocalBluetoothProfileManager construction complete
05-05 20:51:30.922 10959 10959 D LocalBluetoothProfileManager: Adding local A2DP profile
05-05 20:51:30.924 10959 10959 D BluetoothA2dp: Binding service...
05-05 20:51:30.295 1884 2601 I bt_stack: [INFO:gatt_sr.cc(753)] MTU request PDU with MTU size 247
05-05 20:51:30.295 1884 2601 E bt_btm : BTM_SetBleDataLength failed, peer does not support request
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=3
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=4
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=5
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=6
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=7
05-05 20:51:30.295 1884 2601 W bt_stack: [WARNING:gatt_utils.cc(721)] Call back not found for application conn_id=8
05-05 20:51:30.296 1884 2601 W bt_btif : bta_dm_acl_change info: 0x0
05-05 20:51:30.296 1884 2036 D bt_btif_dm: remote version info [ec:d4:69:87:79:62]: 0, 0, 0
05-05 20:51:30.297 1884 2601 E bt_stack: [ERROR:bta_gattc_cache.cc(717)] bta_gattc_cache_load: can't open GATT cache file /data/misc/bluetooth/gatt_cache_ecd469877962 for reading, error: No such file or directory
05-05 20:51:30.297 1884 2601 I bt_stack: [INFO:hearing_aid.cc(1811)] GetDeviceCount: Not initialized yet
05-05 20:51:30.297 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=1, s_handle=0x0001, e_handle=0xffff
05-05 20:51:30.928 10959 10959 D LocalBluetoothProfileManager: Adding local HEADSET profile
05-05 20:51:30.930 10959 10959 D LocalBluetoothProfileManager: Adding local MAP profile
05-05 20:51:30.930 10959 10959 D BluetoothMap: Create BluetoothMap proxy object
05-05 20:51:30.933 10959 10959 D BluetoothMap: Binding service...
05-05 20:51:30.935 10959 10959 D LocalBluetoothProfileManager: Adding local OPP profile
05-05 20:51:30.935 10959 10959 D LocalBluetoothProfileManager: Adding local HID_HOST profile
05-05 20:51:30.935 10936 10936 W UnsafeUtil: platform method missing - proto runtime falling back to safer methods: java.lang.NoSuchMethodException: sun.misc.Unsafe.copyMemory [class java.lang.Object, long, class java.lang.Object, long, long]
05-05 20:51:30.936 10959 10959 D BluetoothHidHost: Binding service...
05-05 20:51:30.938 10959 10959 D LocalBluetoothProfileManager: Adding local HID_DEVICE profile
05-05 20:51:30.942 10959 10959 D BluetoothHidDevice: Binding service...
05-05 20:51:30.946 10959 10959 D LocalBluetoothProfileManager: Adding local PAN profile
05-05 20:51:30.947 10959 10959 D BluetoothPan: Binding service...
05-05 20:51:30.948 10959 10959 D LocalBluetoothProfileManager: Adding local PBAP profile
05-05 20:51:30.950 10959 10959 D LocalBluetoothProfileManager: Adding local SAP profile
05-05 20:51:30.950 10959 10959 D BluetoothSap: Create BluetoothSap proxy object
05-05 20:51:30.951 10959 10959 D BluetoothSap: Binding service...
05-05 20:51:30.961 10959 10959 V LocalBluetoothPreferences: Found no reason to show the dialog - do not show dialog.
05-05 20:51:30.963 10959 10959 D BluetoothA2dp: Proxy object connected
05-05 20:51:30.963 10959 10959 D BluetoothMap: Proxy object connected
05-05 20:51:30.963 10959 10959 D BluetoothMap: getConnectedDevices()
05-05 20:51:30.963 10959 10959 D BluetoothHidHost: Proxy object connected
05-05 20:51:30.963 10959 10959 D BluetoothHidDevice: Proxy object connected
05-05 20:51:30.963 10959 10959 D BluetoothPan: Proxy object connected
05-05 20:51:30.964 10959 10959 D BluetoothSap: Proxy object connected
05-05 20:51:30.964 10959 10959 D BluetoothSap: getConnectedDevices()
05-05 20:51:30.964 1884 3526 V SapService: getConnectedDevices()
05-05 20:51:30.974 10936 10936 D HardwareInfoService: Upload Reason: SERIAL_CHANGED
05-05 20:51:30.976 10959 10959 D BluetoothPairingService: Show pairing notification for EC:D4:69:87:79:62 (PRS31074)
05-05 20:51:31.374 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=4, s_handle=0x0001, e_handle=0x0009
05-05 20:51:31.420 7360 7385 D BluetoothGatt: onPhyUpdate() - status=0 address=EC:D4:69:87:79:62 txPhy=2 rxPhy=2
05-05 20:51:31.735 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=3, s_handle=0x000b, e_handle=0x000f
05-05 20:51:31.915 7360 7385 D BluetoothGatt: onConnectionUpdated() - Device=EC:D4:69:87:79:62 interval=6 latency=0 timeout=500 status=0
05-05 20:51:31.929 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=4, s_handle=0x000b, e_handle=0x000f
05-05 20:51:32.086 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=3, s_handle=0x0010, e_handle=0x0013
05-05 20:51:32.131 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=4, s_handle=0x0010, e_handle=0x0013
05-05 20:51:32.229 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=5, s_handle=0x0013, e_handle=0x0013
05-05 20:51:32.245 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=3, s_handle=0x0014, e_handle=0x0017
05-05 20:51:32.268 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=4, s_handle=0x0014, e_handle=0x0017
05-05 20:51:32.319 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=5, s_handle=0x0017, e_handle=0x0017
05-05 20:51:32.342 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=3, s_handle=0x0018, e_handle=0x001b
05-05 20:51:32.394 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=4, s_handle=0x0018, e_handle=0x001b
05-05 20:51:32.694 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=5, s_handle=0x001f, e_handle=0x001f
05-05 20:51:32.710 1884 2601 I bt_stack: [INFO:gatt_api.cc(632)] GATTC_Discover conn_id=0x0008, disc_type=5, s_handle=0x0022, e_handle=0xffff
05-05 20:51:32.739 1884 2601 I bt_stack: [INFO:bta_gattc_cache.cc(178)] bta_gattc_explore_srvc_finished: service discovery finished
05-05 20:51:32.740 1884 2036 E bt_btif_gattc: btif_gattc_upstreams_evt: Unhandled event (8)!
05-05 20:51:32.742 1884 2036 D bt_bta_gattc: bta_gattc_get_gatt_db
05-05 20:51:32.745 7360 7385 D BluetoothGatt: onSearchComplete() = Device=EC:D4:69:87:79:62 Status=0
And here we got connected now
05-05 20:51:32.756 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["AutoConnectPressureDevice - Pressure device connected."]"
5-05 20:51:32.764 7360 7992 D BLEPlugin: action = startNotification
05-05 20:51:32.764 7360 7992 D Peripheral: Queuing Command com.megster.cordova.ble.central.BLECommand@3495145
05-05 20:51:32.764 7360 7992 D Peripheral: Processing Commands
05-05 20:51:32.765 7360 7992 D Peripheral: Register Notify 873ae82b-4c5a-4342-b539-9d900bf7ebd0
05-05 20:51:32.765 7360 7992 D BluetoothGatt: setCharacteristicNotification() - uuid: 873ae82b-4c5a-4342-b539-9d900bf7ebd0 enable: true
05-05 20:51:32.769 7360 7360 I chromium: [INFO:CONSOLE(37780)] "CoffeeBluetoothDevices: ["Pressure Connected successfully"]"
05-05 20:51:32.800 7360 7385 D Peripheral: onDescriptorWrite android.bluetooth.BluetoothGattDescriptor@d58d09a
05-05 20:51:32.800 7360 7385 D Peripheral: Processing Complete
05-05 20:51:32.800 7360 7385 D Peripheral: Processing Commands
05-05 20:51:32.800 7360 7385 D Peripheral: Command Queue is empty.
05-05 20:51:32.802 11219 11219 E ileged_process: Not starting debugger since process cannot load the jdwp agent.
05-05 20:51:32.820 1494 3480 V UserManagerService: dumpPackageWhitelistProblems(): using mode ENFORCE|IMPLICIT_WHITELIST|IMPLICIT_WHITELIST_SYSTEM
05-05 20:51:32.829 7360 7385 D BluetoothGatt: onConnectionUpdated() - Device=EC:D4:69:87:79:62 interval=36 latency=0 timeout=500 status=0
Thanks! Lars
This line here gives us a gatt error to start from:
05-05 20:51:16.468 1884 2601 W bt_stack: [WARNING:bta_gattc_act.cc(340)] bta_gattc_open_fail: Cannot establish Connection. conn_id=000000. Return GATT_ERROR(133)
I noticed that you are stopping the scan at the same time as trying to connect. I've seen this cause problems on some phones. It might be worth putting a 5-10 second delay there before calling stop scan (still call connect immediately) and see if this helps the stability at all?
Hey @peitschie, I just tried it. I let it scan forever while connecting, same situation. The .connect triggers the disconnect function, and after that, when I call .connect a second time its working.
Also worth mentioning, while the first .connect
the advertisement of the pressure-sensor is still given, therefore it doesn't stop advertising, after the second .connect
call the advertisement stopped because the connect was successfull.
The error stayed the same:
05-06 09:14:28.808 1891 2577 W bt_stack: [WARNING:bta_gattc_act.cc(340)] bta_gattc_open_fail: Cannot establish Connection. conn_id=000000. Return GATT_ERROR(133)
05-06 09:14:35.033 1891 2577 W bt_stack: [WARNING:bta_gattc_act.cc(340)] bta_gattc_open_fail: Cannot establish Connection. conn_id=000000. Return GATT_ERROR(133)
For the flutter-based app @graphefruit , do you know what setting is being used on connect
for the autoConnect
flag?
https://pub.dev/documentation/flutter_blue/latest/flutter_blue/BluetoothDevice/connect.html
It looks like the default value in the Flutter library is true, while the connect
call in this plugin will set that as false. ble.autoConnect
would be the equivalent call with this library.
What you're describing looks something like https://github.com/don/cordova-plugin-ble-central/issues/766
Other users have reported that ble.autoConnect
stopped the disconnect here. I wonder if it will change what you're seeing.
It looks like the default value in the Flutter library is true, while the
connect
call in this plugin will set that as false.ble.autoConnect
would be the equivalent call with this library.
Their app does not use autoConnect.
Just to double confirm, their app is explicitly setting autoConnect
to false when calling connect?
Just to double confirm, their app is explicitly setting
autoConnect
to false when calling connect?
The flag is set to false.
What you're describing looks something like #766
Other users have reported that
ble.autoConnect
stopped the disconnect here. I wonder if it will change what you're seeing.
With .autoConnect I cant (even) more connect to the pressure sensor, this may be because I enabled pairing and had a bit trouble with the device, but anyhow, even calling .disconnect after a timeout and then going with .autoConnect is not working.
The only real solution I got at the moment is to call .connect
wait for the disconnect and connect again.
With a reboot it takes about 30 sec to 1 minute to establish a connection, after that its "fast"
@graphefruit out of interest, do you have anything else connected/paired with the phone? Does this connect problem happen across all Android devices, or just a specific Android version/manufacturer?
Just wondering as another dev has reported that Android disconnects their peripheral when a smartband device is paired with the phone: https://github.com/don/cordova-plugin-ble-central/issues/956#issuecomment-1540078955
@graphefruit another random idea... I noticed that FlutterBlue does connect
and discoverServices
as two separate calls. How does the original app coordinate these calls together?
Hey @peitschie , Sorry for getting back that late.
@graphefruit out of interest, do you have anything else connected/paired with the phone? Does this connect problem happen across all Android devices, or just a specific Android version/manufacturer?
Just wondering as another dev has reported that Android disconnects their peripheral when a smartband device is paired with the phone: #956 (comment)
I had this issue on Google Pixel 2 and Google Pixel 4a 5g, more Android devices I don't realy have to test at home. Yes I'm having one device attached (an old smartwatch).
graphefruit another random idea... I noticed that FlutterBlue does
connect
anddiscoverServices
as two separate calls. How does the original app coordinate these calls together?
I had a call with the manufacturer the last days.
He had one good impression when also having a look at the ADB Log:
05-05 20:50:54.195 7360 7992 D Peripheral: Creating un-scanned peripheral entry for address: EC:D4:69:87:79:62
It looked like the app tries to connect bevor having a scan result.
So what I did on this hint, I added a search for the device, waited until it was found, did a delay of about 1 second and then I tried to connect to the pressure device.
And voila, it connects (nearly) instantly after the search after a phone reboot, after that it also connects instantly. Anyhow, this still has some delay of about 10 seconds.
BUT
When I restart the phone, and I'm not in range for the device, the scan will not find the device and I try to connect, it had the issue that the connection didn't work at all. The disconnect
function was called, I tried to reconnect
and it didn't connect again.
My next workaround is now, that when the disconnect
is triggered, I now try to search for the device again for about 8 second, and then try to connect again.
Anyhow, I'm getting a new firmware of the manufacturer the next couple of days, because this one will disable a pairing possibility with my android device - maybe some issues also results from this.
Anyhow my idea - I don't know if this is possible:
Making another option for .connect
to pass an attribute to say "search before connect" ?
Hope these information helps
@graphefruit another random idea... I noticed that FlutterBlue does
connect
anddiscoverServices
as two separate calls. How does the original app coordinate these calls together?
Hey @peitschie I've got information from the manufacturer how they handle it:
The app waits for the device getting connected state, and then calls discoverServices. After getting the results, the app sets the pressure characteristics to notify and subscribes to it.
@graphefruit that's a lot of really great insight there. I haven't had a chance this week to dig into reproducing myself, but reset assured this is high up on my list!
Thanks for taking the time to detail all this out here!
The app waits for the device getting connected state, and then calls discoverServices. After getting the results, the app sets the pressure characteristics to notify and subscribes to it.
Right. This matches what this plugin does as well, so at least we're all aligned there.
Hello @peitschie, I just had another issue with Android and now the Bluetooth-Scale. I just added for safteyness a scan before connect but while scanning I connected.
Before we start: Its just with one specific scale, and not with all. When I do a ble.autoConnect to the scale, it sometimes randomly disconnects tries to reconnect and disconnects. Restarting the app helped sometimes.
Removing the scan before connecting to the scale and then .autoConnect
it works.
Funfact:
When I add the scan before, but use .connect
it also works, so there needs to be an correlation to the .autoConnect
Meanwhile I've got another firmware from the manufacturer, and many things could be removed. The device accepted ble-pairing, they disabled it in the latest firmware update (or ignoring it?) now the connection is much more smoother, faster and stabler.
Hope all these inside help
Thanks! Lars
This is very much making me appreciate how complex Android's BLE stack really is.
Basically, we have the following systems in play:
connect
explicitly tries to connect to a device by Mac address. If you do it before the scan, Android creates a placeholder proxy and tries to initiate the connection (and we believe this triggers the disconnect on the first try when paired, perhaps)autoConnect
is actually more passive, and waits for an advertising packet to be found via another scanning mechanism before connecting.I wonder if starting a scan explicitly and then auto-connecting confuses some stacks 🤔
So based on what you're saying here though, the two best approaches are:
autoConnect
and don't explicitly scan (i.e., let the OS schedule this itself)connect
connect
without an explicit scan (to be confirmed)I've taken some notes and might turn this into a support doc here someday.
Thanks as ever for continuing to report your findings back. They're most insightful!
This comment was potentially against the wrong issue @graphefruit ? Should be against #975?
Hey BLE-Contributors, thank you all for the hard work you did with this plugin! Its awesome that this is so well maintained and working pretty great!
After I've stepped up on my app to not just connect one single ble, rather multiple once, I've encountered some issues.
Some context to this: I'm developing a coffee app, where you can connect bluetooth scales, bluetooth pressure gauges, aswell as temperature devices and soon also a bluetooth refractometer and coffee particel analyser.
All these devices are connected inside the settings, and the device-id is stored in a database, so when the app starts up again, the app connects to all known devices.
What I've encountered:
-> Would there maybe be the possibility to add the search solution to ble.autoConnect for iOS, that it searches internal the device, before it connects?
2.1. Also I've encountered when I stored the device id, and I autoConnect to the pressure device it sometimes never connects, and I need to disconnect (forget the id), restart the app and start searching again.
2.2 Also I've encountered, when I search the device, connect to it on Android, disconnect and connect again, the device sometimes is not found anymore. (Funny that on iOS this works like without no issues)
On Android I also scanWithOptions
I've made some progress with it, but still not fluent & good, and far away from the iOS performance. Also I've disconnected normal connected Bluetooth-Devices like a watch or bluetooth airpods, which also did some improvement in connectivity.
I'm using the latest release 1.6.3, and tried with Pixel 2XL Android 11, and Pixel 4a 5g Android 13. Same issues on both devices.
The bluetooth scales, are connecting directly, so its real just the pressure sensor which is doing strange. BUT with the original app of the manufacturer, which is written in flutter, it has no issues at all :<.
The connected smart-scale devices sends about one request each 100ms, the connected pressure sensor, also would send between 20-100ms one request. (so faster then the smart scale)
My setup is Ionic 6, with Cordova,
Platform:
I'm also using ble.withPromises... solution.
Thanks for your help, hope. the information are enough, else I'm happy to provide more information! Lars