W3C home > Mailing lists > Public > public-web-bluetooth-log@w3.org > December 2016

Re: [web-bluetooth] BluetoothRemoteGATTServer.disconnect could return a promise

From: Emill via GitHub <sysbot+gh@w3.org>
Date: Tue, 20 Dec 2016 00:17:40 +0000
To: public-web-bluetooth-log@w3.org
Message-ID: <issue_comment.created-268117085-1482193059-sysbot+gh@w3.org>
Your problem scenario is indeed valid. It is hard for an app to know 
when a connection will success or fail if the maximum number of 
connections is reached or almost reached.

When a disconnection is initiated, an LL_TERMINATE_IND packet is sent 
to the remote device. The disconnecting device must wait for a link 
layer acknowledgement of this packet (or timeout) until this 
connection is considered disconnected. So, the time to disconnect 
depends on the connection interval, slave latency and supervision 
timeout. The time to disconnect can in worst case take 32 seconds, 
which corresponds to the longest possible supervision timeout. Under 
normal circumstances however the time to disconnect is usually limited
 by the connection interval * (slave latency + 1).

Making disconnect promise-based is not as easy as it may sound, due to
 the fact that most GATT implementations offer a way to have multiple 
logical connections on the same physical connection. You can for 
example have two Android apps talking to the same BLE peripheral over 
a single physical GATT link. The peripheral "thinks" there is only one
 client at the other end. When you disconnect, you only disconnect the
 logical link, which is done immediately. The physical link will be 
kept open until all logical clients have disconnected. iOS, Android 
and Windows also adds some additional seconds after the last client 
disconnected until the actual link gets terminated. So when do you 
want your promise to resolve?

At least Android and Windows have global broadcasts you can listen to 
in order to know when physical links get disconnected which can be 
good in certain cases. But they are not exposed to Web Bluetooth...

Unfortunately, no platforms I'm aware of have well-defined behaviour 
nor documented APIs to handle the case when the maximum number of 
connections is reached. It seems people working on Bluetooth stacks 
have not really thought, cared about or even tested what will or 
should happen if users have many BLE devices. As an example, the 
Bluetooth stack in Android hangs if you have 7 BLE connections and try
 to establish the 8th with "autoConnect=true" (in the way that it will
 never again connect to BLE devices until Bluetooth is restarted, even
 if the 7 get disconnected). If you have GATT notifications you listen
 to in Windows and are above the maximum number of connections, you 
get no event telling this, so some notifications will not be delivered
 to your computer (since the peripheral can't connect). Generally 
among most platforms some random error code is thrown (general 
failure, internal error, unspecified error, gatt error) when you 
actively try to connect a new device when the maximum number of 
connections has been reached. Sometimes a better error code like "no 
resources" is thrown. The non-existing documentation of error codes 
that is unfortunately general among all BLE implementations is very 
annoying when you are an app developer (Windows must be the worst when
 they're trying to map BLE errors to their general 0x80... HRESULT 
error codes).

In the fliclib-linux-hci project I created 
 which is a GATT client implementation, acting as a TCP server, you 
can connect multiple TCP clients, having multiple logical connections 
for the same physical connection. Here I solved the maximum number of 
connections problem by having two events that are sent to all clients:
 EvtNoSpaceForNewConnection and EvtGotSpaceForNewConnection. 
EvtNoSpaceForNewConnection is sent when the maximum number of 
connections has been reached and EvtGotSpaceForNewConnection is sent 
when one physical link has been disconnected if the maximum number of 
connections was previously reached. Usually the programmer doesn't 
need to react to those events except from notifying the user, since in
 that implementation, there is also no way a connection attempt can 
return a failure status (except when also the white list is full, 
which is usually of size 128 and I guess no one reaches). It will 
simply try to connect forever until success.

GitHub Notification of comment by Emill
Please view or discuss this issue at 
 using your GitHub account
Received on Tuesday, 20 December 2016 00:17:51 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 17:58:24 UTC