React-native-ble-plx: connectToDevice doesn't time out on iOS

Created on 27 Oct 2017  路  9Comments  路  Source: Polidea/react-native-ble-plx

This may be an issue or just a question.

We have a situation where we have to poll a device characteristic for some data. Multiple clients may be in range and do the same polling, which could mean one phone is currently connected while another one also tries to connect. The target may also be turned off so that it's not available at all.

On Android, connecting while it's busy or turned off fails with an error after about 5 seconds. On iOS it can wait for several minutes then finally resolve as soon as the target is available again. Log example:

11:06:52 Reading...
11:06:52 Successfully read!
11:07:00 Reading...
11:09:54 Successfully read! <-- Note the timestamp

I also tried waiting for about 10 minutes; the connection seemed to actually hang there and any subsequent connection attempts resulted in an error, I'm guessing because a connection was already underway.

Android log example, what's expected:

11:24:19 Reading...
11:24:20 Successfully read!
11:24:25 Reading...
11:24:30 Unknown error: BleDisconnectedException{bluetoothDeviceAddress='ABC'}
11:24:35 Reading...
11:24:41 Unknown error: BleDisconnectedException{bluetoothDeviceAddress='ABC'}
11:24:46 Reading...
11:24:51 Unknown error: BleDisconnectedException{bluetoothDeviceAddress='ABC'}
11:24:56 Reading...
11:24:57 Successfully read!

Is this a known iOS behavior?

enhancement

All 9 comments

iOS native module doesn't contain any connection timeout. On Android it is probably defined by vendor, but I'm not sure about it (@dariuszseweryn will know). I think that we can add optional timeout property to connectionOptions object in next version of library. Until this is done you can always use cancelConnection function which will also cancel currently pending connect promises.

Thanks for the quick response! A native timeout option would definitely be welcome. We'll do the manual cancellation until then.

Android OS in direct connection mode (autoConnect=false) usually timeouts after 30 seconds (with status=133). Maybe in the above log there is a situation that the Android BLE stack notices that the peripheral to be connected is busy communicating a different device and returns prematurely?
When autoConnect=true then no timeout is applicable and the connection may succeed after an arbitrary period of time (usually much longer than in direct mode).

Background behaviour of the application is a different topic though especially on Android >= 7.0.

@dariuszseweryn Yeah I guess the behavior can differ between vendors like Cierpliwy said (we're using a mid-range Samsung for testing). So iOS seems to be in something like auto connect mode by default? Would setting autoConnect=true for Android affect anything more than the timeout, like automatic reconnect after disconnect or things like that? We only want to do a quick connect-read-disconnect.

Could you elaborate a bit on background behavior? It's something we will explore for a future version so knowing any caveats beforehand would be useful!

autoConnect=true does two things:

  1. Removes the 30 seconds timeout
  2. Makes the Android OS to use more relaxed setting of the scan鈥攖his makes the time needed for connection to be established longer (sometimes much longer) than in direct mode (autoConnect=false). I have seen situations that it took more than 5-10 minutes even if devices had been right beside each other.

As for the background behaviour I encourage you to read the documentation or check some other articles as this is a complex topic and it is hard to condensate everything into a single post.

I see, in that case we should not use it then. Thanks for the info!

I wonder if we could add 30 sec timeout by default and make autoConnect option to keep connection endlessly on iOS (current behaviour). @dariuszseweryn

We have two options to make the behaviour similar:

  • add a 30 seconds timeout on iOS (and autoConnect or equavilent as an option but mark that on Android it takes a lot longer time to connect this way and it is more susceptible to bugs on the system side)
  • make the Android automatically retry connection after fixed amount of time-let's say 25 seconds- just keep in mind that it can be harder to maintain due to potential timing bugs in the Android BLE stack

Since 0.9 there is timeout option in connectToDevice function.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brycejacobs picture brycejacobs  路  5Comments

biks152207 picture biks152207  路  3Comments

SlavaInstinctools picture SlavaInstinctools  路  4Comments

samthui picture samthui  路  4Comments

juanjo-ramos picture juanjo-ramos  路  3Comments