add new proxy message handler for no-conn message, and feed into

existing store-and-forward system.  With this checkin a robot-vs-robot
game plays for quite a few moves without either game every loaded into
the foreground (via a BoardActivity instance on Android), with all
moves transmitted as a result of relay checks.  One of the games
refuses to open later, however, and there are certainly other bugs.
And I'm not sure what happens when a message sent no-conn (without a
cookie ID) is received in the foreground.  But this is progress.
This commit is contained in:
Andy2 2011-08-16 19:41:33 -07:00
parent 7ab8c6eca4
commit 30145deba7
7 changed files with 121 additions and 19 deletions

View file

@ -241,6 +241,19 @@ CookieRef::_HandleAck( HostID hostID )
handleEvents(); handleEvents();
} }
void
CookieRef::_PutMsg( HostID srcID, HostID destID, unsigned char* buf, int buflen )
{
CRefEvent evt( XWE_PROXYMSG );
evt.u.fwd.src = srcID;
evt.u.fwd.dest = destID;
evt.u.fwd.buf = buf;
evt.u.fwd.buflen = buflen;
m_eventQueue.push_back( evt );
handleEvents();
}
void void
CookieRef::_Disconnect( int socket, HostID hostID ) CookieRef::_Disconnect( int socket, HostID hostID )
{ {
@ -659,6 +672,10 @@ CookieRef::handleEvents()
forward_or_store( &evt ); forward_or_store( &evt );
break; break;
case XWA_PROXYMSG:
forward_or_store/*_proxy*/( &evt );
break;
case XWA_TIMERDISCONN: case XWA_TIMERDISCONN:
disconnectSockets( XWRELAY_ERROR_TIMEOUT ); disconnectSockets( XWRELAY_ERROR_TIMEOUT );
break; break;
@ -1037,7 +1054,13 @@ CookieRef::forward_or_store( const CRefEvent* evt )
int destSocket = SocketForHost( dest ); int destSocket = SocketForHost( dest );
/* This is an ugly hack!!!! */ /* This is an ugly hack!!!! */
*buf = XWRELAY_MSG_FROMRELAY; if ( *buf == XWRELAY_MSG_TORELAY ) {
*buf = XWRELAY_MSG_FROMRELAY;
} else if ( *buf == XWRELAY_MSG_TORELAY_NOCONN ) {
*buf = XWRELAY_MSG_FROMRELAY_NOCONN;
} else {
assert( 0 ); /* don't ship this */
}
if ( 0 < m_delayMicros && destSocket != -1 ) { if ( 0 < m_delayMicros && destSocket != -1 ) {
usleep( m_delayMicros ); usleep( m_delayMicros );

View file

@ -124,6 +124,7 @@ class CookieRef {
bool _Reconnect( int socket, HostID srcID, int nPlayersH, int nPlayersS, bool _Reconnect( int socket, HostID srcID, int nPlayersH, int nPlayersS,
int seed, bool gameDead ); int seed, bool gameDead );
void _HandleAck( HostID hostID ); void _HandleAck( HostID hostID );
void _PutMsg( HostID srcID, HostID destID, unsigned char* buf, int buflen );
void _Disconnect(int socket, HostID hostID ); void _Disconnect(int socket, HostID hostID );
void _DeviceGone( HostID hostID, int seed ); void _DeviceGone( HostID hostID, int seed );
void _Shutdown(); void _Shutdown();

View file

@ -195,6 +195,15 @@ class SafeCref {
return false; return false;
} }
} }
void PutMsg( HostID srcID, HostID destID, unsigned char* buf, int buflen ) {
if ( IsValid() ) {
CookieRef* cref = m_cinfo->GetRef();
assert( 0 != cref->GetCid() );
cref->_PutMsg( srcID, destID, buf, buflen );
}
}
bool Connect( int socket, int nPlayersH, int nPlayersS, int seed ) { bool Connect( int socket, int nPlayersH, int nPlayersS, int seed ) {
if ( IsValid() ) { if ( IsValid() ) {
CookieRef* cref = m_cinfo->GetRef(); CookieRef* cref = m_cinfo->GetRef();

View file

@ -75,6 +75,9 @@ static StateTable g_stateTable[] = {
{ XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_ALLCONND }, { XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_ALLCONND },
{ XWS_ALLCONND, XWE_GOTONEACK, XWA_NONE, XWS_ALLCONND }, { XWS_ALLCONND, XWE_GOTONEACK, XWA_NONE, XWS_ALLCONND },
{ XWS_EMPTY, XWE_PROXYMSG, XWA_PROXYMSG, XWS_SAME },
{ XWS_ALLCONND, XWE_PROXYMSG, XWA_PROXYMSG, XWS_SAME },
/* { XWS_WAITMORE, XWE_GAMEFULL, XWA_SENDALLHERE, XWS_ALLCONND }, */ /* { XWS_WAITMORE, XWE_GAMEFULL, XWA_SENDALLHERE, XWS_ALLCONND }, */
/* { XWS_WAITMORE, XWE_CHECKFULL, XWA_, XWS_WAITMORE }, */ /* { XWS_WAITMORE, XWE_CHECKFULL, XWA_, XWS_WAITMORE }, */
/* { XWS_INITED, XWE_DEVCONNECT, XWA_SEND_NO_ROOM, XWS_DEAD }, */ /* { XWS_INITED, XWE_DEVCONNECT, XWA_SEND_NO_ROOM, XWS_DEAD }, */
@ -224,6 +227,7 @@ eventString( XW_RELAY_EVENT evt )
CASESTR(XWE_DEVCONNECT); CASESTR(XWE_DEVCONNECT);
CASESTR(XWE_RECONNECT); CASESTR(XWE_RECONNECT);
CASESTR(XWE_GOTONEACK); CASESTR(XWE_GOTONEACK);
CASESTR(XWE_PROXYMSG);
CASESTR(XWE_GOTLASTACK); CASESTR(XWE_GOTLASTACK);
CASESTR(XWE_ACKTIMEOUT); CASESTR(XWE_ACKTIMEOUT);
CASESTR(XWE_DISCONN); CASESTR(XWE_DISCONN);
@ -270,6 +274,7 @@ actString( XW_RELAY_ACTION act )
CASESTR(XWA_DROPDEVICE); CASESTR(XWA_DROPDEVICE);
CASESTR(XWA_SNDALLHERE_2); CASESTR(XWA_SNDALLHERE_2);
CASESTR(XWA_FWD); CASESTR(XWA_FWD);
CASESTR(XWA_PROXYMSG);
CASESTR(XWA_NOTEHEART); CASESTR(XWA_NOTEHEART);
CASESTR(XWA_TIMERDISCONN); CASESTR(XWA_TIMERDISCONN);
CASESTR(XWA_DISCONNECT); CASESTR(XWA_DISCONNECT);

View file

@ -85,6 +85,8 @@ typedef enum {
,XWE_RECONNECT /* A device is re-connecting using the connID for ,XWE_RECONNECT /* A device is re-connecting using the connID for
this object */ this object */
,XWE_PROXYMSG /* msg when game may not be connected */
,XWE_GOTONEACK ,XWE_GOTONEACK
,XWE_GOTLASTACK ,XWE_GOTLASTACK
,XWE_ACKTIMEOUT ,XWE_ACKTIMEOUT
@ -143,6 +145,8 @@ typedef enum {
,XWA_FWD /* Forward a message */ ,XWA_FWD /* Forward a message */
,XWA_PROXYMSG /* out-of-band message */
,XWA_NOTEHEART /* Record heartbeat received */ ,XWA_NOTEHEART /* Record heartbeat received */
,XWA_NOTE_EMPTY /* No sockets left; check if can delete */ ,XWA_NOTE_EMPTY /* No sockets left; check if can delete */

View file

@ -782,6 +782,61 @@ handleMsgsMsg( int sock, bool sendFull,
} }
} }
static void
handleProxyMsgs( int sock, unsigned char* bufp, unsigned char* end )
{
logf( XW_LOGINFO, "%s()", __func__ );
unsigned short nameCount;
int ii;
if ( getNetShort( &bufp, end, &nameCount ) ) {
vector<unsigned char> out(4); /* space for len and n_msgs */
assert( out.size() == 4 );
for ( ii = 0; ii < nameCount && bufp < end; ++ii ) {
// See NetUtils.java for reply format
// message-length: 2
// nameCount: 2
// name count reps of:
// counts-this-name: 2
// counts-this-name reps of
// len: 2
// msg: <len>
// pack msgs for one game
HostID hid;
char connName[MAX_CONNNAME_LEN+1];
if ( !parseRelayID( &bufp, end, connName, sizeof(connName),
&hid ) ) {
break;
}
unsigned short nMsgs;
if ( getNetShort( &bufp, end, &nMsgs ) ) {
SafeCref scr( connName );
while ( nMsgs-- > 0 ) {
unsigned short len;
HostID src;
HostID dest;
XWRELAY_Cmd cmd;
if ( getNetShort( &bufp, end, &len ) ) {
unsigned char* start = bufp;
if ( getNetByte( &bufp, end, &cmd )
&& getNetByte( &bufp, end, &src )
&& getNetByte( &bufp, end, &dest ) ) {
assert( cmd == XWRELAY_MSG_TORELAY_NOCONN );
assert( hid == dest );
scr.PutMsg( src, dest, start, len );
bufp = start + len;
continue;
}
}
break;
}
}
}
assert( bufp == end ); // don't ship with this!!!
}
} // handleProxyMsgs
void void
handle_proxy_packet( unsigned char* buf, int len, int sock ) handle_proxy_packet( unsigned char* buf, int len, int sock )
{ {
@ -818,6 +873,10 @@ handle_proxy_packet( unsigned char* buf, int len, int sock )
} }
break; /* PRX_HAS_MSGS */ break; /* PRX_HAS_MSGS */
case PRX_PUT_MSGS:
handleProxyMsgs( sock, bufp, end );
break;
case PRX_DEVICE_GONE: case PRX_DEVICE_GONE:
logf( XW_LOGINFO, "%s: got PRX_DEVICE_GONE", __func__ ); logf( XW_LOGINFO, "%s: got PRX_DEVICE_GONE", __func__ );
if ( len >= 2 ) { if ( len >= 2 ) {

View file

@ -37,29 +37,29 @@ enum { XWRELAY_NONE /* 0 is an illegal value */
flags: 1; cookieLen: 1; cookie: <cookieLen>; hostID: 1; nPlayers: 1; flags: 1; cookieLen: 1; cookie: <cookieLen>; hostID: 1; nPlayers: 1;
nPlayersTotal: 1 */ nPlayersTotal: 1 */
, XWRELAY_GAME_RECONNECT , XWRELAY_GAME_RECONNECT /* 1 */
/* Connect using connName as well as cookie. Used by a device that's /* Connect using connName as well as cookie. Used by a device that's
lost its connection to a game in progress. Once a game is locked lost its connection to a game in progress. Once a game is locked
this is the only way a host can get (back) in. Format: flags: 1; this is the only way a host can get (back) in. Format: flags: 1;
cookieLen: 1; cookie: <cookieLen>; hostID: 1; nPlayers: 1; cookieLen: 1; cookie: <cookieLen>; hostID: 1; nPlayers: 1;
nPlayersTotal: 1; connNameLen: 1; connName<connNameLen>*/ nPlayersTotal: 1; connNameLen: 1; connName<connNameLen>*/
, XWRELAY_ACK , XWRELAY_ACK /* 2 */
, XWRELAY_GAME_DISCONNECT , XWRELAY_GAME_DISCONNECT /* 3 */
/* Tell the relay that we're gone for this game. After this message is /* Tell the relay that we're gone for this game. After this message is
sent, the host can reconnect on the same socket for a new game. sent, the host can reconnect on the same socket for a new game.
Format: cookieID: 2; srcID: 1 */ Format: cookieID: 2; srcID: 1 */
, XWRELAY_CONNECT_RESP , XWRELAY_CONNECT_RESP /* 4 */
/* Sent from relay to device in response to XWRELAY_CONNECT. Format: /* Sent from relay to device in response to XWRELAY_CONNECT. Format:
heartbeat_seconds: 2; players_here: 1; players_sought: 1; */ heartbeat_seconds: 2; players_here: 1; players_sought: 1; */
, XWRELAY_RECONNECT_RESP , XWRELAY_RECONNECT_RESP /* 5 */
/* Sent from relay to device in response to XWRELAY_RECONNECT. Format: /* Sent from relay to device in response to XWRELAY_RECONNECT. Format:
same as for XWRELAY_CONNECT_RESP */ same as for XWRELAY_CONNECT_RESP */
, XWRELAY_ALLHERE , XWRELAY_ALLHERE /* 6 */
/* Sent from relay when it enters the state where all expected devices /* Sent from relay when it enters the state where all expected devices
are here (at start of new game or after having been gone for a are here (at start of new game or after having been gone for a
while). Devices should not attempt to forward messages before this while). Devices should not attempt to forward messages before this
@ -67,36 +67,38 @@ enum { XWRELAY_NONE /* 0 is an illegal value */
Format: hostID: 1; connectionID: 2; connNameLen: 1; Format: hostID: 1; connectionID: 2; connNameLen: 1;
connName<connNameLen>; */ connName<connNameLen>; */
, XWRELAY_ALLBACK__UNUSED , XWRELAY_ALLBACK__UNUSED /* 7 */
/* Like XWRELAY_ALLHERE, but indicates a return to all devices being /* Like XWRELAY_ALLHERE, but indicates a return to all devices being
present rather than the first time that's achieved. Has no real present rather than the first time that's achieved. Has no real
purpose now that the relay does store-and-forward, but at least lets purpose now that the relay does store-and-forward, but at least lets
devices tell users everybody's home. */ devices tell users everybody's home. */
, XWRELAY_DISCONNECT_YOU , XWRELAY_DISCONNECT_YOU /* 8 */
/* Sent from relay when existing connection is terminated. /* Sent from relay when existing connection is terminated.
Format: errorCode: 1 */ Format: errorCode: 1 */
, XWRELAY_DISCONNECT_OTHER , XWRELAY_DISCONNECT_OTHER /* 9 */
/* Another device has left the game. /* Another device has left the game.
Format: errorCode: 1; lostHostId: 1 */ Format: errorCode: 1; lostHostId: 1 */
, XWRELAY_CONNECTDENIED , XWRELAY_CONNECTDENIED /* 10 */
/* The relay says go away. Format: reason code: 1 */ /* The relay says go away. Format: reason code: 1 */
, XWRELAY_HEARTBEAT , XWRELAY_HEARTBEAT /* 11 */
/* Sent in either direction. Format: cookieID: 2; srcID: 1 */ /* Sent in either direction. Format: cookieID: 2; srcID: 1 */
, XWRELAY_MSG_FROMRELAY , XWRELAY_MSG_FROMRELAY /* 12 */
/* Sent from relay to device. Format: cookieID: 2; src_hostID: 1; /* Sent from relay to device. Format: cookieID: 2; src_hostID: 1;
dest_hostID: 1; data <len-headerLen> */ dest_hostID: 1; data <len-headerLen> */
, XWRELAY_MSG_TORELAY , XWRELAY_MSG_TORELAY /* 13 */
/* Sent from device to relay. Format: connectionID: 2; src_hostID: /* Sent from device to relay. Format: connectionID: 2; src_hostID:
1; dest_hostID: 1 */ 1; dest_hostID: 1 */
, XWRELAY_MSG_STATUS /* message conveying status of some sort. , XWRELAY_MSG_STATUS /* 14 message conveying status of some sort.
Format: msgCode: 1; varies after that */ Format: msgCode: 1; varies after that */
, XWRELAY_MSG_TORELAY_NOCONN /* 15 same as above, but no cookieID */
, XWRELAY_MSG_FROMRELAY_NOCONN /* 16 same as above, but no cookieID */
} }
#ifndef CANT_DO_TYPEDEF #ifndef CANT_DO_TYPEDEF
XWRelayMsg XWRelayMsg
@ -111,7 +113,7 @@ typedef unsigned char XWRELAY_Cmd;
#define HOST_ID_SERVER 1 #define HOST_ID_SERVER 1
#define MAX_INVITE_LEN 31 #define MAX_INVITE_LEN 31
#define MAX_MSG_LEN 256 /* 100 is more like it */ #define MAX_MSG_LEN 1024 /* Used for proxy too! */
#define MAX_CONNNAME_LEN 48 /* host ID, boot time, and seeds as hex? */ #define MAX_CONNNAME_LEN 48 /* host ID, boot time, and seeds as hex? */
#define XWRELAY_PROTO_VERSION_ORIG 0x01 #define XWRELAY_PROTO_VERSION_ORIG 0x01
@ -157,6 +159,7 @@ enum { PRX_NONE /* 0 is an illegal value */
,PRX_HAS_MSGS /* return message counts for connName/devid array */ ,PRX_HAS_MSGS /* return message counts for connName/devid array */
,PRX_DEVICE_GONE /* return message counts for connName/devid array */ ,PRX_DEVICE_GONE /* return message counts for connName/devid array */
,PRX_GET_MSGS /* return full messages for connName/devid array */ ,PRX_GET_MSGS /* return full messages for connName/devid array */
,PRX_PUT_MSGS /* incoming set of messages with connName/devid header */
} }
#ifndef CANT_DO_TYPEDEF #ifndef CANT_DO_TYPEDEF
XWPRXYCMD XWPRXYCMD
@ -167,8 +170,6 @@ XWPRXYCMD
typedef unsigned short CookieID; typedef unsigned short CookieID;
#endif #endif
#define MAX_PROXY_MSGLEN 128 #define COOKIE_ID_NONE 0
#define COOKIE_ID_NONE 0L
#endif #endif