Poll for connections in series, with a delay between attempts.

The delay reduces interference between Bluetooth and wifi.
parent 0db14bd9
Pipeline #4361 passed with stage
in 9 minutes and 8 seconds
......@@ -31,6 +31,7 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger;
import javax.annotation.Nullable;
......@@ -78,11 +79,12 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
AndroidBluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
SecureRandom secureRandom, AndroidExecutor androidExecutor,
Context appContext, Clock clock, Backoff backoff,
PluginCallback callback, int maxLatency, int maxIdleTime) {
super(connectionLimiter, timeoutMonitor, ioExecutor, secureRandom,
backoff, callback, maxLatency, maxIdleTime);
ScheduledExecutorService scheduler, SecureRandom secureRandom,
AndroidExecutor androidExecutor, Context appContext, Clock clock,
Backoff backoff, PluginCallback callback, int maxLatency,
int maxIdleTime) {
super(connectionLimiter, timeoutMonitor, ioExecutor, scheduler,
secureRandom, backoff, callback, maxLatency, maxIdleTime);
this.androidExecutor = androidExecutor;
this.appContext = appContext;
this.clock = clock;
......
......@@ -16,6 +16,7 @@ import org.briarproject.bramble.api.system.Clock;
import java.security.SecureRandom;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import javax.annotation.concurrent.Immutable;
......@@ -32,6 +33,7 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;
private final AndroidExecutor androidExecutor;
private final Context appContext;
private final SecureRandom secureRandom;
......@@ -41,10 +43,12 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
private final BackoffFactory backoffFactory;
public AndroidBluetoothPluginFactory(Executor ioExecutor,
AndroidExecutor androidExecutor, Context appContext,
SecureRandom secureRandom, EventBus eventBus, Clock clock,
TimeoutMonitor timeoutMonitor, BackoffFactory backoffFactory) {
ScheduledExecutorService scheduler, AndroidExecutor androidExecutor,
Context appContext, SecureRandom secureRandom, EventBus eventBus,
Clock clock, TimeoutMonitor timeoutMonitor,
BackoffFactory backoffFactory) {
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.androidExecutor = androidExecutor;
this.appContext = appContext;
this.secureRandom = secureRandom;
......@@ -71,8 +75,8 @@ public class AndroidBluetoothPluginFactory implements DuplexPluginFactory {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
AndroidBluetoothPlugin plugin = new AndroidBluetoothPlugin(
connectionLimiter, timeoutMonitor, ioExecutor, secureRandom,
androidExecutor, appContext, clock, backoff,
connectionLimiter, timeoutMonitor, ioExecutor, scheduler,
secureRandom, androidExecutor, appContext, clock, backoff,
callback, MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin);
return plugin;
......
......@@ -31,13 +31,17 @@ import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Collection;
import java.util.LinkedList;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
......@@ -60,10 +64,18 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
private static final Logger LOG =
getLogger(BluetoothPlugin.class.getName());
/**
* The delay between connection attempts when polling. This reduces
* interference between Bluetooth and wifi.
*/
private static final long CONNECTION_ATTEMPT_INTERVAL_MS =
SECONDS.toMillis(5);
final BluetoothConnectionLimiter connectionLimiter;
final TimeoutMonitor timeoutMonitor;
private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;
private final SecureRandom secureRandom;
private final Backoff backoff;
private final PluginCallback callback;
......@@ -108,11 +120,13 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
BluetoothPlugin(BluetoothConnectionLimiter connectionLimiter,
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
SecureRandom secureRandom, Backoff backoff,
PluginCallback callback, int maxLatency, int maxIdleTime) {
ScheduledExecutorService scheduler, SecureRandom secureRandom,
Backoff backoff, PluginCallback callback, int maxLatency,
int maxIdleTime) {
this.connectionLimiter = connectionLimiter;
this.timeoutMonitor = timeoutMonitor;
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.secureRandom = secureRandom;
this.backoff = backoff;
this.callback = callback;
......@@ -268,21 +282,31 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
properties) {
if (!isRunning() || !shouldAllowContactConnections()) return;
backoff.increment();
for (Pair<TransportProperties, ConnectionHandler> p : properties) {
connect(p.getFirst(), p.getSecond());
LinkedList<Pair<TransportProperties, ConnectionHandler>> connectable =
new LinkedList<>();
for (Pair<TransportProperties, ConnectionHandler> pair : properties) {
TransportProperties p = pair.getFirst();
if (isNullOrEmpty(p.get(PROP_ADDRESS))) continue;
if (isNullOrEmpty(p.get(PROP_UUID))) continue;
connectable.add(pair);
}
if (!connectable.isEmpty()) poll(connectable);
}
private void connect(TransportProperties p, ConnectionHandler h) {
String address = p.get(PROP_ADDRESS);
if (isNullOrEmpty(address)) return;
String uuid = p.get(PROP_UUID);
if (isNullOrEmpty(uuid)) return;
private void poll(LinkedList<Pair<TransportProperties, ConnectionHandler>>
connectable) {
ioExecutor.execute(() -> {
DuplexTransportConnection d = createConnection(p);
if (!isRunning() || !shouldAllowContactConnections()) return;
Pair<TransportProperties, ConnectionHandler> pair =
connectable.removeFirst();
DuplexTransportConnection d = createConnection(pair.getFirst());
if (d != null) {
backoff.reset();
h.handleConnection(d);
pair.getSecond().handleConnection(d);
}
if (!connectable.isEmpty()) {
scheduler.schedule(() -> poll(connectable),
CONNECTION_ATTEMPT_INTERVAL_MS, MILLISECONDS);
}
});
}
......
......@@ -10,6 +10,7 @@ import org.briarproject.bramble.api.plugin.PluginConfig;
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import org.briarproject.bramble.api.plugin.simplex.SimplexPluginFactory;
import org.briarproject.bramble.api.reliability.ReliabilityLayerFactory;
import org.briarproject.bramble.api.system.Scheduler;
import org.briarproject.bramble.plugin.bluetooth.JavaBluetoothPluginFactory;
import org.briarproject.bramble.plugin.modem.ModemPluginFactory;
import org.briarproject.bramble.plugin.tcp.LanTcpPluginFactory;
......@@ -18,6 +19,7 @@ import org.briarproject.bramble.plugin.tcp.WanTcpPluginFactory;
import java.security.SecureRandom;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import dagger.Module;
import dagger.Provides;
......@@ -30,12 +32,14 @@ public class DesktopPluginModule extends PluginModule {
@Provides
PluginConfig getPluginConfig(@IoExecutor Executor ioExecutor,
@Scheduler ScheduledExecutorService scheduler,
SecureRandom random, BackoffFactory backoffFactory,
ReliabilityLayerFactory reliabilityFactory,
ShutdownManager shutdownManager, EventBus eventBus,
TimeoutMonitor timeoutMonitor) {
DuplexPluginFactory bluetooth = new JavaBluetoothPluginFactory(
ioExecutor, random, eventBus, timeoutMonitor, backoffFactory);
ioExecutor, scheduler, random, eventBus, timeoutMonitor,
backoffFactory);
DuplexPluginFactory modem = new ModemPluginFactory(ioExecutor,
reliabilityFactory);
DuplexPluginFactory lan = new LanTcpPluginFactory(ioExecutor,
......
......@@ -10,6 +10,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.logging.Logger;
import javax.annotation.Nullable;
......@@ -36,10 +37,11 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
JavaBluetoothPlugin(BluetoothConnectionLimiter connectionManager,
TimeoutMonitor timeoutMonitor, Executor ioExecutor,
SecureRandom secureRandom, Backoff backoff,
PluginCallback callback, int maxLatency, int maxIdleTime) {
super(connectionManager, timeoutMonitor, ioExecutor, secureRandom,
backoff, callback, maxLatency, maxIdleTime);
ScheduledExecutorService scheduler, SecureRandom secureRandom,
Backoff backoff, PluginCallback callback, int maxLatency,
int maxIdleTime) {
super(connectionManager, timeoutMonitor, ioExecutor, scheduler,
secureRandom, backoff, callback, maxLatency, maxIdleTime);
}
@Override
......
......@@ -12,6 +12,7 @@ import org.briarproject.bramble.api.plugin.duplex.DuplexPluginFactory;
import java.security.SecureRandom;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import javax.annotation.concurrent.Immutable;
......@@ -28,15 +29,18 @@ public class JavaBluetoothPluginFactory implements DuplexPluginFactory {
private static final double BACKOFF_BASE = 1.2;
private final Executor ioExecutor;
private final ScheduledExecutorService scheduler;
private final SecureRandom secureRandom;
private final EventBus eventBus;
private final TimeoutMonitor timeoutMonitor;
private final BackoffFactory backoffFactory;
public JavaBluetoothPluginFactory(Executor ioExecutor,
SecureRandom secureRandom, EventBus eventBus,
TimeoutMonitor timeoutMonitor, BackoffFactory backoffFactory) {
ScheduledExecutorService scheduler, SecureRandom secureRandom,
EventBus eventBus, TimeoutMonitor timeoutMonitor,
BackoffFactory backoffFactory) {
this.ioExecutor = ioExecutor;
this.scheduler = scheduler;
this.secureRandom = secureRandom;
this.eventBus = eventBus;
this.timeoutMonitor = timeoutMonitor;
......@@ -60,8 +64,8 @@ public class JavaBluetoothPluginFactory implements DuplexPluginFactory {
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE);
JavaBluetoothPlugin plugin = new JavaBluetoothPlugin(connectionLimiter,
timeoutMonitor, ioExecutor, secureRandom, backoff, callback,
MAX_LATENCY, MAX_IDLE_TIME);
timeoutMonitor, ioExecutor, scheduler, secureRandom, backoff,
callback, MAX_LATENCY, MAX_IDLE_TIME);
eventBus.addListener(plugin);
return plugin;
}
......
......@@ -127,8 +127,8 @@ public class AppModule {
TimeoutMonitor timeoutMonitor) {
Context appContext = app.getApplicationContext();
DuplexPluginFactory bluetooth = new AndroidBluetoothPluginFactory(
ioExecutor, androidExecutor, appContext, random, eventBus,
clock, timeoutMonitor, backoffFactory);
ioExecutor, scheduler, androidExecutor, appContext, random,
eventBus, clock, timeoutMonitor, backoffFactory);
DuplexPluginFactory tor = new AndroidTorPluginFactory(ioExecutor,
scheduler, appContext, networkManager, locationUtils, eventBus,
torSocketFactory, backoffFactory, resourceProvider,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment