Skip to content
Snippets Groups Projects
Commit 18cd0c5f authored by akwizgran's avatar akwizgran
Browse files

Android Bluetooth sockets will fail to connect during discovery.

parent 3355851e
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,7 @@ import static java.util.logging.Level.WARNING; ...@@ -11,6 +11,7 @@ import static java.util.logging.Level.WARNING;
import java.io.IOException; import java.io.IOException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
...@@ -247,20 +248,23 @@ class DroidtoothPlugin implements DuplexPlugin { ...@@ -247,20 +248,23 @@ class DroidtoothPlugin implements DuplexPlugin {
LOG.warning("Invalid address " + address); LOG.warning("Invalid address " + address);
return null; return null;
} }
BluetoothDevice d = adapter.getRemoteDevice(address);
// Validate the UUID // Validate the UUID
UUID u; UUID u;
try { try {
u = UUID.fromString(uuid); u = UUID.fromString(uuid);
} catch(IllegalArgumentException e) { } catch(IllegalArgumentException e) {
if(LOG.isLoggable(WARNING)) if(LOG.isLoggable(WARNING)) LOG.warning("Invalid UUID " + uuid);
LOG.warning("Invalid UUID " + uuid);
return null; return null;
} }
// Try to connect // Try to connect
BluetoothDevice d = adapter.getRemoteDevice(address);
try { try {
if(LOG.isLoggable(INFO))
LOG.info("Creating socket for " + address);
BluetoothSocket s = InsecureBluetooth.createSocket(d, u); BluetoothSocket s = InsecureBluetooth.createSocket(d, u);
if(LOG.isLoggable(INFO)) LOG.info("Connecting");
s.connect(); s.connect();
if(LOG.isLoggable(INFO)) LOG.info("Connected");
return new DroidtoothTransportConnection(s); return new DroidtoothTransportConnection(s);
} catch(IOException e) { } catch(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
...@@ -324,6 +328,7 @@ class DroidtoothPlugin implements DuplexPlugin { ...@@ -324,6 +328,7 @@ class DroidtoothPlugin implements DuplexPlugin {
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
return null; return null;
} }
if(LOG.isLoggable(INFO)) LOG.info("Listening");
// Return the first connection received by the socket, if any // Return the first connection received by the socket, if any
try { try {
return new DroidtoothTransportConnection(ss.accept((int) timeout)); return new DroidtoothTransportConnection(ss.accept((int) timeout));
...@@ -369,6 +374,7 @@ class DroidtoothPlugin implements DuplexPlugin { ...@@ -369,6 +374,7 @@ class DroidtoothPlugin implements DuplexPlugin {
private class DiscoveryReceiver extends BroadcastReceiver { private class DiscoveryReceiver extends BroadcastReceiver {
private final CountDownLatch finished = new CountDownLatch(1); private final CountDownLatch finished = new CountDownLatch(1);
private final Collection<String> addresses = new ArrayList<String>();
private final String uuid; private final String uuid;
private volatile DuplexTransportConnection connection = null; private volatile DuplexTransportConnection connection = null;
...@@ -378,13 +384,22 @@ class DroidtoothPlugin implements DuplexPlugin { ...@@ -378,13 +384,22 @@ class DroidtoothPlugin implements DuplexPlugin {
} }
@Override @Override
public void onReceive(final Context ctx, Intent intent) { public void onReceive(Context ctx, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
if(action.equals(DISCOVERY_FINISHED)) { if(action.equals(DISCOVERY_FINISHED)) {
finish(ctx); if(LOG.isLoggable(INFO)) LOG.info("Discovery finished");
ctx.unregisterReceiver(this);
connectToDiscoveredDevices();
} else if(action.equals(FOUND)) { } else if(action.equals(FOUND)) {
BluetoothDevice d = intent.getParcelableExtra(EXTRA_DEVICE); BluetoothDevice d = intent.getParcelableExtra(EXTRA_DEVICE);
final String address = d.getAddress(); String address = d.getAddress();
if(LOG.isLoggable(INFO)) LOG.info("Discovered " + address);
addresses.add(address);
}
}
private void connectToDiscoveredDevices() {
for(final String address : addresses) {
pluginExecutor.execute(new Runnable() { pluginExecutor.execute(new Runnable() {
public void run() { public void run() {
synchronized(DroidtoothPlugin.this) { synchronized(DroidtoothPlugin.this) {
...@@ -393,18 +408,13 @@ class DroidtoothPlugin implements DuplexPlugin { ...@@ -393,18 +408,13 @@ class DroidtoothPlugin implements DuplexPlugin {
DuplexTransportConnection conn = connect(address, uuid); DuplexTransportConnection conn = connect(address, uuid);
if(conn != null) { if(conn != null) {
connection = conn; connection = conn;
finish(ctx); finished.countDown();
} }
} }
}); });
} }
} }
private void finish(Context ctx) {
ctx.unregisterReceiver(this);
finished.countDown();
}
private DuplexTransportConnection waitForConnection(long timeout) private DuplexTransportConnection waitForConnection(long timeout)
throws InterruptedException { throws InterruptedException {
finished.await(timeout, MILLISECONDS); finished.await(timeout, MILLISECONDS);
......
...@@ -116,9 +116,7 @@ class InsecureBluetooth { ...@@ -116,9 +116,7 @@ class InsecureBluetooth {
int errno = (Integer) result; int errno = (Integer) result;
if(errno != 0) { if(errno != 0) {
socket.close(); socket.close();
Method throwErrnoNative = mSocket.getClass().getMethod( throw new IOException("Can't bind: errno " + errno);
"throwErrnoNative", int.class);
throwErrnoNative.invoke(mSocket, errno);
} }
return socket; return socket;
} catch(NoSuchMethodException e) { } catch(NoSuchMethodException e) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment