From a34ccb424f942bfbbbe26a9a03eaacbe2fc630f3 Mon Sep 17 00:00:00 2001 From: Andy2 Date: Sun, 22 Aug 2010 12:16:57 -0700 Subject: [PATCH] device now passes list of "relayID"s, consisting of connName plus device id, to relay, one for each stored game that's communicating via the relay. Relay parses out each relayID. Next relay can use these to look up whether messages are available and reply with that, and device can put up a notification. --- xwords4/android/XWords4/jni/xwjni.c | 7 ++ .../src/org/eehouse/android/xw4/DBHelper.java | 2 + .../src/org/eehouse/android/xw4/DBUtils.java | 8 +- .../org/eehouse/android/xw4/RelayService.java | 74 ++++++++++++++----- .../eehouse/android/xw4/jni/GameSummary.java | 4 +- xwords4/common/comms.c | 23 ++++++ xwords4/common/comms.h | 4 + xwords4/relay/xwrelay.cpp | 53 +++++++++++-- 8 files changed, 150 insertions(+), 25 deletions(-) diff --git a/xwords4/android/XWords4/jni/xwjni.c b/xwords4/android/XWords4/jni/xwjni.c index dfc45f618..3cdecf0e6 100644 --- a/xwords4/android/XWords4/jni/xwjni.c +++ b/xwords4/android/XWords4/jni/xwjni.c @@ -972,6 +972,13 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1summarize "org/eehouse/android/xw4/jni/" "CommsAddrRec$CommsConnType" ); if ( COMMS_CONN_RELAY == addr.conType ) { + XP_U8 buf[128]; + XP_U16 len = VSIZE(buf); + if ( comms_getRelayID( state->game.comms, buf, &len ) ) { + jbyteArray barr = makeByteArray( env, len, (jbyte*)buf ); + setObject( env, jsummary, "relayID", "[B", barr ); + (*env)->DeleteLocalRef( env, barr ); + } setString( env, jsummary, "roomName", addr.u.ip_relay.invite ); } else if ( COMMS_CONN_SMS == addr.conType ) { setString( env, jsummary, "smsPhone", addr.u.sms.phone ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBHelper.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBHelper.java index 923fb1f3f..3edd90420 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBHelper.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBHelper.java @@ -41,6 +41,7 @@ public class DBHelper extends SQLiteOpenHelper { public static final String SNAPSHOT = "SNAPSHOT"; public static final String CONTYPE = "CONTYPE"; public static final String ROOMNAME = "ROOMNAME"; + public static final String RELAYID = "RELAYID"; public static final String SMSPHONE = "SMSPHONE"; // not used yet public static final String CREATE_TIME = "CREATE_TIME"; @@ -63,6 +64,7 @@ public class DBHelper extends SQLiteOpenHelper { + CONTYPE + " INTEGER," + ROOMNAME + " TEXT," + + RELAYID + " BLOB," + SMSPHONE + " TEXT," + SCORES + " TEXT," + GAMEID + " INTEGER," diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java index e9a3e2a1f..8a04ed4b5 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java @@ -44,7 +44,8 @@ public class DBUtils { SQLiteDatabase db = s_dbHelper.getReadableDatabase(); String[] columns = { DBHelper.NUM_MOVES, DBHelper.GAME_OVER, DBHelper.CONTYPE, DBHelper.ROOMNAME, - DBHelper.SMSPHONE, DBHelper.SCORES + DBHelper.RELAYID, DBHelper.SMSPHONE, + DBHelper.SCORES }; String selection = DBHelper.FILE_NAME + "=\"" + file + "\""; @@ -79,6 +80,10 @@ public class DBUtils { if ( col >= 0 ) { summary.roomName = cursor.getString( col ); } + col = cursor.getColumnIndex( DBHelper.RELAYID ); + if ( col >= 0 ) { + summary.relayID = cursor.getBlob( col ); + } col = cursor.getColumnIndex( DBHelper.SMSPHONE ); if ( col >= 0 ) { summary.smsPhone = cursor.getString( col ); @@ -116,6 +121,7 @@ public class DBUtils { if ( null != summary.conType ) { values.put( DBHelper.CONTYPE, summary.conType.ordinal() ); values.put( DBHelper.ROOMNAME, summary.roomName ); + values.put( DBHelper.RELAYID, summary.relayID ); values.put( DBHelper.SMSPHONE, summary.smsPhone ); } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java index 938851faf..c9b5076f4 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/RelayService.java @@ -31,12 +31,18 @@ import javax.net.SocketFactory; import java.net.InetAddress; import java.net.Socket; import java.io.InputStream; +import java.io.DataInputStream; import java.io.OutputStream; +import java.io.DataOutputStream; +import java.util.ArrayList; + +import org.eehouse.android.xw4.jni.GameSummary; public class RelayService extends Service { private static final String proxy_addr = "10.0.2.2"; private static final int proxy_port = 10998; + private static final byte PROTOCOL_VERSION = 0; private NotificationManager m_nm; @@ -48,24 +54,42 @@ public class RelayService extends Service { Thread thread = new Thread( null, new Runnable() { public void run() { - try { - SocketFactory factory = SocketFactory.getDefault(); - InetAddress addr = InetAddress.getByName( proxy_addr ); - Socket socket = factory.createSocket( addr, proxy_port ); - socket.setSoTimeout( 3000 ); - Utils.logf( "writing to proxy socket" ); - OutputStream outStream = socket.getOutputStream(); - outStream.write( 0 ); - InputStream inStream = socket.getInputStream(); - int result = inStream.read(); - socket.close(); - Utils.logf( "read %d and closed proxy socket", result ); - } catch( java.net.UnknownHostException uhe ) { - Utils.logf( uhe.toString() ); - } catch( java.io.IOException ioe ) { - Utils.logf( ioe.toString() ); - } + ArrayListids = collectIDs(); + if ( null != ids ) { + try { + SocketFactory factory = SocketFactory.getDefault(); + InetAddress addr = InetAddress.getByName( proxy_addr ); + Socket socket = factory.createSocket( addr, + proxy_port ); + socket.setSoTimeout( 3000 ); + DataOutputStream outStream = + new DataOutputStream( socket.getOutputStream() ); + outStream.writeByte( PROTOCOL_VERSION ); + + outStream.writeShort( ids.size() ); + Utils.logf( "wrote count %d to proxy socket", + ids.size() ); + for ( byte[] id : ids ) { + outStream.writeShort( id.length ); + Utils.logf( "wrote length %d to proxy socket", + id.length ); + outStream.write( id, 0, id.length ); + } + outStream.flush(); + + DataInputStream dis = + new DataInputStream(socket.getInputStream()); + Utils.logf( "reading from proxy socket" ); + short result = dis.readShort(); + socket.close(); + Utils.logf( "read %d and closed proxy socket", result ); + } catch( java.net.UnknownHostException uhe ) { + Utils.logf( uhe.toString() ); + } catch( java.io.IOException ioe ) { + Utils.logf( ioe.toString() ); + } + } RelayService.this.stopSelf(); } }, getClass().getName() ); @@ -112,5 +136,21 @@ public class RelayService extends Service { // m_nm.notify( R.string.running_notification, notification ); // } + private ArrayList collectIDs() + { + ArrayList ids = new ArrayList(); + String[] games = GameUtils.gamesList( this ); + for ( String path : games ) { + Utils.logf( "looking at %s", path ); + GameSummary summary = DBUtils.getSummary( this, path ); + if ( null != summary.relayID ) { + ids.add( summary.relayID ); + Utils.logf( "adding id with length %d", summary.relayID.length ); + } + } + + return ids; + } + } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java index d1544baf3..3d90af04a 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/GameSummary.java @@ -29,6 +29,8 @@ public class GameSummary { public int[] scores; public boolean gameOver; public CommsAddrRec.CommsConnType conType; - public String roomName; public String smsPhone; + // relay-related fields + public String roomName; + public byte[] relayID; } diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index 58bd7e587..dbaeed6e3 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -726,6 +726,29 @@ comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr ) } /* comms_setAddr */ +#ifdef XWFEATURE_RELAY +XP_Bool +comms_getRelayID( const CommsCtxt* comms, XP_U8* buf, XP_U16* lenp ) +{ + XP_Bool success = comms->r.connName[0] != 0; + if ( success ) { + XP_U16 len = sizeof( comms->r.connName ) + 16; + XP_UCHAR local[len]; + XP_SNPRINTF( local, sizeof(local), "%s/%d", + comms->r.connName, comms->r.myHostID ); + XP_U16 strln = XP_STRLEN(local); + success = *lenp >= strln; + if ( success ) { + *lenp = strln; + XP_MEMCPY( buf, local, strln ); + XP_LOGF( "%s: keysize=%d", __func__, strln ); + } + } + LOG_RETURNF( "%d", success ); + return success; +} +#endif + void comms_getInitialAddr( CommsAddrRec* addr #ifdef XWFEATURE_RELAY diff --git a/xwords4/common/comms.h b/xwords4/common/comms.h index 9a9c28d59..3a86eff04 100644 --- a/xwords4/common/comms.h +++ b/xwords4/common/comms.h @@ -162,6 +162,10 @@ XP_Bool comms_checkAddr( DeviceRole role, const CommsAddrRec* addr, void comms_getAddr( const CommsCtxt* comms, CommsAddrRec* addr ); void comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr ); +#ifdef XWFEATURE_RELAY +XP_Bool comms_getRelayID( const CommsCtxt* comms, XP_U8* buf, XP_U16* len ); +#endif + CommsConnType comms_getConType( const CommsCtxt* comms ); XP_Bool comms_getIsServer( const CommsCtxt* comms ); diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index 8336ef08d..5bf07ce76 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -76,6 +76,8 @@ #include "lstnrmgr.h" static int s_nSpawns = 0; +#define MAX_PROXY_LEN 64 +#define MAX_PROXY_COUNT 48 void logf( XW_LogLevel level, const char* format, ... ) @@ -931,14 +933,53 @@ main( int argc, char** argv ) tPool->AddSocket( newSock ); } else { - unsigned char one; - read( newSock, &one, 1 ); - logf( XW_LOGERROR, "new socket connected; read %d", one ); - one = 1; - write( newSock, &one, 1 ); + unsigned char protocol; + ssize_t nread; + + nread = recv( newSock, &protocol, sizeof(protocol), + MSG_WAITALL ); + if ( nread == sizeof(protocol) && (0 == protocol) ) { + logf( XW_LOGERROR, "proxy socket connected; " + "protocol=%d", protocol ); + unsigned short count; + nread = recv( newSock, &count, sizeof(count), + MSG_WAITALL ); + if ( nread == sizeof( count ) ) { + count = ntohs( count ); + logf( XW_LOGERROR, "count=%d", count ); + if ( count < MAX_PROXY_COUNT ) { + for ( int ii = 0; ii < count; ++ii ) { + unsigned short len; + nread = recv( newSock, &len, sizeof(len), + MSG_WAITALL ); + if ( nread != sizeof(len) ) { + break; + } + len = ntohs( len ); + if ( len > MAX_PROXY_LEN ) { + break; + } + logf( XW_LOGERROR, "len=%d", len ); + unsigned char buf[MAX_PROXY_LEN+1]; + nread = recv( newSock, buf, len, + MSG_WAITALL ); + if ( nread == len ) { + buf[len] = '\0'; + logf( XW_LOGINFO, "read %s", buf ); + } + + /* fake, random result */ + unsigned char result = ii % 2 == 0? 1 : 0; + write( newSock, &result, sizeof(result) ); + } + } + } else { + logf( XW_LOGERROR, "Read %d bytes instead of %d", + nread, sizeof(count) ); + } + } close( newSock ); } - --retval; } }