From 0d04fd138d59348093b5d67cca296c98ba76241b Mon Sep 17 00:00:00 2001 From: Eric House Date: Sun, 21 Sep 2014 13:06:12 -0700 Subject: [PATCH] ping remote BT hosts on game open and on radio on in order to update the status of the connection arrows. --- .../org/eehouse/android/xw4/BTService.java | 98 ++++++++++++++----- .../eehouse/android/xw4/BoardDelegate.java | 40 +++++++- .../eehouse/android/xw4/CommsTransport.java | 21 +--- 3 files changed, 113 insertions(+), 46 deletions(-) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTService.java index afbe2bb71..8262d3488 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BTService.java @@ -66,6 +66,7 @@ public class BTService extends XWService { private static final int CLEAR = 5; private static final int REMOVE = 6; private static final int NFCINVITE = 7; + private static final int PINGHOST = 8; private static final String CMD_STR = "CMD"; private static final String MSG_STR = "MSG"; @@ -128,6 +129,10 @@ public class BTService extends XWService { m_msg = buf; m_recipient = targetName; m_addr = targetAddr; m_gameID = gameID; } + public BTQueueElem( BTCmd cmd, String targetName ) { + this( cmd ); + m_recipient = targetName; + } public int incrFailCount() { return ++m_failCount; } public boolean failCountExceeded() { return m_failCount >= MAX_SEND_FAIL; } @@ -180,6 +185,14 @@ public class BTService extends XWService { context.startService( intent ); } + public static void pingHost( Context context, String hostName, String hostAddr ) + { + Intent intent = getIntentTo( context, PINGHOST ); + intent.putExtra( TARGET_STR, hostName ); + intent.putExtra( ADDR_STR, hostAddr ); + context.startService( intent ); + } + public static void inviteRemote( Context context, String hostName, int gameID, String initialName, int lang, String dict, int nPlayersT, @@ -296,6 +309,11 @@ public class BTService extends XWService { dict, nPlayersT, nPlayersH ) ); break; + case PINGHOST: + target = intent.getStringExtra( TARGET_STR ); + m_sender.add( new BTQueueElem( BTCmd.PING, target ) ); + break; + case NFCINVITE: gameID = intent.getIntExtra( GAMEID_STR, -1 ); lang = intent.getIntExtra( LANG_STR, -1 ); @@ -439,6 +457,7 @@ public class BTService extends XWService { os.flush(); socket.close(); + updateStatusOut( true ); } private void receiveInvitation( Context context, @@ -627,7 +646,11 @@ public class BTService extends XWService { switch( elem.m_cmd ) { case PING: - sendPings( MultiEvent.HOST_PONGED ); + if ( null == elem.m_recipient ) { + sendPings( MultiEvent.HOST_PONGED ); + } else { + sendPing( elem.m_recipient ); + } break; case SCAN: sendPings( null ); @@ -662,38 +685,61 @@ public class BTService extends XWService { if ( null != addrFor( name ) ) { continue; } - boolean success = false; - try { - DbgUtils.logf( "PingThread: got socket to device %s", - dev.getName() ); - BluetoothSocket socket = - dev.createRfcommSocketToServiceRecord( XWApp.getAppUUID() ); - if ( null != socket ) { - DataOutputStream os = connect( socket, BTCmd.PING ); - if ( null != os ) { - os.flush(); - Thread killer = killSocketIn( socket ); - DataInputStream is = - new DataInputStream( socket.getInputStream() ); - success = BTCmd.PONG == BTCmd.values()[is.readByte()]; - killer.interrupt(); - } - socket.close(); - } - } catch ( IOException ioe ) { - logIOE( ioe ); - } - - if ( success ) { - DbgUtils.logf( "got PONG from %s", dev.getName() ); + if ( sendPing( dev ) ) { addAddr( dev ); if ( null != event ) { sendResult( event, dev.getName() ); } } } - } // sendPings + } + + private boolean sendPing( BluetoothDevice dev ) + { + boolean success = false; + boolean sendWorking = false; + boolean receiveWorking = false; + try { + DbgUtils.logf( "PingThread: got socket to device %s", + dev.getName() ); + BluetoothSocket socket = + dev.createRfcommSocketToServiceRecord( XWApp.getAppUUID() ); + if ( null != socket ) { + DataOutputStream os = connect( socket, BTCmd.PING ); + if ( null != os ) { + os.flush(); + Thread killer = killSocketIn( socket ); + + DataInputStream is = + new DataInputStream( socket.getInputStream() ); + success = BTCmd.PONG == BTCmd.values()[is.readByte()]; + receiveWorking = true; + killer.interrupt(); + sendWorking = true; + } + socket.close(); + } + } catch ( IOException ioe ) { + logIOE( ioe ); + } + updateStatusOut( sendWorking ); + updateStatusIn( receiveWorking ); + return success; + } // sendPing + + private boolean sendPing( String hostName ) + { + boolean success = false; + String hostAddr = addrFor( hostName ); + if ( null == hostAddr ) { + DbgUtils.logf( "sendPing: no addr for hostname %s; dropping", hostName ); + } else { + BluetoothDevice dev = m_adapter.getRemoteDevice( hostAddr ); + success = sendPing( dev ); + } + return success; + } private void sendInvite( BTQueueElem elem ) { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java index 6a261145a..abf957bb9 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java @@ -1040,6 +1040,10 @@ public class BoardDelegate extends DelegateBase } break; + case BT_ENABLED: + pingBTRemotes(); + break; + // This can be BT or SMS. In BT case there's a progress // thing going. Not in SMS case. case NEWGAME_FAILURE: @@ -1634,6 +1638,8 @@ public class BoardDelegate extends DelegateBase } } // userError + // Called from server_makeFromStream, whether there's something + // missing or not. @Override public void informMissing( boolean isServer, CommsConnType connType, final int nMissingPlayers ) @@ -1914,7 +1920,7 @@ public class BoardDelegate extends DelegateBase if ( null != m_xport ) { warnIfNoTransport(); trySendChats(); - m_xport.tickle( m_connType ); + tickle(); tryInvites(); } } @@ -1925,6 +1931,38 @@ public class BoardDelegate extends DelegateBase } } // loadGame + @SuppressWarnings("fallthrough") + private void tickle() + { + switch( m_connType ) { + case COMMS_CONN_BT: + pingBTRemotes(); + // fallthrough + case COMMS_CONN_RELAY: + // break; // Try skipping the resend -- later + // fallthrough + case COMMS_CONN_SMS: + // Let other know I'm here + // DbgUtils.logf( "tickle calling comms_resendAll" ); + m_jniThread.handle( JNIThread.JNICmd.CMD_RESEND, false, true ); + break; + default: + DbgUtils.logf( "tickle: unexpected type %s", + m_connType.toString() ); + Assert.fail(); + } + } + + private void pingBTRemotes() + { + if ( CommsConnType.COMMS_CONN_BT == m_connType ) { + CommsAddrRec[] addrs = XwJNI.comms_getAddrs( m_jniGamePtr ); + for ( CommsAddrRec addr : addrs ) { + BTService.pingHost( m_activity, addr.bt_hostName, addr.bt_btAddr ); + } + } + } + private void checkAndHandle( JNICmd cmd ) { if ( null != m_jniThread ) { diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java index 531868710..4804e77c4 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java @@ -228,7 +228,9 @@ public class CommsTransport implements TransportProcs, NetStateCache.unregister( m_context, this ); } + ////////////////////////////////////////////////////////////////////// // NetStateCache.StateChangedIf interface + ////////////////////////////////////////////////////////////////////// public void netAvail( boolean nowAvailable ) { if ( !nowAvailable ) { @@ -237,25 +239,6 @@ public class CommsTransport implements TransportProcs, } } - public void tickle( CommsConnType connType ) - { - switch( connType ) { - case COMMS_CONN_RELAY: - // do nothing - // break; // Try skipping the resend -- later - case COMMS_CONN_BT: - case COMMS_CONN_SMS: - // Let other know I'm here - DbgUtils.logf( "tickle calling comms_resendAll" ); - m_jniThread.handle( JNIThread.JNICmd.CMD_RESEND, false, true ); - break; - default: - DbgUtils.logf( "tickle: unexpected type %s", - connType.toString() ); - Assert.fail(); - } - } - private synchronized void putOut( final byte[] buf ) { if ( !XWApp.UDP_ENABLED ) {