Add a one-byte header to BT messages so one device can signal another

that a new game's begun without dropping the connection.  On Palm,
remove connection-drop on new game.  With this change starting a new
game takes imperciptible time, down from 30 seconds.
This commit is contained in:
ehouse 2007-02-08 02:53:10 +00:00
parent 91c1b1246e
commit 51f726ddcf
2 changed files with 147 additions and 94 deletions

View file

@ -116,6 +116,13 @@ struct CommsCtxt {
MPSLOT MPSLOT
}; };
#ifdef XWFEATURE_BLUETOOTH
typedef enum {
BTMSG_DATA = 0
,BTMSG_RESET
} BTMsgType;
#endif
/**************************************************************************** /****************************************************************************
* prototypes * prototypes
****************************************************************************/ ****************************************************************************/
@ -124,7 +131,7 @@ static AddressRecord* rememberChannelAddress( CommsCtxt* comms,
XWHostID id, XWHostID id,
const CommsAddrRec* addr ); const CommsAddrRec* addr );
static XP_Bool channelToAddress( CommsCtxt* comms, XP_PlayerAddr channelNo, static XP_Bool channelToAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
CommsAddrRec** addr ); const CommsAddrRec** addr );
static AddressRecord* getRecordFor( CommsCtxt* comms, static AddressRecord* getRecordFor( CommsCtxt* comms,
XP_PlayerAddr channelNo ); XP_PlayerAddr channelNo );
static XP_S16 sendMsg( CommsCtxt* comms, MsgQueueElem* elem ); static XP_S16 sendMsg( CommsCtxt* comms, MsgQueueElem* elem );
@ -139,6 +146,9 @@ static XWHostID getDestID( CommsCtxt* comms, XP_PlayerAddr channelNo );
static void setHeartbeatTimer( CommsCtxt* comms ); static void setHeartbeatTimer( CommsCtxt* comms );
#endif #endif
#ifdef XWFEATURE_BLUETOOTH #ifdef XWFEATURE_BLUETOOTH
static XP_S16 send_via_bt( CommsCtxt* comms, BTMsgType typ,
XP_PlayerAddr channelNo,
void* data, int dlen );
static void btConnect( CommsCtxt* comms ); static void btConnect( CommsCtxt* comms );
#endif #endif
@ -510,12 +520,17 @@ comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr )
#endif #endif
XP_MEMCPY( &comms->addr, addr, sizeof(comms->addr) ); XP_MEMCPY( &comms->addr, addr, sizeof(comms->addr) );
if ( 0 ) {
#ifdef XWFEATURE_RELAY #ifdef XWFEATURE_RELAY
/* We should now have a cookie so we can connect??? */ /* We should now have a cookie so we can connect??? */
if ( addr->conType == COMMS_CONN_RELAY ) { } else if ( addr->conType == COMMS_CONN_RELAY ) {
relayConnect( comms ); relayConnect( comms );
}
#endif #endif
#ifdef XWFEATURE_BLUETOOTH
} else if ( addr->conType == COMMS_CONN_BT ) {
btConnect( comms );
#endif
}
} /* comms_setAddr */ } /* comms_setAddr */
void void
@ -705,13 +720,13 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
{ {
XP_S16 result = 0; XP_S16 result = 0;
XP_PlayerAddr channelNo; XP_PlayerAddr channelNo;
CommsAddrRec* addr; CommsConnType conType = comms_getConType( comms );
channelNo = elem->channelNo; channelNo = elem->channelNo;
if ( 0 ) { if ( 0 ) {
#ifdef XWFEATURE_RELAY #ifdef XWFEATURE_RELAY
} else if ( comms_getConType( comms ) == COMMS_CONN_RELAY ) { } else if ( conType == COMMS_CONN_RELAY ) {
if ( comms->r.relayState == COMMS_RELAYSTATE_ALLCONNECTED ) { if ( comms->r.relayState == COMMS_RELAYSTATE_ALLCONNECTED ) {
XWHostID destID = getDestID( comms, channelNo ); XWHostID destID = getDestID( comms, channelNo );
result = send_via_relay( comms, XWRELAY_MSG_TORELAY, destID, result = send_via_relay( comms, XWRELAY_MSG_TORELAY, destID,
@ -719,12 +734,15 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
} else { } else {
XP_LOGF( "%s: skipping message: not connected", __func__ ); XP_LOGF( "%s: skipping message: not connected", __func__ );
} }
#endif
#ifdef XWFEATURE_BLUETOOTH
} else if ( conType == COMMS_CONN_BT ) {
result = send_via_bt( comms, BTMSG_DATA, channelNo,
elem->msg, elem->len );
#endif #endif
} else { } else {
const CommsAddrRec* addr;
if ( !channelToAddress( comms, channelNo, &addr ) ) { (void)channelToAddress( comms, channelNo, &addr );
addr = NULL;
}
XP_ASSERT( !!comms->sendproc ); XP_ASSERT( !!comms->sendproc );
result = (*comms->sendproc)( elem->msg, elem->len, addr, result = (*comms->sendproc)( elem->msg, elem->len, addr,
@ -757,15 +775,13 @@ comms_resendAll( CommsCtxt* comms )
static XP_Bool static XP_Bool
relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID ) relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID )
{ {
XP_Bool consumed; XP_Bool consumed = XP_TRUE;
XWHostID destID, srcID; XWHostID destID, srcID;
CookieID cookieID; CookieID cookieID;
XP_U8 relayErr; XP_U8 relayErr;
XP_U8 hasName; XP_U8 hasName;
/* nothing for us to do here if not using relay */ /* nothing for us to do here if not using relay */
consumed = comms->addr.conType == COMMS_CONN_RELAY;
if ( consumed ) {
XWRELAY_Cmd cmd = stream_getU8( stream ); XWRELAY_Cmd cmd = stream_getU8( stream );
switch( cmd ) { switch( cmd ) {
@ -832,9 +848,24 @@ relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID )
XP_LOGF( "dropping relay msg with cmd %d", (XP_U16)cmd ); XP_LOGF( "dropping relay msg with cmd %d", (XP_U16)cmd );
} }
}
return consumed; return consumed;
} /* checkForRelay */ } /* relayPreProcess */
#endif
#ifdef XWFEATURE_BLUETOOTH
static XP_Bool
btPreProcess( CommsCtxt* comms, XWStreamCtxt* stream )
{
BTMsgType typ = (BTMsgType)stream_getU8( stream );
XP_Bool consumed = typ != BTMSG_DATA;
if ( consumed ) {
XP_ASSERT( typ == BTMSG_RESET );
(void)comms_resendAll( comms );
}
return consumed;
} /* btPreProcess */
#endif #endif
static XP_Bool static XP_Bool
@ -903,14 +934,21 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
XP_ASSERT( addr == NULL || comms->addr.conType == addr->conType ); XP_ASSERT( addr == NULL || comms->addr.conType == addr->conType );
if ( 0 ) {
#ifdef XWFEATURE_RELAY #ifdef XWFEATURE_RELAY
/* relayPreProcess returns true if consumes the message. May just eat the /* relayPreProcess returns true if consumes the message. May just eat the
header and leave a regular message to be processed below. */ header and leave a regular message to be processed below. */
} else if ( comms->addr.conType == COMMS_CONN_RELAY ) {
done = relayPreProcess( comms, stream, &senderID ); done = relayPreProcess( comms, stream, &senderID );
if ( !done ) { if ( !done ) {
usingRelay = comms->addr.conType == COMMS_CONN_RELAY; usingRelay = comms->addr.conType == COMMS_CONN_RELAY;
} }
#endif #endif
#ifdef XWFEATURE_BLUETOOTH
} else if ( comms->addr.conType == COMMS_CONN_BT ) {
done = btPreProcess( comms, stream );
#endif
}
if ( !done ) { if ( !done ) {
if ( stream_getSize( stream ) >= sizeof(connID) ) { if ( stream_getSize( stream ) >= sizeof(connID) ) {
@ -1125,16 +1163,12 @@ rememberChannelAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
static XP_Bool static XP_Bool
channelToAddress( CommsCtxt* comms, XP_PlayerAddr channelNo, channelToAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
CommsAddrRec** addr ) const CommsAddrRec** addr )
{ {
AddressRecord* recs = getRecordFor( comms, channelNo ); AddressRecord* recs = getRecordFor( comms, channelNo );
XP_Bool found = !!recs;
if ( !!recs ) { *addr = found? &recs->addr : NULL;
*addr = &recs->addr; return found;
return XP_TRUE;
} else {
return XP_FALSE;
}
} /* channelToAddress */ } /* channelToAddress */
static AddressRecord* static AddressRecord*
@ -1294,11 +1328,33 @@ btConnect( CommsCtxt* comms )
need to do this once per guest record with non-null address. Might as need to do this once per guest record with non-null address. Might as
well use real messages if we have 'em. Otherwise a fake size-0 msg. */ well use real messages if we have 'em. Otherwise a fake size-0 msg. */
if ( comms_resendAll( comms ) <= 0 ) { if ( comms_resendAll( comms ) <= 0 ) {
/* any valid ptr will do */ send_via_bt( comms, BTMSG_RESET, CHANNEL_NONE, NULL, 0 );
(void)(*comms->sendproc)( (const void*)comms, 0, NULL,
comms->sendClosure );
} }
} /* btConnect */ } /* btConnect */
static XP_S16
send_via_bt( CommsCtxt* comms, BTMsgType typ, XP_PlayerAddr channelNo,
void* data, int dlen )
{
XP_U8* buf;
XP_S16 nSent = -1;
buf = XP_MALLOC( comms->mpool, dlen + 1 );
if ( !!buf ) {
const CommsAddrRec* addr;
(void)channelToAddress( comms, channelNo, &addr );
buf[0] = typ;
if ( dlen > 0 ) {
XP_MEMCPY( &buf[1], data, dlen );
}
nSent = (*comms->sendproc)( buf, dlen+1, addr, comms->sendClosure );
XP_FREE( comms->mpool, buf );
}
return nSent;
} /* send_via_bt */
#endif #endif
#ifdef XWFEATURE_RELAY #ifdef XWFEATURE_RELAY

View file

@ -2423,9 +2423,6 @@ mainViewHandleEvent( EventPtr event )
break; break;
case newGameOkEvent: case newGameOkEvent:
#if defined XWFEATURE_BLUETOOTH
palm_bt_close( globals );
#endif
if ( globals->newGameIsNew ) { if ( globals->newGameIsNew ) {
globals->gState.curGameIndex = countGameRecords( globals ); globals->gState.curGameIndex = countGameRecords( globals );
} }