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();
}
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
CookieRef::_Disconnect( int socket, HostID hostID )
{
@ -659,6 +672,10 @@ CookieRef::handleEvents()
forward_or_store( &evt );
break;
case XWA_PROXYMSG:
forward_or_store/*_proxy*/( &evt );
break;
case XWA_TIMERDISCONN:
disconnectSockets( XWRELAY_ERROR_TIMEOUT );
break;
@ -1037,7 +1054,13 @@ CookieRef::forward_or_store( const CRefEvent* evt )
int destSocket = SocketForHost( dest );
/* 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 ) {
usleep( m_delayMicros );

View file

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

View file

@ -195,6 +195,15 @@ class SafeCref {
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 ) {
if ( IsValid() ) {
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_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_CHECKFULL, XWA_, XWS_WAITMORE }, */
/* { XWS_INITED, XWE_DEVCONNECT, XWA_SEND_NO_ROOM, XWS_DEAD }, */
@ -224,6 +227,7 @@ eventString( XW_RELAY_EVENT evt )
CASESTR(XWE_DEVCONNECT);
CASESTR(XWE_RECONNECT);
CASESTR(XWE_GOTONEACK);
CASESTR(XWE_PROXYMSG);
CASESTR(XWE_GOTLASTACK);
CASESTR(XWE_ACKTIMEOUT);
CASESTR(XWE_DISCONN);
@ -270,6 +274,7 @@ actString( XW_RELAY_ACTION act )
CASESTR(XWA_DROPDEVICE);
CASESTR(XWA_SNDALLHERE_2);
CASESTR(XWA_FWD);
CASESTR(XWA_PROXYMSG);
CASESTR(XWA_NOTEHEART);
CASESTR(XWA_TIMERDISCONN);
CASESTR(XWA_DISCONNECT);

View file

@ -85,6 +85,8 @@ typedef enum {
,XWE_RECONNECT /* A device is re-connecting using the connID for
this object */
,XWE_PROXYMSG /* msg when game may not be connected */
,XWE_GOTONEACK
,XWE_GOTLASTACK
,XWE_ACKTIMEOUT
@ -143,6 +145,8 @@ typedef enum {
,XWA_FWD /* Forward a message */
,XWA_PROXYMSG /* out-of-band message */
,XWA_NOTEHEART /* Record heartbeat received */
,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
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 */
case PRX_PUT_MSGS:
handleProxyMsgs( sock, bufp, end );
break;
case PRX_DEVICE_GONE:
logf( XW_LOGINFO, "%s: got PRX_DEVICE_GONE", __func__ );
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;
nPlayersTotal: 1 */
, XWRELAY_GAME_RECONNECT
, XWRELAY_GAME_RECONNECT /* 1 */
/* 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
this is the only way a host can get (back) in. Format: flags: 1;
cookieLen: 1; cookie: <cookieLen>; hostID: 1; nPlayers: 1;
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
sent, the host can reconnect on the same socket for a new game.
Format: cookieID: 2; srcID: 1 */
, XWRELAY_CONNECT_RESP
, XWRELAY_CONNECT_RESP /* 4 */
/* Sent from relay to device in response to XWRELAY_CONNECT. Format:
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:
same as for XWRELAY_CONNECT_RESP */
, XWRELAY_ALLHERE
, XWRELAY_ALLHERE /* 6 */
/* 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
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;
connName<connNameLen>; */
, XWRELAY_ALLBACK__UNUSED
, XWRELAY_ALLBACK__UNUSED /* 7 */
/* Like XWRELAY_ALLHERE, but indicates a return to all devices being
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
devices tell users everybody's home. */
, XWRELAY_DISCONNECT_YOU
, XWRELAY_DISCONNECT_YOU /* 8 */
/* Sent from relay when existing connection is terminated.
Format: errorCode: 1 */
, XWRELAY_DISCONNECT_OTHER
, XWRELAY_DISCONNECT_OTHER /* 9 */
/* Another device has left the game.
Format: errorCode: 1; lostHostId: 1 */
, XWRELAY_CONNECTDENIED
, XWRELAY_CONNECTDENIED /* 10 */
/* The relay says go away. Format: reason code: 1 */
, XWRELAY_HEARTBEAT
, XWRELAY_HEARTBEAT /* 11 */
/* 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;
dest_hostID: 1; data <len-headerLen> */
, XWRELAY_MSG_TORELAY
, XWRELAY_MSG_TORELAY /* 13 */
/* Sent from device to relay. Format: connectionID: 2; src_hostID:
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 */
, 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
XWRelayMsg
@ -111,7 +113,7 @@ typedef unsigned char XWRELAY_Cmd;
#define HOST_ID_SERVER 1
#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 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_DEVICE_GONE /* return message counts 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
XWPRXYCMD
@ -167,8 +170,6 @@ XWPRXYCMD
typedef unsigned short CookieID;
#endif
#define MAX_PROXY_MSGLEN 128
#define COOKIE_ID_NONE 0L
#define COOKIE_ID_NONE 0
#endif