diff --git a/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java b/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java index 28223c1109f9f7e250aac2439d24c706d4d4a811..f93708e21c0297f2925b2343235fa1fd6ab23945 100644 --- a/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java +++ b/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java @@ -130,7 +130,7 @@ class DroidtoothPlugin implements DuplexPlugin { // Bind a server socket to accept connections from contacts BluetoothServerSocket ss; try { - ss = InsecureBluetooth.listen(adapter, "RFCOMM", getUuid(), false); + ss = InsecureBluetooth.listen(adapter, "RFCOMM", getUuid()); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); return; @@ -262,7 +262,7 @@ class DroidtoothPlugin implements DuplexPlugin { } // Try to connect try { - BluetoothSocket s = InsecureBluetooth.createSocket(d, u, false); + BluetoothSocket s = InsecureBluetooth.createSocket(d, u); return new DroidtoothTransportConnection(s); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); @@ -323,7 +323,7 @@ class DroidtoothPlugin implements DuplexPlugin { // Bind a new server socket to accept the invitation connection final BluetoothServerSocket ss; try { - ss = InsecureBluetooth.listen(adapter, "RFCOMM", uuid, false); + ss = InsecureBluetooth.listen(adapter, "RFCOMM", uuid); } catch(IOException e) { if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); return null; diff --git a/src/net/sf/briar/plugins/droidtooth/InsecureBluetooth.java b/src/net/sf/briar/plugins/droidtooth/InsecureBluetooth.java index fadde3fdb8d3429bfa1132d17ce28e9a4501f3fa..05b7a31ab7ecd24951423d21ab5050c1a758c7b1 100644 --- a/src/net/sf/briar/plugins/droidtooth/InsecureBluetooth.java +++ b/src/net/sf/briar/plugins/droidtooth/InsecureBluetooth.java @@ -7,11 +7,13 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.UUID; +import android.annotation.SuppressLint; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.ParcelUuid; @@ -19,8 +21,13 @@ import android.os.ParcelUuid; // Based on http://stanford.edu/~tpurtell/InsecureBluetooth.java by T.J. Purtell class InsecureBluetooth { + @SuppressLint("NewApi") static BluetoothServerSocket listen(BluetoothAdapter adapter, String name, - UUID uuid, boolean encrypt) throws IOException { + UUID uuid) throws IOException { + if(Build.VERSION.SDK_INT >= 10) { + return adapter.listenUsingInsecureRfcommWithServiceRecord(name, + uuid); + } try { String className = BluetoothAdapter.class.getName() + ".RfcommChannelPicker"; @@ -43,19 +50,10 @@ class InsecureBluetooth { "nextChannel", new Class[0]); nextChannel.setAccessible(true); BluetoothServerSocket socket = null; - int channel; - while(true) { - channel = (Integer) nextChannel.invoke(channelPicker, - new Object[0]); - if(channel == -1) - throw new IOException("No available channels"); - try { - socket = listen(channel, encrypt); - break; - } catch(InUseException e) { - continue; - } - } + int channel = (Integer) nextChannel.invoke(channelPicker, + new Object[0]); + if(channel == -1) throw new IOException("No available channels"); + socket = listen(channel); Field f = adapter.getClass().getDeclaredField("mService"); f.setAccessible(true); Object mService = f.get(adapter); @@ -97,8 +95,7 @@ class InsecureBluetooth { } } - private static BluetoothServerSocket listen(int port, boolean encrypt, - boolean reuse) throws IOException, InUseException { + private static BluetoothServerSocket listen(int port) throws IOException { BluetoothServerSocket socket = null; try { Constructor<BluetoothServerSocket> constructor = @@ -110,21 +107,16 @@ class InsecureBluetooth { Field f = BluetoothSocket.class.getDeclaredField("TYPE_RFCOMM"); f.setAccessible(true); int rfcommType = (Integer) f.get(null); - Field f1 = BluetoothSocket.class.getDeclaredField("EADDRINUSE"); + socket = constructor.newInstance(rfcommType, false, false, port); + Field f1 = socket.getClass().getDeclaredField("mSocket"); f1.setAccessible(true); - int eAddrInUse = (Integer) f1.get(null); - socket = constructor.newInstance(rfcommType, false, encrypt, port); - Field f2 = socket.getClass().getDeclaredField("mSocket"); - f2.setAccessible(true); - Object mSocket = f2.get(socket); + Object mSocket = f1.get(socket); Method bindListen = mSocket.getClass().getDeclaredMethod( "bindListen", new Class[0]); bindListen.setAccessible(true); Object result = bindListen.invoke(mSocket, new Object[0]); int errno = (Integer) result; - if(reuse && errno == eAddrInUse) { - throw new InUseException(); - } else if(errno != 0) { + if(errno != 0) { try { socket.close(); } catch(IOException ignored) {} @@ -150,13 +142,12 @@ class InsecureBluetooth { } } - static BluetoothServerSocket listen(int port, boolean encrypt) + @SuppressLint("NewApi") + static BluetoothSocket createSocket(BluetoothDevice device, UUID uuid) throws IOException { - return listen(port, encrypt, false); - } - - private static BluetoothSocket createSocket(BluetoothDevice device, - int port, UUID uuid, boolean encrypt) throws IOException { + if(Build.VERSION.SDK_INT >= 10) { + return device.createInsecureRfcommSocketToServiceRecord(uuid); + } try { BluetoothSocket socket = null; Constructor<BluetoothSocket> constructor = @@ -165,13 +156,12 @@ class InsecureBluetooth { BluetoothDevice.class, int.class, ParcelUuid.class); if(constructor == null) throw new IOException("Can't find socket constructor"); - constructor.setAccessible(true); Field f = BluetoothSocket.class.getDeclaredField("TYPE_RFCOMM"); f.setAccessible(true); int typeRfcomm = (Integer) f.get(null); socket = constructor.newInstance(typeRfcomm, -1, false, true, - device, port, uuid != null ? new ParcelUuid(uuid) : null); + device, -1, uuid != null ? new ParcelUuid(uuid) : null); return socket; } catch(NoSuchMethodException e) { throw new IOException(e.toString()); @@ -189,19 +179,4 @@ class InsecureBluetooth { } } } - - static BluetoothSocket createSocket(BluetoothDevice device, UUID uuid, - boolean encrypt) throws IOException { - return createSocket(device, -1, uuid, encrypt); - } - - static BluetoothSocket createSocket(BluetoothDevice device, int port, - boolean encrypt) throws IOException { - return createSocket(device, port, null, encrypt); - } - - private static class InUseException extends RuntimeException { - - private static final long serialVersionUID = -5983642322821496023L; - } }