New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 620405 link

Starred by 5 users

Issue metadata

Status: WontFix
Owner: ----
Closed: Apr 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Feature

Blocking:
issue 577974



Sign in to add a comment

bluetooth: reject GATT connection in the same amount of time for all platforms

Project Member Reported by fbeaufort@chromium.org, Jun 15 2016

Issue description

The Web Platform Predictability project is an effort to make developing for the web more predictable, and as a result more enjoyable, cost-effective and competitive with native mobile platforms. See https://sites.google.com/a/chromium.org/dev/blink/platform-predictability

That's why I wonder if we could try to reject BluetoothDevice.gatt.connect() promise in the same amount of time for all platforms if device fails to connect.

Here are my early tests I'll update with new findings over time:

- Chrome OS: 40s
- Android N: 30s
 
Cc: jlebel@chromium.org
Status: Available (was: Untriaged)
On OS X, it looks like BluetoothDevice.gatt.connect() promise never rejects... it might be a bug there. 
I'd like gatt.connect() to hang forever on all platforms, until either a device shows up or the site calls gatt.disconnect(). Sorry it's not spec'ed yet: https://github.com/WebBluetoothCG/web-bluetooth/issues/152.
For info, here's some background from #bluez-users IRC channel about why the connection timeout is 40 seconds on current version of Chrome OS (Chromebook Pixel 2013):

10:14 <jhe> what's the base kernel version
10:14 <jhe> if you go back in history long enough this timeout didn't exist
10:14 <jhe> instead the socket's default timeout was used
10:15 <jhe> actually I think that's 40 seconds
10:15 <jhe> and it's controllable using some socket option, I think
10:15 <fbeaufort> OOOh! That's maybe why ;)
10:16 <fbeaufort> Base is  3.8.11
10:16 <jhe> that's probably threason then
10:16 <jhe> a quick check shows that the timeout was introduced in 3.15
10:16 <jhe> before that the code would rely on SO_RCVTIMEO or SO_SNDTIMEO (not sure which one is used for connect())
10:17 <fbeaufort> And we figured it out! Yeah!
10:17 <jhe> i.e. the generic socket code in the kernel will forcefully close the socket if the connection wasn't successful by then
New messages since you tabbed out
10:19 <jhe> for the record (if you indend to do some backporting) it was the following commit that introduced the 20s timeout:
10:19 <jhe> commit 9489eca4ab2fd5d9bbf3bab992168cc8107fc3e9
10:19 <jhe> Author: Johan Hedberg <johan.hedberg@intel.com>
10:19 <jhe> Date:   Fri Feb 28 17:45:46 2014 +0200
10:19 <jhe>     Bluetooth: Add timeout for LE connection attempts
10:21 <fbeaufort> Thank you ;)
Kernel 3.15 will have a dedicated timeout set to 20 seconds.

#define HCI_LE_CONN_TIMEOUT	msecs_to_jiffies(20000)	/* 20 seconds */

See http://git.kernel.org/cgit/linux/kernel/git/bluetooth/bluetooth.git/tree/include/net/bluetooth/hci.h#n267

Here are some adb logs which seem to indicate that Chrome doesn't do anything special regarding the 30 seconds timeout observed.

// Device is manually disconnected while connected
 
06-16 12:28:43.000 22944 23089 D BtGatt.GattService: onDisconnected() - clientIf=5, connId=5, address=AC:E6:4B:05:88:2D
06-16 12:28:43.001 31400 31411 D BluetoothGatt: onClientConnectionState() - status=8 clientIf=5 device=AC:E6:4B:05:88:2D
06-16 12:28:43.001 31400 31411 I cr_Bluetooth: onConnectionStateChange status:8 newState:Disconnected
06-16 12:28:43.002 31400 31411 D BluetoothGatt: close()
06-16 12:28:43.002 31400 31411 D BluetoothGatt: unregisterApp() - mClientIf=5
06-16 12:28:43.003 22944 23089 E BluetoothRemoteDevices: state12newState1
06-16 12:28:43.003 22944 22958 D BtGatt.GattService: unregisterClient() - clientIf=5
06-16 12:28:43.006 22944 22944 D BluetoothMapService: onReceive
06-16 12:28:43.007 22944 22944 D BluetoothMapService: onReceive: android.bluetooth.device.action.ACL_DISCONNECTED
06-16 12:28:43.013 11991 11991 I TrustAgent.Tracker: [BluetoothConnectionTracker] Bluetooth disconnect broadast for PLAYBULB Candle AC:E6:4B:05:88:2D

// Trying to reconnect right away...

