Several users reported timeouts while adding contacts. The problem seemed to be more severe in larger groups. One user experienced a long series of timeouts before successfully adding a contact.
If this problem is caused in some cases by congestion at the Bluetooth MAC layer, we may be able to mitigate it by keeping a cache of discovered devices and trying to connect to them before performing discovery. If a group of users are adding each other as contacts, the first discovery by each user should put most of the other users' devices in the cache.
If this problem is caused in some cases by poorly performing Bluetooth drivers or hardware, we may not be able to work around it at the application level.
This could be caused by the limit of eight devices (one master and seven slaves) in a Bluetooth piconet. If so, closing any open Bluetooth connections before attempting a new connection may help.
Alex Phleps provided this log output. The devices trying to connect were a Nexus 5 running Android 5.0.1 and an LG G2 Mini running Android 4.4.2. Four of the scrubbed MAC addresses correspond to the other phone running Briar; two correspond to a third device; and two to a fourth device. Thus apparently the other phone running Briar is discovered twice.
03-09 23:42:45.058 28476-29206/org.briarproject I/Connector﹕ org.briarproject.plugins.droidtooth.DroidtoothPlugin creating invitation connection 03-09 23:42:45.059 28476-29206/org.briarproject I/DroidtoothPlugin﹕ Invitation UUID fa22ce21-2bac-3247-ad8b-8e8cdad2e891 03-09 23:42:45.059 28476-29206/org.briarproject I/InsecureBluetooth﹕ Listening with new API 03-09 23:42:45.060 28476-29206/org.briarproject W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback 03-09 23:42:45.064 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Discovering nearby devices 03-09 23:42:45.065 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Starting discovery 03-09 23:43:03.011 28476-28476/org.briarproject I/DroidtoothPlugin﹕ Discovery finished 03-09 23:43:03.016 28476-29207/org.briarproject I/InsecureBluetooth﹕ Creating socket with new API 03-09 23:43:03.016 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Connecting to ###### 03-09 23:43:03.016 28476-29207/org.briarproject W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback 03-09 23:43:03.595 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Failed to connect to ###### 03-09 23:43:03.596 28476-29207/org.briarproject I/InsecureBluetooth﹕ Creating socket with new API 03-09 23:43:03.596 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Connecting to ###### 03-09 23:43:03.596 28476-29207/org.briarproject W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback 03-09 23:43:03.620 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Failed to connect to ###### 03-09 23:43:03.621 28476-29207/org.briarproject I/InsecureBluetooth﹕ Creating socket with new API 03-09 23:43:03.621 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Connecting to ###### 03-09 23:43:03.621 28476-29207/org.briarproject W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback 03-09 23:43:04.955 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Failed to connect to ###### 03-09 23:43:04.956 28476-29207/org.briarproject I/InsecureBluetooth﹕ Creating socket with new API 03-09 23:43:04.956 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Connecting to ###### 03-09 23:43:04.956 28476-29207/org.briarproject W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback 03-09 23:43:10.083 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Failed to connect to ###### 03-09 23:43:10.085 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Discovering nearby devices 03-09 23:43:10.086 28476-29207/org.briarproject I/DroidtoothPlugin﹕ Starting discovery 03-09 23:43:15.063 28476-29208/org.briarproject I/DroidtoothPlugin﹕ java.io.IOException: read failed, socket might closed or timeout, read ret: -1 03-09 23:43:15.065 28476-29204/org.briarproject I/ReferenceManagerImpl﹕ 1 handles for org.briarproject.api.invitation.InvitationTask after remove 03-09 23:43:18.454 28476-28963/org.briarproject I/Connector﹕ org.briarproject.plugins.droidtooth.DroidtoothPlugin received confirmation: false 03-09 23:43:18.454 28476-28963/org.briarproject I/ReferenceManagerImpl﹕ 0 handles for org.briarproject.api.invitation.InvitationTask after remove 03-09 23:43:18.454 28476-28963/org.briarproject I/AliceConnector﹕ org.briarproject.plugins.droidtooth.DroidtoothPlugin confirmation failed 03-09 23:43:18.457 28476-28963/org.briarproject I/Connector﹕ Closing connection
My test device had issues with bluetooth in the end. The icon in the status bar was going away and coming back while the phone was trying to establish a connection after scanning the code. Because of this, I couldn't add some people, but they could add each other.
Last week I spent some time testing Bluetooth connections between nine test devices.
Most of the experiments involved one hub device (Nexus 5X, Android 8.1.0) and up to eight contact devices (the usual pile of test phones). Wifi was turned off on all devices. After finishing the experiments I realised some of the contact devices might have had access to mobile data, but the hub didn't, so it wouldn't have affected most of the results.
I tested adding contacts to the hub and sharing a forum. In some of the experiments I also added contacts between the contact devices.
Summary of results:
BT connection issues start to appear when five or more contacts are added to the hub
It's sometimes possible to add seven contacts to the hub, but never eight
This matches the BT piconet limit (one master and seven slaves)
When the limit's reached, signing out on one of the contact devices (and turning off its BT) sometimes allows a new contact to be added, but not always
The limit seems to be enforced locally (on the Nexus 5X at least) - when the limit's reached, new connection attempts fail in a few milliseconds, as opposed to a few seconds before reaching the limit
More than eight devices can (sometimes) be connected in a mesh, but existing connections start to fail when there are too many devices or connections
Disabling and re-enabling BT sometimes helps with connection issues
When Briar crashes (e.g. killed by the power manager), contacts don't always detect that the connection has been lost - it may still be counted towards the connection limit on their end
Avoid making BT connections if we have a better option. For example, prefer LAN to BT when adding contacts, and don't poll for BT connections to contacts who are already connected via LAN
Keep some capacity free for adding contacts. Set a limit on the number of BT connections - say five. When the number of open connections reaches the limit, don't poll for contact connections, accept incoming contact connections, or convert key exchange connections into contact connections. This will allow us to keep adding contacts, but we'll only be able to sync with the first few contacts unless another transport is available
Close idle BT connections to free up capacity. This would require significant backend changes (don't poll unless we have something to send) and UX changes (online/offline states would have to be replaced by active/idle)
When we want to add a contact and the number of open BT connections is above some limit - say five - close connections in the order they were opened until we're down to the limit. Don't poll for contact connections or accept incoming contact connections while adding a contact, but do allow key exchange connections to be converted into contact connections.
If we add a lot of contacts in quick succession, this will have the effect of keeping the latest five connections, which may be a better experience than keeping the first five connections.
The approach above improves the situation on the Nexus 5X, allowing nine contacts (which is as many as I could test) to be added at once, with the five latest connections remaining open.
But other devices seem to have lower limits. The Moto E3 doesn't seem to be able to keep more than three connections open. Sometimes it's possible to open a fourth, but this causes all the existing connections to fail.
While working on this I found some bugs related to #283 (closed) that cause unused Bluetooth connections to be left open. But even with those bugs fixed, the Moto E3 can't add more than three contacts at once.
Next week I'll look at a new approach: instead of guessing how many connections we can handle, track the maximum number of simultaneous connections since startup. If we're at the maximum and opening a new connection fails, close the oldest connection.