mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-22 07:28:16 +01:00
use insecure; get own mac addr
Try using both secure and insecure sockets. The latter appears to cause fewer problems on OS/device combos with crappy BT. It's only possible if I know the addr of the device I want to, so hack around that being secret by passing it on request.
This commit is contained in:
parent
dbfe8083ca
commit
776cc5703d
1 changed files with 184 additions and 60 deletions
|
@ -61,10 +61,12 @@ public class BTUtils {
|
||||||
private static final String TAG = BTUtils.class.getSimpleName();
|
private static final String TAG = BTUtils.class.getSimpleName();
|
||||||
private static final String BOGUS_MARSHMALLOW_ADDR = "02:00:00:00:00:00";
|
private static final String BOGUS_MARSHMALLOW_ADDR = "02:00:00:00:00:00";
|
||||||
private static final int MAX_PACKET_LEN = 4 * 1024;
|
private static final int MAX_PACKET_LEN = 4 * 1024;
|
||||||
private static int CONNECT_SLEEP_MS = 2500;
|
private static final int CONNECT_SLEEP_MS = 2500;
|
||||||
|
private static final String KEY_OWN_MAC = TAG + ":own_mac";
|
||||||
private static Set<ScanListener> sListeners = new HashSet<>();
|
private static Set<ScanListener> sListeners = new HashSet<>();
|
||||||
private static Map<String, PacketAccumulator> sSenders = new HashMap<>();
|
private static Map<String, PacketAccumulator> sSenders = new HashMap<>();
|
||||||
private static Map<String, String> s_namesToAddrs;
|
private static Map<String, String> s_namesToAddrs;
|
||||||
|
private static String sMyMacAddr = null;
|
||||||
|
|
||||||
private enum BTCmd {
|
private enum BTCmd {
|
||||||
BAD_PROTO,
|
BAD_PROTO,
|
||||||
|
@ -82,6 +84,8 @@ public class BTUtils {
|
||||||
MESG_GAMEGONE,
|
MESG_GAMEGONE,
|
||||||
_REMOVE_FOR, // unused
|
_REMOVE_FOR, // unused
|
||||||
INVITE_DUP_INVITE,
|
INVITE_DUP_INVITE,
|
||||||
|
MAC_ASK, // ask peer what my mac address is
|
||||||
|
MAC_REPLY, // reply to above
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ScanListener {
|
interface ScanListener {
|
||||||
|
@ -152,6 +156,7 @@ public class BTUtils {
|
||||||
Log.d( TAG, "init()" );
|
Log.d( TAG, "init()" );
|
||||||
sAppName = appName;
|
sAppName = appName;
|
||||||
sUUID = uuid;
|
sUUID = uuid;
|
||||||
|
loadOwnMac( context );
|
||||||
onResume( context );
|
onResume( context );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +170,8 @@ public class BTUtils {
|
||||||
Log.d( TAG, "onResume()" );
|
Log.d( TAG, "onResume()" );
|
||||||
// Should only run this in the background if we have BT games
|
// Should only run this in the background if we have BT games
|
||||||
// going. In the foreground we want to
|
// going. In the foreground we want to
|
||||||
ListenThread.getOrStart();
|
SecureListenThread.getOrStart();
|
||||||
|
InsecureListenThread.getOrStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onStop( Context context )
|
static void onStop( Context context )
|
||||||
|
@ -192,11 +198,7 @@ public class BTUtils {
|
||||||
String[] result = null;
|
String[] result = null;
|
||||||
BluetoothAdapter adapter = getAdapterIf();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
if ( null != adapter ) {
|
if ( null != adapter ) {
|
||||||
String addr = adapter.getAddress();
|
result = new String[] { adapter.getName(), sMyMacAddr };
|
||||||
if ( isBogusAddr( addr ) ) {
|
|
||||||
addr = null;
|
|
||||||
}
|
|
||||||
result = new String[] { adapter.getName(), addr };
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +216,8 @@ public class BTUtils {
|
||||||
|
|
||||||
private static void stopThreads()
|
private static void stopThreads()
|
||||||
{
|
{
|
||||||
ListenThread.stopSelf();
|
SecureListenThread.stopSelf();
|
||||||
|
InsecureListenThread.stopSelf();
|
||||||
ReadThread.stopSelf();
|
ReadThread.stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +230,17 @@ public class BTUtils {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void loadOwnMac( Context context )
|
||||||
|
{
|
||||||
|
sMyMacAddr = DBUtils.getStringFor( context, KEY_OWN_MAC, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void storeOwnMac( String macAddr )
|
||||||
|
{
|
||||||
|
Context context = getContext();
|
||||||
|
DBUtils.setStringFor( context, KEY_OWN_MAC, macAddr );
|
||||||
|
}
|
||||||
|
|
||||||
public static int sendPacket( Context context, byte[] buf, String msgID,
|
public static int sendPacket( Context context, byte[] buf, String msgID,
|
||||||
CommsAddrRec targetAddr, int gameID )
|
CommsAddrRec targetAddr, int gameID )
|
||||||
{
|
{
|
||||||
|
@ -587,7 +601,7 @@ public class BTUtils {
|
||||||
private BTHelper mHelper;
|
private BTHelper mHelper;
|
||||||
private boolean mPostOnResponse;
|
private boolean mPostOnResponse;
|
||||||
|
|
||||||
PacketAccumulator( String addr ) { this(addr, 20000); }
|
PacketAccumulator( String addr ) { this( addr, 20000 ); }
|
||||||
|
|
||||||
// Ping case -- used only once
|
// Ping case -- used only once
|
||||||
PacketAccumulator( String addr, int timeoutMS )
|
PacketAccumulator( String addr, int timeoutMS )
|
||||||
|
@ -603,6 +617,11 @@ public class BTUtils {
|
||||||
Assert.assertTrueNR( null != mAdapter );
|
Assert.assertTrueNR( null != mAdapter );
|
||||||
mHelper = new BTHelper( mName, mAddr );
|
mHelper = new BTHelper( mName, mAddr );
|
||||||
mPostOnResponse = true;
|
mPostOnResponse = true;
|
||||||
|
|
||||||
|
if ( null == sMyMacAddr ) {
|
||||||
|
addGetMac();
|
||||||
|
}
|
||||||
|
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,6 +714,15 @@ public class BTUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addGetMac()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
append( BTCmd.MAC_ASK, new OutputPair() );
|
||||||
|
} catch ( IOException ioe ) {
|
||||||
|
Assert.failDbg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void append( BTCmd cmd, OutputPair op ) throws IOException
|
private void append( BTCmd cmd, OutputPair op ) throws IOException
|
||||||
{
|
{
|
||||||
append( cmd, 0, null, op );
|
append( cmd, 0, null, op );
|
||||||
|
@ -837,16 +865,15 @@ public class BTUtils {
|
||||||
BluetoothSocket socket = null;
|
BluetoothSocket socket = null;
|
||||||
try {
|
try {
|
||||||
Log.d( TAG, "trySend(): attempting to connect to %s", mName );
|
Log.d( TAG, "trySend(): attempting to connect to %s", mName );
|
||||||
socket = mAdapter.getRemoteDevice( getBTAddr() )
|
BluetoothDevice dev = mAdapter.getRemoteDevice( getBTAddr() );
|
||||||
.createRfcommSocketToServiceRecord( sUUID );
|
socket = connect( dev, mTimeoutMS );
|
||||||
DataOutputStream dos = connect( socket, mTimeoutMS );
|
if ( null == socket ) {
|
||||||
if ( null == dos ) {
|
|
||||||
setNoHost();
|
setNoHost();
|
||||||
updateStatusOut( false );
|
updateStatusOut( false );
|
||||||
} else {
|
} else {
|
||||||
Log.d( TAG, "PacketAccumulator.run(): connect(%s) => %s",
|
Log.d( TAG, "PacketAccumulator.run(): connect(%s) => %s",
|
||||||
mName, dos );
|
mName, socket );
|
||||||
nDone += writeAndCheck( socket, dos );
|
nDone += writeAndCheck( socket );
|
||||||
updateStatusOut( true );
|
updateStatusOut( true );
|
||||||
if ( mPostOnResponse ) {
|
if ( mPostOnResponse ) {
|
||||||
callListeners( socket.getRemoteDevice() );
|
callListeners( socket.getRemoteDevice() );
|
||||||
|
@ -864,11 +891,12 @@ public class BTUtils {
|
||||||
return nDone;
|
return nDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int writeAndCheck( BluetoothSocket socket, DataOutputStream dos )
|
private int writeAndCheck( BluetoothSocket socket )
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
|
DataOutputStream dos = new DataOutputStream( socket.getOutputStream() );
|
||||||
Log.d( TAG, "%s.writeAndCheck() IN", this );
|
Log.d( TAG, "%s.writeAndCheck() IN", this );
|
||||||
Assert.assertNotNull( dos );
|
dos.writeByte( BT_PROTO );
|
||||||
|
|
||||||
List<MsgElem> localElems = new ArrayList<>();
|
List<MsgElem> localElems = new ArrayList<>();
|
||||||
try ( DeadlockWatch dw = new DeadlockWatch( this ) ) {
|
try ( DeadlockWatch dw = new DeadlockWatch( this ) ) {
|
||||||
|
@ -986,6 +1014,16 @@ public class BTUtils {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MAC_ASK:
|
||||||
|
if ( BTCmd.MAC_REPLY == reply ) {
|
||||||
|
String mac = inStream.readUTF();
|
||||||
|
Assert.assertTrueNR( null == sMyMacAddr || sMyMacAddr.equals(mac) );
|
||||||
|
sMyMacAddr = mac;
|
||||||
|
Log.d( TAG, "got %s as my mac addr", sMyMacAddr );
|
||||||
|
storeOwnMac( sMyMacAddr );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.e( TAG, "handleReply(cmd=%s) case not handled", cmd );
|
Log.e( TAG, "handleReply(cmd=%s) case not handled", cmd );
|
||||||
Assert.failDbg(); // fired
|
Assert.failDbg(); // fired
|
||||||
|
@ -996,9 +1034,9 @@ public class BTUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataOutputStream connect( BluetoothSocket socket, int timeout )
|
private BluetoothSocket connect( BluetoothDevice remote, int timeout )
|
||||||
{
|
{
|
||||||
BluetoothDevice remote = socket.getRemoteDevice();
|
BluetoothSocket socket = null;
|
||||||
String name = remote.getName();
|
String name = remote.getName();
|
||||||
String addr = remote.getAddress();
|
String addr = remote.getAddress();
|
||||||
Log.w( TAG, "connect(%s/%s, timeout=%d) starting", name, addr, timeout );
|
Log.w( TAG, "connect(%s/%s, timeout=%d) starting", name, addr, timeout );
|
||||||
|
@ -1006,22 +1044,21 @@ public class BTUtils {
|
||||||
// Docs say always call cancelDiscovery before trying to connect
|
// Docs say always call cancelDiscovery before trying to connect
|
||||||
mAdapter.cancelDiscovery();
|
mAdapter.cancelDiscovery();
|
||||||
|
|
||||||
DataOutputStream dos = null;
|
|
||||||
|
|
||||||
// Retry for some time. Some devices take a long time to generate and
|
// Retry for some time. Some devices take a long time to generate and
|
||||||
// broadcast ACL conn ACTION
|
// broadcast ACL conn ACTION
|
||||||
int nTries = 0;
|
int nTries = 0;
|
||||||
for ( long end = timeout + System.currentTimeMillis(); ; ) {
|
for ( long end = timeout + System.currentTimeMillis(); ; ) {
|
||||||
try {
|
try {
|
||||||
// Log.d( TAG, "trying connect(%s/%s) (check accept() logs)", name, addr );
|
boolean useInsecure = 0 == nTries++ % 2;
|
||||||
++nTries;
|
socket = useInsecure
|
||||||
|
? remote.createInsecureRfcommSocketToServiceRecord( sUUID )
|
||||||
|
: remote.createRfcommSocketToServiceRecord( sUUID );
|
||||||
socket.connect();
|
socket.connect();
|
||||||
Log.i( TAG, "connect(%s/%s) succeeded after %d tries",
|
Log.i( TAG, "connect(%s/%s/useInsecure=%b) succeeded after %d tries",
|
||||||
name, addr, nTries );
|
name, addr, useInsecure, nTries );
|
||||||
dos = new DataOutputStream( socket.getOutputStream() );
|
|
||||||
dos.writeByte( BT_PROTO );
|
|
||||||
break; // success!!!
|
break; // success!!!
|
||||||
} catch (IOException|SecurityException ioe) {
|
} catch (IOException|SecurityException ioe) {
|
||||||
|
socket = null;
|
||||||
// Log.d( TAG, "connect(): %s", ioe.getMessage() );
|
// Log.d( TAG, "connect(): %s", ioe.getMessage() );
|
||||||
long msLeft = end - System.currentTimeMillis();
|
long msLeft = end - System.currentTimeMillis();
|
||||||
if ( msLeft <= 0 ) {
|
if ( msLeft <= 0 ) {
|
||||||
|
@ -1034,8 +1071,8 @@ public class BTUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.e( TAG, "connect(%s/%s) => %s", name, addr, dos );
|
Log.e( TAG, "connect(%s/%s) => %s", name, addr, socket );
|
||||||
return dos;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setNoHost()
|
private void setNoHost()
|
||||||
|
@ -1076,26 +1113,27 @@ public class BTUtils {
|
||||||
}
|
}
|
||||||
} // class PacketAccumulator
|
} // class PacketAccumulator
|
||||||
|
|
||||||
private static class ListenThread extends Thread {
|
private abstract static class ListenThread extends Thread {
|
||||||
private static AtomicReference<Thread> sInstance = new AtomicReference<>();
|
|
||||||
private BluetoothAdapter mAdapter;
|
private BluetoothAdapter mAdapter;
|
||||||
private BluetoothServerSocket mServerSocket;
|
private BluetoothServerSocket mServerSocket;
|
||||||
|
|
||||||
private ListenThread( BluetoothAdapter adapter )
|
private ListenThread( BluetoothAdapter adapter )
|
||||||
{
|
{
|
||||||
mAdapter = adapter;
|
mAdapter = adapter;
|
||||||
sInstance.set( this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract BluetoothServerSocket openListener( BluetoothAdapter adapter )
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
Log.d( TAG, "ListenThread: %s.run() starting", this );
|
String simpleName = getClass().getSimpleName();
|
||||||
|
Log.d( TAG, "%s.run() starting", simpleName );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Assert.assertTrueNR( null != sAppName && null != sUUID );
|
Assert.assertTrueNR( null != sAppName && null != sUUID );
|
||||||
mServerSocket = mAdapter
|
mServerSocket = openListener( mAdapter );
|
||||||
.listenUsingRfcommWithServiceRecord( sAppName, sUUID );
|
|
||||||
} catch ( IOException ioe ) {
|
} catch ( IOException ioe ) {
|
||||||
Log.ex( TAG, ioe );
|
Log.ex( TAG, ioe );
|
||||||
mServerSocket = null;
|
mServerSocket = null;
|
||||||
|
@ -1108,11 +1146,12 @@ public class BTUtils {
|
||||||
mServerSocket = null;
|
mServerSocket = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( null != mServerSocket && this == sInstance.get() ) {
|
AtomicReference<Thread> wrapper = getWrapper();
|
||||||
Log.d( TAG, "%s.run(): calling accept()", this );
|
while ( null != mServerSocket && this == wrapper.get() ) {
|
||||||
|
Log.d( TAG, "%s.run(): calling accept()", simpleName );
|
||||||
try {
|
try {
|
||||||
BluetoothSocket socket = mServerSocket.accept(); // blocks
|
BluetoothSocket socket = mServerSocket.accept(); // blocks
|
||||||
Log.d( TAG, "%s.run(): accept() returned", this );
|
Log.d( TAG, "%s.run(): accept() returned", simpleName );
|
||||||
ReadThread.handle( socket );
|
ReadThread.handle( socket );
|
||||||
} catch ( IOException ioe ) {
|
} catch ( IOException ioe ) {
|
||||||
Log.ex( TAG, ioe );
|
Log.ex( TAG, ioe );
|
||||||
|
@ -1120,46 +1159,121 @@ public class BTUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clearInstance( sInstance, this );
|
clearInstance( wrapper, this );
|
||||||
Log.d( TAG, "ListenThread: %s.run() exiting", this );
|
Log.d( TAG, "%s.run() exiting", simpleName );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ListenThread getOrStart()
|
void closeListener()
|
||||||
|
{
|
||||||
|
BluetoothServerSocket serverSocket = mServerSocket;
|
||||||
|
if ( null != serverSocket ) {
|
||||||
|
try {
|
||||||
|
serverSocket.close();
|
||||||
|
} catch ( IOException ioe ) {
|
||||||
|
Log.ex( TAG, ioe );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract AtomicReference<Thread> getWrapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SecureListenThread extends ListenThread {
|
||||||
|
private static AtomicReference<Thread> sInstance = new AtomicReference<>();
|
||||||
|
|
||||||
|
private SecureListenThread( BluetoothAdapter adapter )
|
||||||
|
{
|
||||||
|
super( adapter );
|
||||||
|
Assert.assertTrueNR( null == sInstance.get() );
|
||||||
|
sInstance.set( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BluetoothServerSocket openListener( BluetoothAdapter adapter )
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return adapter.listenUsingRfcommWithServiceRecord( sAppName, sUUID );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
AtomicReference<Thread> getWrapper() { return sInstance; }
|
||||||
|
|
||||||
|
private static void getOrStart()
|
||||||
{
|
{
|
||||||
ListenThread result = null;
|
|
||||||
BluetoothAdapter adapter = getAdapterIf();
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
if ( null != adapter ) {
|
if ( null != adapter ) {
|
||||||
synchronized ( sInstance ) {
|
synchronized ( sInstance ) {
|
||||||
result = (ListenThread)sInstance.get();
|
SecureListenThread thread = (SecureListenThread)sInstance.get();
|
||||||
if ( null == result ) {
|
if ( null == thread ) {
|
||||||
result = new ListenThread( adapter );
|
thread = new SecureListenThread( adapter );
|
||||||
Assert.assertTrueNR( result == sInstance.get() );
|
Assert.assertTrueNR( thread == sInstance.get() );
|
||||||
result.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void stopSelf()
|
private static void stopSelf()
|
||||||
{
|
{
|
||||||
synchronized ( sInstance ) {
|
synchronized ( sInstance ) {
|
||||||
ListenThread self = (ListenThread)sInstance.get();
|
SecureListenThread self = (SecureListenThread)sInstance.get();
|
||||||
Log.d( TAG, "ListenThread.stopSelf(): self: %s", self );
|
Log.d( TAG, "SecureListenThread.stopSelf(): self: %s", self );
|
||||||
if ( null != self ) {
|
if ( null != self ) {
|
||||||
sInstance.set( null );
|
sInstance.set( null );
|
||||||
|
self.closeListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BluetoothServerSocket serverSocket = self.mServerSocket;
|
private static class InsecureListenThread extends ListenThread {
|
||||||
if ( null != serverSocket ) {
|
private static AtomicReference<Thread> sInstance = new AtomicReference<>();
|
||||||
try {
|
|
||||||
serverSocket.close();
|
private InsecureListenThread( BluetoothAdapter adapter )
|
||||||
} catch ( IOException ioe ) {
|
{
|
||||||
Log.ex( TAG, ioe );
|
super( adapter );
|
||||||
}
|
Assert.assertTrueNR( null == sInstance.get() );
|
||||||
|
sInstance.set( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
BluetoothServerSocket openListener( BluetoothAdapter adapter )
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return adapter
|
||||||
|
.listenUsingInsecureRfcommWithServiceRecord( sAppName, sUUID );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
AtomicReference<Thread> getWrapper() { return sInstance; }
|
||||||
|
|
||||||
|
private static void getOrStart()
|
||||||
|
{
|
||||||
|
BluetoothAdapter adapter = getAdapterIf();
|
||||||
|
if ( null != adapter ) {
|
||||||
|
synchronized ( sInstance ) {
|
||||||
|
InsecureListenThread thread = (InsecureListenThread)sInstance.get();
|
||||||
|
if ( null == thread ) {
|
||||||
|
thread = new InsecureListenThread( adapter );
|
||||||
|
Assert.assertTrueNR( thread == sInstance.get() );
|
||||||
|
thread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void stopSelf()
|
||||||
|
{
|
||||||
|
synchronized ( sInstance ) {
|
||||||
|
InsecureListenThread self = (InsecureListenThread)sInstance.get();
|
||||||
|
Log.d( TAG, "InsecureListenThread.stopSelf(): self: %s", self );
|
||||||
|
if ( null != self ) {
|
||||||
|
sInstance.set( null );
|
||||||
|
self.closeListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ReadThread extends Thread {
|
private static class ReadThread extends Thread {
|
||||||
|
@ -1169,9 +1283,8 @@ public class BTUtils {
|
||||||
|
|
||||||
static void handle( BluetoothSocket incoming )
|
static void handle( BluetoothSocket incoming )
|
||||||
{
|
{
|
||||||
Log.d( TAG, "read(%s)", incoming );
|
Log.d( TAG, "read(from=%s)", incoming.getRemoteDevice().getName() );
|
||||||
ReadThread self = getOrStart();
|
getOrStart().enqueue( incoming );
|
||||||
self.enqueue( incoming );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReadThread()
|
private ReadThread()
|
||||||
|
@ -1280,6 +1393,9 @@ public class BTUtils {
|
||||||
gameID = dis.readInt();
|
gameID = dis.readInt();
|
||||||
receiveGameGone( gameID, socket );
|
receiveGameGone( gameID, socket );
|
||||||
break;
|
break;
|
||||||
|
case MAC_ASK:
|
||||||
|
receiveMacAsk( socket );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Assert.failDbg();
|
Assert.failDbg();
|
||||||
break;
|
break;
|
||||||
|
@ -1355,6 +1471,14 @@ public class BTUtils {
|
||||||
writeBack( socket, BTCmd.MESG_ACCPT );
|
writeBack( socket, BTCmd.MESG_ACCPT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void receiveMacAsk( BluetoothSocket socket ) throws IOException
|
||||||
|
{
|
||||||
|
DataOutputStream os = new DataOutputStream( socket.getOutputStream() );
|
||||||
|
os.writeByte( BTCmd.MAC_REPLY.ordinal() );
|
||||||
|
String addr = socket.getRemoteDevice().getAddress();
|
||||||
|
os.writeUTF( addr );
|
||||||
|
}
|
||||||
|
|
||||||
private void enqueue( BluetoothSocket socket )
|
private void enqueue( BluetoothSocket socket )
|
||||||
{
|
{
|
||||||
mQueue.add( socket );
|
mQueue.add( socket );
|
||||||
|
|
Loading…
Reference in a new issue