06-16 12:28:43.013 31400 31400 I cr_Bluetooth: connectGatt
06-16 12:28:43.016 31400 31400 D BluetoothGatt: connect() - device: AC:E6:4B:05:88:2D, auto: false
06-16 12:28:43.016 31400 31400 D BluetoothGatt: registerApp()
06-16 12:28:43.017 31400 31400 D BluetoothGatt: registerApp() - UUID=8b0da2e0-b8b1-4901-86ba-317655bf7b79
06-16 12:28:43.018 22944 22958 D BtGatt.GattService: registerClient() - UUID=8b0da2e0-b8b1-4901-86ba-317655bf7b79
06-16 12:28:43.019 22944 23089 D BtGatt.GattService: onClientRegistered() - UUID=8b0da2e0-b8b1-4901-86ba-317655bf7b79, clientIf=5
06-16 12:28:43.020 31400 31533 D BluetoothGatt: onClientRegistered() - status=0 clientIf=5
06-16 12:28:43.025 22944 23126 D BtGatt.GattService: clientConnect() - address=AC:E6:4B:05:88:2D, isDirect=true
06-16 12:28:43.027 22944 23089 D bt_btif_config: btif_get_address_type: Device [ac:e6:4b:05:88:2d] address type 0
06-16 12:28:43.027 22944 23089 D bt_btif_config: btif_get_device_type: Device [ac:e6:4b:05:88:2d] type 2

06-16 12:29:13.053 22944 23089 D BtGatt.GattService: onConnected() - clientIf=5, connId=0, address=AC:E6:4B:05:88:2D
06-16 12:29:13.054 31400 31533 D BluetoothGatt: onClientConnectionState() - status=133 clientIf=5 device=AC:E6:4B:05:88:2D
06-16 12:29:13.056 31400 31533 I cr_Bluetooth: onConnectionStateChange status:133 newState:Disconnected
06-16 12:29:13.058 31400 31533 D BluetoothGatt: close()
06-16 12:29:13.059 31400 31533 D BluetoothGatt: unregisterApp() - mClientIf=5
06-16 12:29:13.062 22944 23128 D BtGatt.GattService: unregisterClient() - clientIf=5

// Trying again after 2 seconds...

06-16 12:29:15.075 31400 31400 I cr_Bluetooth: connectGatt
06-16 12:29:15.079 31400 31400 D BluetoothGatt: connect() - device: AC:E6:4B:05:88:2D, auto: false
06-16 12:29:15.081 31400 31400 D BluetoothGatt: registerApp()
06-16 12:29:15.082 31400 31400 D BluetoothGatt: registerApp() - UUID=f2919890-69ee-4f6a-a59b-b6b0de7dafb9
06-16 12:29:15.085 22944 23125 D BtGatt.GattService: registerClient() - UUID=f2919890-69ee-4f6a-a59b-b6b0de7dafb9
06-16 12:29:15.090 22944 23089 D BtGatt.GattService: onClientRegistered() - UUID=f2919890-69ee-4f6a-a59b-b6b0de7dafb9, clientIf=5
06-16 12:29:15.091 31400 31410 D BluetoothGatt: onClientRegistered() - status=0 clientIf=5
06-16 12:29:15.094 22944 23126 D BtGatt.GattService: clientConnect() - address=AC:E6:4B:05:88:2D, isDirect=true
06-16 12:29:15.097 22944 23089 D bt_btif_config: btif_get_address_type: Device [ac:e6:4b:05:88:2d] address type 0
06-16 12:29:15.098 22944 23089 D bt_btif_config: btif_get_device_type: Device [ac:e6:4b:05:88:2d] type 2
According to BlueZ folks (https://plus.google.com/+FrancoisBeaufort/posts/ZZhfasV2WBJ), with BlueZ you can get reconnected using org.bluez.GattManager.RegisterApplication then the application is supposed to expose org.bluez.GattProfile1 to tell which UUID it is interested to be auto connected  as long as the application stay connected over D-Bus.
Cc: luiz.von...@intel.com
I agree with jyasskin, I don't think the connection attempts should "fail" at all due to time out. If a user wants a time out, he could just implement that himself in javascript, just as suggested at https://webbluetoothcg.github.io/web-bluetooth/#create-an-att-bearer.

For Android and I think BlueZ as well you have the option to either use "direct connect" or "auto connect".

For the "direct connect" there is an automatic timeout of 30s on Android. The "auto connect" has no time out. A very bad limitation of the direct connect is that you may only have one single outstanding connection attempt at a time (for the whole Android device). That said the direct connect seems pretty useless and shouldn't be used (and exist) at all in my opinion.

I tried with Web Bluetooth on Android (which uses direct connect) and indeed, if I have two pending connects and both two devices are currently not advertising and then start advertising on the second one I initiated a connection to, it will NOT connect, since Android is busy connecting to the first one.

The only good thing about the direct connect is that the default scan parameters are more active than auto connect (30 ms window, 60 ms interval) vs (30 ms window, 1280 ms interval). Samsung however have been smart to change the auto connect parameters to a bigger scan window. Of course it's a balance between power consumption (and blocking Wi-Fi radio) and latency. So the direct connect with a duty cycle of 50% won't be good in the long run anyway if the connection attempt is just restarted at time out.

In my opinion there should exist some mode with scan parameters with around 20% duty.

For Mac, it always uses "auto connect" since that's the only option available.
We should discuss this at https://github.com/WebBluetoothCG/web-bluetooth/issues/152 in order to get an audience broader than just Chromium.
Status: WontFix (was: Available)
We actually want the connection requests to never time out.

Sign in to add a comment