mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-18 22:26:30 +01:00
Re-add direct-via-ip transport, and implement for linux in order to
better test heartbeats. Fix so can play against Palm over BT. Assertions failing on Linux when reset, but it's otherwise done.
This commit is contained in:
parent
044a889d6d
commit
42615345c9
8 changed files with 373 additions and 264 deletions
253
common/comms.c
253
common/comms.c
|
@ -53,14 +53,15 @@ typedef struct MsgQueueElem {
|
||||||
XP_U8* msg;
|
XP_U8* msg;
|
||||||
XP_U16 len;
|
XP_U16 len;
|
||||||
XP_U16 channelNo;
|
XP_U16 channelNo;
|
||||||
|
XP_U16 sendCount; /* how many times sent? */
|
||||||
MsgID msgID; /* saved for ease of deletion */
|
MsgID msgID; /* saved for ease of deletion */
|
||||||
} MsgQueueElem;
|
} MsgQueueElem;
|
||||||
|
|
||||||
typedef struct AddressRecord {
|
typedef struct AddressRecord {
|
||||||
struct AddressRecord* next;
|
struct AddressRecord* next;
|
||||||
CommsAddrRec addr;
|
CommsAddrRec addr;
|
||||||
#ifdef DEBUG
|
|
||||||
XP_U16 lastACK;
|
XP_U16 lastACK;
|
||||||
|
#ifdef DEBUG
|
||||||
XP_U16 nUniqueBytes;
|
XP_U16 nUniqueBytes;
|
||||||
#endif
|
#endif
|
||||||
MsgID nextMsgID; /* on a per-channel basis */
|
MsgID nextMsgID; /* on a per-channel basis */
|
||||||
|
@ -136,11 +137,12 @@ struct CommsCtxt {
|
||||||
MPSLOT
|
MPSLOT
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BTMSG_DATA = 0
|
BTIPMSG_NONE = 0
|
||||||
,BTMSG_RESET
|
,BTIPMSG_DATA
|
||||||
} BTMsgType;
|
,BTIPMSG_RESET
|
||||||
|
} BTIPMsgType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -157,6 +159,8 @@ static AddressRecord* getRecordFor( CommsCtxt* comms,
|
||||||
static XP_S16 sendMsg( CommsCtxt* comms, MsgQueueElem* elem );
|
static XP_S16 sendMsg( CommsCtxt* comms, MsgQueueElem* elem );
|
||||||
static void addToQueue( CommsCtxt* comms, MsgQueueElem* newMsgElem );
|
static void addToQueue( CommsCtxt* comms, MsgQueueElem* newMsgElem );
|
||||||
static XP_U16 countAddrRecs( const CommsCtxt* comms );
|
static XP_U16 countAddrRecs( const CommsCtxt* comms );
|
||||||
|
static void sendConnect( CommsCtxt* comms );
|
||||||
|
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
static void relayConnect( CommsCtxt* comms );
|
static void relayConnect( CommsCtxt* comms );
|
||||||
static void relayDisconnect( CommsCtxt* comms );
|
static void relayDisconnect( CommsCtxt* comms );
|
||||||
|
@ -166,12 +170,13 @@ static XWHostID getDestID( CommsCtxt* comms, XP_PlayerAddr channelNo );
|
||||||
#endif
|
#endif
|
||||||
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
|
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
|
||||||
static void setHeartbeatTimer( CommsCtxt* comms );
|
static void setHeartbeatTimer( CommsCtxt* comms );
|
||||||
|
#else
|
||||||
|
# define setHeartbeatTimer( comms )
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
|
||||||
static XP_S16 send_via_bt( CommsCtxt* comms, BTMsgType typ,
|
static XP_S16 send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType typ,
|
||||||
XP_PlayerAddr channelNo,
|
XP_PlayerAddr channelNo,
|
||||||
void* data, int dlen );
|
void* data, int dlen );
|
||||||
static void btConnect( CommsCtxt* comms );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -299,7 +304,7 @@ addrFromStream( CommsAddrRec* addrP, XWStreamCtxt* stream )
|
||||||
case COMMS_CONN_IR:
|
case COMMS_CONN_IR:
|
||||||
/* nothing to save */
|
/* nothing to save */
|
||||||
break;
|
break;
|
||||||
case COMMS_CONN_IP_NOUSE:
|
case COMMS_CONN_IP_DIRECT:
|
||||||
stringFromStreamHere( stream, addr.u.ip.hostName_ip,
|
stringFromStreamHere( stream, addr.u.ip.hostName_ip,
|
||||||
sizeof(addr.u.ip.hostName_ip) );
|
sizeof(addr.u.ip.hostName_ip) );
|
||||||
addr.u.ip.ipAddr_ip = stream_getU32( stream );
|
addr.u.ip.ipAddr_ip = stream_getU32( stream );
|
||||||
|
@ -398,7 +403,9 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util,
|
||||||
|
|
||||||
msg->channelNo = stream_getU16( stream );
|
msg->channelNo = stream_getU16( stream );
|
||||||
msg->msgID = stream_getU32( stream );
|
msg->msgID = stream_getU32( stream );
|
||||||
|
#ifdef COMMS_HEARTBEAT
|
||||||
|
msg->sendCount = 0;
|
||||||
|
#endif
|
||||||
msg->len = stream_getU16( stream );
|
msg->len = stream_getU16( stream );
|
||||||
msg->msg = (XP_U8*)XP_MALLOC( mpool, msg->len );
|
msg->msg = (XP_U8*)XP_MALLOC( mpool, msg->len );
|
||||||
stream_getBytes( stream, msg->msg, msg->len );
|
stream_getBytes( stream, msg->msg, msg->len );
|
||||||
|
@ -419,21 +426,36 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util,
|
||||||
void
|
void
|
||||||
comms_start( CommsCtxt* comms )
|
comms_start( CommsCtxt* comms )
|
||||||
{
|
{
|
||||||
if ( 0 ) {
|
|
||||||
#ifdef XWFEATURE_RELAY
|
|
||||||
} else if ( comms->addr.conType == COMMS_CONN_RELAY ) {
|
|
||||||
comms->r.relayState = COMMS_RELAYSTATE_UNCONNECTED;
|
|
||||||
relayConnect( comms );
|
|
||||||
#endif
|
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
|
||||||
} else if ( comms->addr.conType == COMMS_CONN_BT ) {
|
|
||||||
btConnect( comms );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef COMMS_HEARTBEAT
|
#ifdef COMMS_HEARTBEAT
|
||||||
comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR;
|
comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
sendConnect( comms );
|
||||||
|
} /* comms_start */
|
||||||
|
|
||||||
|
static void
|
||||||
|
sendConnect( CommsCtxt* comms )
|
||||||
|
{
|
||||||
|
switch( comms->addr.conType ) {
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
|
case COMMS_CONN_RELAY:
|
||||||
|
comms->r.relayState = COMMS_RELAYSTATE_UNCONNECTED;
|
||||||
|
relayConnect( comms );
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
|
||||||
|
case COMMS_CONN_BT:
|
||||||
|
case COMMS_CONN_IP_DIRECT:
|
||||||
|
send_via_bt_or_ip( comms, BTIPMSG_RESET,
|
||||||
|
CHANNEL_NONE, NULL, 0 );
|
||||||
|
(void)comms_resendAll( comms );
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setHeartbeatTimer( comms );
|
||||||
} /* comms_start */
|
} /* comms_start */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -460,7 +482,7 @@ addrToStream( XWStreamCtxt* stream, const CommsAddrRec* addrP )
|
||||||
case COMMS_CONN_IR:
|
case COMMS_CONN_IR:
|
||||||
/* nothing to save */
|
/* nothing to save */
|
||||||
break;
|
break;
|
||||||
case COMMS_CONN_IP_NOUSE:
|
case COMMS_CONN_IP_DIRECT:
|
||||||
stringToStream( stream, addr.u.ip.hostName_ip );
|
stringToStream( stream, addr.u.ip.hostName_ip );
|
||||||
stream_putU32( stream, addr.u.ip.ipAddr_ip );
|
stream_putU32( stream, addr.u.ip.ipAddr_ip );
|
||||||
stream_putU16( stream, addr.u.ip.port_ip );
|
stream_putU16( stream, addr.u.ip.port_ip );
|
||||||
|
@ -546,22 +568,16 @@ void
|
||||||
comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr )
|
comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr )
|
||||||
{
|
{
|
||||||
XP_ASSERT( comms != NULL );
|
XP_ASSERT( comms != NULL );
|
||||||
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
|
||||||
util_addrChange( comms->util, &comms->addr, addr );
|
util_addrChange( comms->util, &comms->addr, addr );
|
||||||
#endif
|
#endif
|
||||||
XP_MEMCPY( &comms->addr, addr, sizeof(comms->addr) );
|
XP_MEMCPY( &comms->addr, addr, sizeof(comms->addr) );
|
||||||
|
|
||||||
if ( 0 ) {
|
#ifdef COMMS_HEARTBEAT
|
||||||
#ifdef XWFEATURE_RELAY
|
comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR;
|
||||||
/* We should now have a cookie so we can connect??? */
|
|
||||||
} else if ( addr->conType == COMMS_CONN_RELAY ) {
|
|
||||||
relayConnect( comms );
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
sendConnect( comms );
|
||||||
} else if ( addr->conType == COMMS_CONN_BT ) {
|
|
||||||
btConnect( comms );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef COMMS_HEARTBEAT
|
#ifdef COMMS_HEARTBEAT
|
||||||
comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR;
|
comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR;
|
||||||
#endif
|
#endif
|
||||||
|
@ -601,9 +617,9 @@ comms_getIsServer( const CommsCtxt* comms )
|
||||||
return comms->isServer;
|
return comms->isServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static XP_S16
|
static MsgQueueElem*
|
||||||
sendWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
|
makeElemWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
|
||||||
XP_PlayerAddr channelNo, XWStreamCtxt* stream )
|
XP_PlayerAddr channelNo, XWStreamCtxt* stream )
|
||||||
{
|
{
|
||||||
XP_U16 headerLen;
|
XP_U16 headerLen;
|
||||||
XP_U16 streamSize = NULL == stream? 0 : stream_getSize( stream );
|
XP_U16 streamSize = NULL == stream? 0 : stream_getSize( stream );
|
||||||
|
@ -623,6 +639,9 @@ sendWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
|
||||||
sizeof( *newMsgElem ) );
|
sizeof( *newMsgElem ) );
|
||||||
newMsgElem->channelNo = channelNo;
|
newMsgElem->channelNo = channelNo;
|
||||||
newMsgElem->msgID = msgID;
|
newMsgElem->msgID = msgID;
|
||||||
|
#ifdef COMMS_HEARTBEAT
|
||||||
|
newMsgElem->sendCount = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
msgStream = mem_stream_make( MPPARM(comms->mpool)
|
msgStream = mem_stream_make( MPPARM(comms->mpool)
|
||||||
util_getVTManager(comms->util),
|
util_getVTManager(comms->util),
|
||||||
|
@ -646,10 +665,8 @@ sendWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
|
||||||
stream_getBytes( stream, newMsgElem->msg + headerLen, streamSize );
|
stream_getBytes( stream, newMsgElem->msg + headerLen, streamSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
addToQueue( comms, newMsgElem );
|
return newMsgElem;
|
||||||
|
} /* makeElemWithID */
|
||||||
return sendMsg( comms, newMsgElem );
|
|
||||||
} /* sendWithID */
|
|
||||||
|
|
||||||
/* Send a message using the sequentially next MsgID. Save the message so
|
/* Send a message using the sequentially next MsgID. Save the message so
|
||||||
* resend can work. */
|
* resend can work. */
|
||||||
|
@ -659,9 +676,17 @@ comms_send( CommsCtxt* comms, XWStreamCtxt* stream )
|
||||||
XP_PlayerAddr channelNo = stream_getAddress( stream );
|
XP_PlayerAddr channelNo = stream_getAddress( stream );
|
||||||
AddressRecord* rec = getRecordFor( comms, channelNo );
|
AddressRecord* rec = getRecordFor( comms, channelNo );
|
||||||
MsgID msgID = (!!rec)? ++rec->nextMsgID : 0;
|
MsgID msgID = (!!rec)? ++rec->nextMsgID : 0;
|
||||||
|
MsgQueueElem* elem;
|
||||||
|
XP_S16 result = -1;
|
||||||
|
|
||||||
XP_DEBUGF( "assigning msgID=" XP_LD " on chnl %d", msgID, channelNo );
|
XP_DEBUGF( "assigning msgID=" XP_LD " on chnl %d", msgID, channelNo );
|
||||||
return sendWithID( comms, msgID, rec, channelNo, stream );
|
|
||||||
|
elem = makeElemWithID( comms, msgID, rec, channelNo, stream );
|
||||||
|
if ( NULL != elem ) {
|
||||||
|
addToQueue( comms, elem );
|
||||||
|
result = sendMsg( comms, elem );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
} /* comms_send */
|
} /* comms_send */
|
||||||
|
|
||||||
/* Add new message to the end of the list. The list needs to be kept in order
|
/* Add new message to the end of the list. The list needs to be kept in order
|
||||||
|
@ -702,6 +727,13 @@ printQueue( CommsCtxt* comms )
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
freeElem( const CommsCtxt* comms, MsgQueueElem* elem )
|
||||||
|
{
|
||||||
|
XP_FREE( comms->mpool, elem->msg );
|
||||||
|
XP_FREE( comms->mpool, elem );
|
||||||
|
}
|
||||||
|
|
||||||
/* We've received on some channel a message with a certain ID. This means
|
/* We've received on some channel a message with a certain ID. This means
|
||||||
* that all messages sent on that channel with lower IDs have been received
|
* that all messages sent on that channel with lower IDs have been received
|
||||||
* and can be removed from our queue. BUT: if this ID is higher than any
|
* and can be removed from our queue. BUT: if this ID is higher than any
|
||||||
|
@ -737,8 +769,7 @@ removeFromQueue( CommsCtxt* comms, XP_PlayerAddr channelNo, MsgID msgID )
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !knownGood && (elem->msgID <= msgID) ) {
|
if ( !knownGood && (elem->msgID <= msgID) ) {
|
||||||
XP_FREE( comms->mpool, elem->msg );
|
freeElem( comms, elem );
|
||||||
XP_FREE( comms->mpool, elem );
|
|
||||||
--comms->queueLen;
|
--comms->queueLen;
|
||||||
} else {
|
} else {
|
||||||
keep->next = elem;
|
keep->next = elem;
|
||||||
|
@ -762,7 +793,7 @@ removeFromQueue( CommsCtxt* comms, XP_PlayerAddr channelNo, MsgID msgID )
|
||||||
static XP_S16
|
static XP_S16
|
||||||
sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
||||||
{
|
{
|
||||||
XP_S16 result = 0;
|
XP_S16 result = -1;
|
||||||
XP_PlayerAddr channelNo;
|
XP_PlayerAddr channelNo;
|
||||||
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
|
||||||
CommsConnType conType = comms_getConType( comms );
|
CommsConnType conType = comms_getConType( comms );
|
||||||
|
@ -781,10 +812,13 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
||||||
XP_LOGF( "%s: skipping message: not connected", __func__ );
|
XP_LOGF( "%s: skipping message: not connected", __func__ );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
|
||||||
} else if ( conType == COMMS_CONN_BT ) {
|
} else if ( conType == COMMS_CONN_BT || conType == COMMS_CONN_IP_DIRECT ) {
|
||||||
result = send_via_bt( comms, BTMSG_DATA, channelNo,
|
result = send_via_bt_or_ip( comms, BTIPMSG_DATA, channelNo,
|
||||||
elem->msg, elem->len );
|
elem->msg, elem->len );
|
||||||
|
#ifdef COMMS_HEARTBEAT
|
||||||
|
setHeartbeatTimer( comms );
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
const CommsAddrRec* addr;
|
const CommsAddrRec* addr;
|
||||||
|
@ -794,6 +828,12 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
||||||
result = (*comms->sendproc)( elem->msg, elem->len, addr,
|
result = (*comms->sendproc)( elem->msg, elem->len, addr,
|
||||||
comms->sendClosure );
|
comms->sendClosure );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( result == elem->len ) {
|
||||||
|
++elem->sendCount;
|
||||||
|
XP_LOGF( "sendCount now %d", elem->sendCount );
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} /* sendMsg */
|
} /* sendMsg */
|
||||||
|
|
||||||
|
@ -898,22 +938,51 @@ relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID )
|
||||||
} /* relayPreProcess */
|
} /* relayPreProcess */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
btPreProcess( CommsCtxt* comms, XWStreamCtxt* stream )
|
btIpPreProcess( CommsCtxt* comms, XWStreamCtxt* stream )
|
||||||
{
|
{
|
||||||
BTMsgType typ = (BTMsgType)stream_getU8( stream );
|
BTIPMsgType typ = (BTIPMsgType)stream_getU8( stream );
|
||||||
XP_Bool consumed = typ != BTMSG_DATA;
|
XP_Bool consumed = typ != BTIPMSG_DATA;
|
||||||
|
|
||||||
if ( consumed ) {
|
if ( consumed ) {
|
||||||
XP_ASSERT( typ == BTMSG_RESET );
|
/* This is all there is so far */
|
||||||
|
XP_ASSERT( typ == BTIPMSG_RESET );
|
||||||
(void)comms_resendAll( comms );
|
(void)comms_resendAll( comms );
|
||||||
}
|
}
|
||||||
|
|
||||||
return consumed;
|
return consumed;
|
||||||
} /* btPreProcess */
|
} /* btIpPreProcess */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static XP_Bool
|
||||||
|
preProcess( CommsCtxt* comms, XWStreamCtxt* stream,
|
||||||
|
XP_Bool* usingRelay, XWHostID* senderID )
|
||||||
|
{
|
||||||
|
XP_Bool consumed = XP_FALSE;
|
||||||
|
switch ( comms->addr.conType ) {
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
|
/* relayPreProcess returns true if consumes the message. May just eat the
|
||||||
|
header and leave a regular message to be processed below. */
|
||||||
|
case COMMS_CONN_RELAY:
|
||||||
|
consumed = relayPreProcess( comms, stream, senderID );
|
||||||
|
if ( !consumed ) {
|
||||||
|
*usingRelay = comms->addr.conType == COMMS_CONN_RELAY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
|
||||||
|
case COMMS_CONN_BT:
|
||||||
|
case COMMS_CONN_IP_DIRECT:
|
||||||
|
consumed = btIpPreProcess( comms, stream );
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
} /* preProcess */
|
||||||
|
|
||||||
static XP_Bool
|
static XP_Bool
|
||||||
addressUnknown( CommsCtxt* comms, const CommsAddrRec* addr )
|
addressUnknown( CommsCtxt* comms, const CommsAddrRec* addr )
|
||||||
{
|
{
|
||||||
|
@ -976,27 +1045,10 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
||||||
XWHostID senderID = 0; /* unset; default for non-relay cases */
|
XWHostID senderID = 0; /* unset; default for non-relay cases */
|
||||||
XP_Bool usingRelay = XP_FALSE;
|
XP_Bool usingRelay = XP_FALSE;
|
||||||
XP_Bool channelWas0 = XP_FALSE;
|
XP_Bool channelWas0 = XP_FALSE;
|
||||||
XP_Bool done = XP_FALSE;
|
|
||||||
|
|
||||||
XP_ASSERT( addr == NULL || comms->addr.conType == addr->conType );
|
XP_ASSERT( addr == NULL || comms->addr.conType == addr->conType );
|
||||||
|
|
||||||
if ( 0 ) {
|
if ( !preProcess( comms, stream, &usingRelay, &senderID ) ) {
|
||||||
#ifdef XWFEATURE_RELAY
|
|
||||||
/* relayPreProcess returns true if consumes the message. May just eat the
|
|
||||||
header and leave a regular message to be processed below. */
|
|
||||||
} else if ( comms->addr.conType == COMMS_CONN_RELAY ) {
|
|
||||||
done = relayPreProcess( comms, stream, &senderID );
|
|
||||||
if ( !done ) {
|
|
||||||
usingRelay = comms->addr.conType == COMMS_CONN_RELAY;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
|
||||||
} else if ( comms->addr.conType == COMMS_CONN_BT ) {
|
|
||||||
done = btPreProcess( comms, stream );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !done ) {
|
|
||||||
if ( stream_getSize( stream ) >= sizeof(connID) ) {
|
if ( stream_getSize( stream ) >= sizeof(connID) ) {
|
||||||
connID = stream_getU32( stream );
|
connID = stream_getU32( stream );
|
||||||
XP_STATUSF( "%s: read connID of %lx", __func__, connID );
|
XP_STATUSF( "%s: read connID of %lx", __func__, connID );
|
||||||
|
@ -1073,14 +1125,16 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if ( !!recs ) {
|
if ( !!recs ) {
|
||||||
XP_ASSERT( lastMsgRcd <= recs->nextMsgID );
|
/* XP_ASSERT( lastMsgRcd <= recs->nextMsgID ); */
|
||||||
if ( lastMsgRcd > recs->nextMsgID ) {
|
if ( lastMsgRcd > recs->nextMsgID ) {
|
||||||
XP_LOGF( "bad: got lastMsgRcd of %ld, "
|
XP_LOGF( "bad: got lastMsgRcd of %ld, "
|
||||||
"nextMsgID is %ld",
|
"nextMsgID is %ld",
|
||||||
lastMsgRcd, recs->nextMsgID );
|
lastMsgRcd, recs->nextMsgID );
|
||||||
|
validMessage = XP_FALSE;
|
||||||
|
} else {
|
||||||
|
XP_ASSERT( lastMsgRcd < 0x0000FFFF );
|
||||||
|
recs->lastACK = (XP_U16)lastMsgRcd;
|
||||||
}
|
}
|
||||||
XP_ASSERT( lastMsgRcd < 0x0000FFFF );
|
|
||||||
recs->lastACK = (XP_U16)lastMsgRcd;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1146,7 +1200,9 @@ heartbeat_checks( CommsCtxt* comms )
|
||||||
|
|
||||||
for ( elem = comms->msgQueueHead; !!elem; elem = elem->next ) {
|
for ( elem = comms->msgQueueHead; !!elem; elem = elem->next ) {
|
||||||
XP_ASSERT( elem->channelNo < MAX_NUM_PLAYERS );
|
XP_ASSERT( elem->channelNo < MAX_NUM_PLAYERS );
|
||||||
++pendingPacks[elem->channelNo];
|
if ( elem->sendCount == 0 ) { /* still waiting being sent? */
|
||||||
|
++pendingPacks[elem->channelNo];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
now = util_getCurSeconds( comms->util );
|
now = util_getCurSeconds( comms->util );
|
||||||
|
@ -1154,17 +1210,27 @@ heartbeat_checks( CommsCtxt* comms )
|
||||||
for ( rec = comms->recs; !!rec; rec = rec->next ) {
|
for ( rec = comms->recs; !!rec; rec = rec->next ) {
|
||||||
XP_U32 lastMsgRcvdTime = rec->lastMsgRcvdTime;
|
XP_U32 lastMsgRcvdTime = rec->lastMsgRcvdTime;
|
||||||
if ( lastMsgRcvdTime == 0 ) { /* nothing received yet */
|
if ( lastMsgRcvdTime == 0 ) { /* nothing received yet */
|
||||||
|
XP_LOGF( "no last message" );
|
||||||
/* do nothing; or should we send? */
|
/* do nothing; or should we send? */
|
||||||
} else if ( (lastMsgRcvdTime > 0) && (lastMsgRcvdTime < tooLongAgo) ) {
|
} else if ( (lastMsgRcvdTime > 0) && (lastMsgRcvdTime < tooLongAgo) ) {
|
||||||
XP_LOGF( "calling reset proc" );
|
XP_LOGF( "calling reset proc; last was %ld secs too long ago",
|
||||||
|
tooLongAgo-lastMsgRcvdTime );
|
||||||
(*comms->resetproc)(comms->sendClosure);
|
(*comms->resetproc)(comms->sendClosure);
|
||||||
resetTimer = XP_FALSE;
|
resetTimer = XP_FALSE;
|
||||||
break;
|
break;
|
||||||
} else if ( 0 == pendingPacks[rec->channelNo] ) {
|
} else if ( 0 == pendingPacks[rec->channelNo] ) {
|
||||||
XP_LOGF( "sending heartbeat on channel %d", rec->channelNo );
|
MsgQueueElem* hb;
|
||||||
sendWithID( comms, rec->lastMsgReceived, rec, rec->channelNo, NULL );
|
XP_LOGF( "sending heartbeat on channel %d with msgID %d",
|
||||||
|
rec->channelNo, rec->lastMsgReceived );
|
||||||
|
hb = makeElemWithID( comms, rec->lastACK, rec, rec->channelNo, NULL );
|
||||||
|
if ( NULL != hb ) {
|
||||||
|
sendMsg( comms, hb );
|
||||||
|
freeElem( comms, hb );
|
||||||
|
} else {
|
||||||
|
XP_ASSERT( XP_FALSE );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "All's well" );
|
XP_LOGF( "All's well (%d pending)", pendingPacks[rec->channelNo] );
|
||||||
resetTimer = XP_TRUE;
|
resetTimer = XP_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1199,6 +1265,7 @@ p_comms_timerFired( void* closure, XWTimerReason XP_UNUSED_DBG(why) )
|
||||||
static void
|
static void
|
||||||
setHeartbeatTimer( CommsCtxt* comms )
|
setHeartbeatTimer( CommsCtxt* comms )
|
||||||
{
|
{
|
||||||
|
LOG_FUNC();
|
||||||
#ifdef RELAY_HEARTBEAT
|
#ifdef RELAY_HEARTBEAT
|
||||||
if ( comms->addr.conType == COMMS_CONN_RELAY ) {
|
if ( comms->addr.conType == COMMS_CONN_RELAY ) {
|
||||||
util_setTimer( comms->util, TIMER_HEARTBEAT, comms->r.heartbeat,
|
util_setTimer( comms->util, TIMER_HEARTBEAT, comms->r.heartbeat,
|
||||||
|
@ -1463,22 +1530,10 @@ relayConnect( CommsCtxt* comms )
|
||||||
} /* relayConnect */
|
} /* relayConnect */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
|
||||||
static void
|
|
||||||
btConnect( CommsCtxt* comms )
|
|
||||||
{
|
|
||||||
XP_ASSERT( !!comms );
|
|
||||||
/* Ping the bt layer so it'll get sockets set up. PENDING: if I'm server
|
|
||||||
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. */
|
|
||||||
|
|
||||||
send_via_bt( comms, BTMSG_RESET, CHANNEL_NONE, NULL, 0 );
|
|
||||||
(void)( comms_resendAll( comms ) );
|
|
||||||
} /* btConnect */
|
|
||||||
|
|
||||||
static XP_S16
|
static XP_S16
|
||||||
send_via_bt( CommsCtxt* comms, BTMsgType typ, XP_PlayerAddr channelNo,
|
send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType typ, XP_PlayerAddr channelNo,
|
||||||
void* data, int dlen )
|
void* data, int dlen )
|
||||||
{
|
{
|
||||||
XP_U8* buf;
|
XP_U8* buf;
|
||||||
XP_S16 nSent = -1;
|
XP_S16 nSent = -1;
|
||||||
|
@ -1499,7 +1554,7 @@ send_via_bt( CommsCtxt* comms, BTMsgType typ, XP_PlayerAddr channelNo,
|
||||||
setHeartbeatTimer( comms );
|
setHeartbeatTimer( comms );
|
||||||
}
|
}
|
||||||
return nSent;
|
return nSent;
|
||||||
} /* send_via_bt */
|
} /* send_via_bt_or_ip */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ typedef XP_U8 XWHostID;
|
||||||
typedef enum {
|
typedef enum {
|
||||||
COMMS_CONN_UNUSED, /* I want errors on uninited case */
|
COMMS_CONN_UNUSED, /* I want errors on uninited case */
|
||||||
COMMS_CONN_IR,
|
COMMS_CONN_IR,
|
||||||
COMMS_CONN_IP_NOUSE,
|
COMMS_CONN_IP_DIRECT,
|
||||||
COMMS_CONN_RELAY,
|
COMMS_CONN_RELAY,
|
||||||
COMMS_CONN_BT,
|
COMMS_CONN_BT,
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,10 @@ BLUETOOTH = -DXWFEATURE_BLUETOOTH -DBT_USE_L2CAP
|
||||||
DEFINES += ${BLUETOOTH}
|
DEFINES += ${BLUETOOTH}
|
||||||
DEFINES += -DXWFEATURE_RELAY
|
DEFINES += -DXWFEATURE_RELAY
|
||||||
|
|
||||||
|
# Support device-to-device connection via UDP, e.g. using wifi on a
|
||||||
|
# LAN or where the host/server isn't behind a firewall.
|
||||||
|
DEFINES += -DXWFEATURE_IP_DIRECT
|
||||||
|
|
||||||
# Choose one of these. RELAY_HEARTBEAT means relay (must be compiled
|
# Choose one of these. RELAY_HEARTBEAT means relay (must be compiled
|
||||||
# with same -D) works with comms on heartbeat. Works only with relay.
|
# with same -D) works with comms on heartbeat. Works only with relay.
|
||||||
# COMMS_HEARTBEAT should work on any comms transport (even IR, but
|
# COMMS_HEARTBEAT should work on any comms transport (even IR, but
|
||||||
|
@ -106,6 +110,7 @@ OBJ = $(PLATFORM)/linuxmain.o \
|
||||||
$(PLATFORM)/cursesletterask.o \
|
$(PLATFORM)/cursesletterask.o \
|
||||||
$(PLATFORM)/filestream.o \
|
$(PLATFORM)/filestream.o \
|
||||||
$(PLATFORM)/linuxbt.o \
|
$(PLATFORM)/linuxbt.o \
|
||||||
|
$(PLATFORM)/linuxudp.o \
|
||||||
|
|
||||||
# $(PLATFORM)/linuxcommpipe.o \
|
# $(PLATFORM)/linuxcommpipe.o \
|
||||||
|
|
||||||
|
|
|
@ -665,11 +665,12 @@ static void
|
||||||
curses_stop_listening( CursesAppGlobals* globals, int sock )
|
curses_stop_listening( CursesAppGlobals* globals, int sock )
|
||||||
{
|
{
|
||||||
int count = globals->fdCount;
|
int count = globals->fdCount;
|
||||||
int i, found = 0;
|
int i;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
for ( i = 0; i < count; ++i ) {
|
for ( i = 0; i < count; ++i ) {
|
||||||
if ( globals->fdArray[i].fd == sock ) {
|
if ( globals->fdArray[i].fd == sock ) {
|
||||||
found = 1;
|
found = true;
|
||||||
} else if ( found ) {
|
} else if ( found ) {
|
||||||
globals->fdArray[i-1].fd = globals->fdArray[i].fd;
|
globals->fdArray[i-1].fd = globals->fdArray[i].fd;
|
||||||
}
|
}
|
||||||
|
@ -680,7 +681,8 @@ curses_stop_listening( CursesAppGlobals* globals, int sock )
|
||||||
} /* curses_stop_listening */
|
} /* curses_stop_listening */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
curses_socket_changed( void* closure, int oldSock, int newSock )
|
curses_socket_changed( void* closure, int oldSock, int newSock,
|
||||||
|
void** XP_UNUSED(storage) )
|
||||||
{
|
{
|
||||||
CursesAppGlobals* globals = (CursesAppGlobals*)closure;
|
CursesAppGlobals* globals = (CursesAppGlobals*)closure;
|
||||||
if ( oldSock != -1 ) {
|
if ( oldSock != -1 ) {
|
||||||
|
@ -1014,7 +1016,9 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
||||||
|
|
||||||
globals.amServer = isServer;
|
globals.amServer = isServer;
|
||||||
globals.cGlobals.params = params;
|
globals.cGlobals.params = params;
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
globals.cGlobals.socket = -1;
|
globals.cGlobals.socket = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
globals.cGlobals.socketChanged = curses_socket_changed;
|
globals.cGlobals.socketChanged = curses_socket_changed;
|
||||||
globals.cGlobals.socketChangedClosure = &globals;
|
globals.cGlobals.socketChangedClosure = &globals;
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "linuxmain.h"
|
#include "linuxmain.h"
|
||||||
#include "linuxbt.h"
|
#include "linuxbt.h"
|
||||||
|
#include "linuxudp.h"
|
||||||
/* #include "gtkmain.h" */
|
/* #include "gtkmain.h" */
|
||||||
|
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
@ -59,7 +60,6 @@
|
||||||
/* static guint gtkSetupClientSocket( GtkAppGlobals* globals, int sock ); */
|
/* static guint gtkSetupClientSocket( GtkAppGlobals* globals, int sock ); */
|
||||||
static void sendOnClose( XWStreamCtxt* stream, void* closure );
|
static void sendOnClose( XWStreamCtxt* stream, void* closure );
|
||||||
static XP_Bool file_exists( const char* fileName );
|
static XP_Bool file_exists( const char* fileName );
|
||||||
static void gtkListenOnSocket( GtkAppGlobals* globals, int newSock );
|
|
||||||
static void setCtrlsForTray( GtkAppGlobals* globals );
|
static void setCtrlsForTray( GtkAppGlobals* globals );
|
||||||
static void printFinalScores( GtkAppGlobals* globals );
|
static void printFinalScores( GtkAppGlobals* globals );
|
||||||
|
|
||||||
|
@ -317,6 +317,7 @@ createOrLoadObjects( GtkAppGlobals* globals )
|
||||||
XP_U16 gameID;
|
XP_U16 gameID;
|
||||||
CommsAddrRec addr;
|
CommsAddrRec addr;
|
||||||
|
|
||||||
|
XP_MEMSET( &addr, 0, sizeof(addr) );
|
||||||
addr.conType = params->conType;
|
addr.conType = params->conType;
|
||||||
|
|
||||||
gameID = (XP_U16)util_getCurSeconds( globals->cGlobals.params->util );
|
gameID = (XP_U16)util_getCurSeconds( globals->cGlobals.params->util );
|
||||||
|
@ -354,6 +355,12 @@ createOrLoadObjects( GtkAppGlobals* globals )
|
||||||
>= sizeof(params->connInfo.bt.hostAddr));
|
>= sizeof(params->connInfo.bt.hostAddr));
|
||||||
XP_MEMCPY( &addr.u.bt.btAddr, ¶ms->connInfo.bt.hostAddr,
|
XP_MEMCPY( &addr.u.bt.btAddr, ¶ms->connInfo.bt.hostAddr,
|
||||||
sizeof(params->connInfo.bt.hostAddr) );
|
sizeof(params->connInfo.bt.hostAddr) );
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
} else if ( addr.conType == COMMS_CONN_IP_DIRECT ) {
|
||||||
|
XP_STRNCPY( addr.u.ip.hostName_ip, params->connInfo.ip.hostName,
|
||||||
|
sizeof(addr.u.ip.hostName_ip) - 1 );
|
||||||
|
addr.u.ip.port_ip = params->connInfo.ip.port;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,6 +385,10 @@ createOrLoadObjects( GtkAppGlobals* globals )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !!globals->cGlobals.game.comms ) {
|
||||||
|
comms_start( globals->cGlobals.game.comms );
|
||||||
|
}
|
||||||
|
|
||||||
server_do( globals->cGlobals.game.server );
|
server_do( globals->cGlobals.game.server );
|
||||||
|
|
||||||
} /* createOrLoadObjects */
|
} /* createOrLoadObjects */
|
||||||
|
@ -548,6 +559,9 @@ quit( void* XP_UNUSED(dunno), GtkAppGlobals* globals )
|
||||||
|
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
linux_bt_close( &globals->cGlobals );
|
linux_bt_close( &globals->cGlobals );
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
linux_udp_close( &globals->cGlobals );
|
||||||
#endif
|
#endif
|
||||||
vtmgr_destroy( MEMPOOL globals->cGlobals.params->vtMgr );
|
vtmgr_destroy( MEMPOOL globals->cGlobals.params->vtMgr );
|
||||||
|
|
||||||
|
@ -1201,7 +1215,7 @@ score_timer_func( gpointer data )
|
||||||
return XP_FALSE;
|
return XP_FALSE;
|
||||||
} /* score_timer_func */
|
} /* score_timer_func */
|
||||||
|
|
||||||
#ifdef XWFEATURE_RELAY
|
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
|
||||||
static gint
|
static gint
|
||||||
heartbeat_timer_func( gpointer data )
|
heartbeat_timer_func( gpointer data )
|
||||||
{
|
{
|
||||||
|
@ -1217,7 +1231,7 @@ heartbeat_timer_func( gpointer data )
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
||||||
XP_U16 XP_UNUSED_RELAY(when),
|
XP_U16 when,
|
||||||
XWTimerProc proc, void* closure )
|
XWTimerProc proc, void* closure )
|
||||||
{
|
{
|
||||||
GtkAppGlobals* globals = (GtkAppGlobals*)uc->closure;
|
GtkAppGlobals* globals = (GtkAppGlobals*)uc->closure;
|
||||||
|
@ -1236,7 +1250,7 @@ gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
|
||||||
(void)gettimeofday( &globals->scoreTv, NULL );
|
(void)gettimeofday( &globals->scoreTv, NULL );
|
||||||
|
|
||||||
newSrc = g_timeout_add( 1000, score_timer_func, globals );
|
newSrc = g_timeout_add( 1000, score_timer_func, globals );
|
||||||
#ifdef XWFEATURE_RELAY
|
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
|
||||||
} else if ( why == TIMER_HEARTBEAT ) {
|
} else if ( why == TIMER_HEARTBEAT ) {
|
||||||
newSrc = g_timeout_add( 1000 * when, heartbeat_timer_func, globals );
|
newSrc = g_timeout_add( 1000 * when, heartbeat_timer_func, globals );
|
||||||
#endif
|
#endif
|
||||||
|
@ -1570,17 +1584,26 @@ newConnectionInput( GIOChannel *source,
|
||||||
if ( (condition & (G_IO_HUP | G_IO_ERR)) != 0 ) {
|
if ( (condition & (G_IO_HUP | G_IO_ERR)) != 0 ) {
|
||||||
XP_LOGF( "dropping socket %d", sock );
|
XP_LOGF( "dropping socket %d", sock );
|
||||||
close( sock );
|
close( sock );
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
globals->cGlobals.socket = -1;
|
globals->cGlobals.socket = -1;
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
|
||||||
if ( COMMS_CONN_BT == globals->cGlobals.params->conType ) {
|
|
||||||
linux_bt_socketclosed( &globals->cGlobals, sock );
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
if ( 0 ) {
|
||||||
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
|
} else if ( COMMS_CONN_BT == globals->cGlobals.params->conType ) {
|
||||||
|
linux_bt_socketclosed( &globals->cGlobals, sock );
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
} else if ( COMMS_CONN_IP_DIRECT == globals->cGlobals.params->conType ) {
|
||||||
|
linux_udp_socketclosed( &globals->cGlobals, sock );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
keepSource = FALSE; /* remove the event source */
|
keepSource = FALSE; /* remove the event source */
|
||||||
|
|
||||||
} else if ( (condition & G_IO_IN) != 0 ) {
|
} else if ( (condition & G_IO_IN) != 0 ) {
|
||||||
ssize_t nRead;
|
ssize_t nRead;
|
||||||
unsigned char buf[512];
|
unsigned char buf[512];
|
||||||
|
CommsAddrRec addr;
|
||||||
|
CommsAddrRec* addrp = NULL;
|
||||||
|
|
||||||
if ( 0 ) {
|
if ( 0 ) {
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
|
@ -1591,6 +1614,11 @@ newConnectionInput( GIOChannel *source,
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
} else if ( globals->cGlobals.params->conType == COMMS_CONN_BT ) {
|
} else if ( globals->cGlobals.params->conType == COMMS_CONN_BT ) {
|
||||||
nRead = linux_bt_receive( sock, buf, sizeof(buf) );
|
nRead = linux_bt_receive( sock, buf, sizeof(buf) );
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
} else if ( globals->cGlobals.params->conType == COMMS_CONN_IP_DIRECT ) {
|
||||||
|
addrp = &addr;
|
||||||
|
nRead = linux_udp_receive( sock, buf, sizeof(buf), addrp, &globals->cGlobals );
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
XP_ASSERT( 0 );
|
XP_ASSERT( 0 );
|
||||||
|
@ -1603,7 +1631,7 @@ newConnectionInput( GIOChannel *source,
|
||||||
inboundS = stream_from_msgbuf( &globals->cGlobals, buf, nRead );
|
inboundS = stream_from_msgbuf( &globals->cGlobals, buf, nRead );
|
||||||
if ( !!inboundS ) {
|
if ( !!inboundS ) {
|
||||||
if ( comms_checkIncomingStream( globals->cGlobals.game.comms,
|
if ( comms_checkIncomingStream( globals->cGlobals.game.comms,
|
||||||
inboundS, NULL ) ) {
|
inboundS, addrp ) ) {
|
||||||
redraw =
|
redraw =
|
||||||
server_receiveMessage(globals->cGlobals.game.server,
|
server_receiveMessage(globals->cGlobals.game.server,
|
||||||
inboundS );
|
inboundS );
|
||||||
|
@ -1631,40 +1659,50 @@ newConnectionInput( GIOChannel *source,
|
||||||
return keepSource; /* FALSE means to remove event source */
|
return keepSource; /* FALSE means to remove event source */
|
||||||
} /* newConnectionInput */
|
} /* newConnectionInput */
|
||||||
|
|
||||||
/* Make gtk listen for events on the socket that clients will use to
|
typedef struct SockInfo {
|
||||||
* connect to us.
|
GIOChannel* channel;
|
||||||
*/
|
guint watch;
|
||||||
static void
|
int socket;
|
||||||
gtkListenOnSocket( GtkAppGlobals* globals, int newSock )
|
} SockInfo;
|
||||||
{
|
|
||||||
|
|
||||||
GIOChannel* channel = g_io_channel_unix_new( newSock );
|
|
||||||
guint result = g_io_add_watch( channel,
|
|
||||||
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
|
|
||||||
newConnectionInput,
|
|
||||||
globals );
|
|
||||||
XP_LOGF( "g_io_add_watch(%d) => %d", newSock, result );
|
|
||||||
} /* gtkListenOnSocket */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_socket_changed( void* closure, int oldSock, int newSock )
|
gtk_socket_changed( void* closure, int oldSock, int newSock, void** storage )
|
||||||
{
|
{
|
||||||
GtkAppGlobals* globals = (GtkAppGlobals*)closure;
|
GtkAppGlobals* globals = (GtkAppGlobals*)closure;
|
||||||
|
SockInfo* info = (SockInfo*)*storage;
|
||||||
|
XP_LOGF( "%s(old:%d; new:%d)", __func__, oldSock, newSock );
|
||||||
|
|
||||||
if ( oldSock != -1 ) {
|
if ( oldSock != -1 ) {
|
||||||
g_source_remove( oldSock );
|
XP_ASSERT( info != NULL );
|
||||||
XP_LOGF( "Removed %d from gtk's list of listened-to sockets" );
|
g_source_remove( info->watch );
|
||||||
|
g_io_channel_unref( info->channel );
|
||||||
|
XP_FREE( globals->cGlobals.params->util->mpool, info );
|
||||||
|
*storage = NULL;
|
||||||
|
XP_LOGF( "Removed socket %d from gtk's list of listened-to sockets", oldSock );
|
||||||
}
|
}
|
||||||
if ( newSock != -1 ) {
|
if ( newSock != -1 ) {
|
||||||
gtkListenOnSocket( globals, newSock );
|
info = (SockInfo*)XP_MALLOC( globals->cGlobals.params->util->mpool,
|
||||||
|
sizeof(*info) );
|
||||||
|
GIOChannel* channel = g_io_channel_unix_new( newSock );
|
||||||
|
g_io_channel_set_close_on_unref( channel, TRUE );
|
||||||
|
guint result = g_io_add_watch( channel,
|
||||||
|
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
|
||||||
|
newConnectionInput,
|
||||||
|
globals );
|
||||||
|
info->channel = channel;
|
||||||
|
info->watch = result;
|
||||||
|
*storage = info;
|
||||||
|
XP_LOGF( "g_io_add_watch(%d) => %d", newSock, result );
|
||||||
}
|
}
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
globals->cGlobals.socket = newSock;
|
globals->cGlobals.socket = newSock;
|
||||||
|
#endif
|
||||||
/* A hack for the bluetooth case. */
|
/* A hack for the bluetooth case. */
|
||||||
CommsCtxt* comms = globals->cGlobals.game.comms;
|
CommsCtxt* comms = globals->cGlobals.game.comms;
|
||||||
if ( comms != NULL ) {
|
if ( (comms != NULL) && (comms_getConType(comms) == COMMS_CONN_BT) ) {
|
||||||
comms_resendAll( comms );
|
comms_resendAll( comms );
|
||||||
}
|
}
|
||||||
|
LOG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -1739,7 +1777,9 @@ gtkmain( LaunchParams* params, int argc, char *argv[] )
|
||||||
|
|
||||||
globals.cGlobals.params = params;
|
globals.cGlobals.params = params;
|
||||||
globals.cGlobals.lastNTilesToUse = MAX_TRAY_TILES;
|
globals.cGlobals.lastNTilesToUse = MAX_TRAY_TILES;
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
globals.cGlobals.socket = -1;
|
globals.cGlobals.socket = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
globals.cGlobals.socketChanged = gtk_socket_changed;
|
globals.cGlobals.socketChanged = gtk_socket_changed;
|
||||||
globals.cGlobals.socketChangedClosure = &globals;
|
globals.cGlobals.socketChangedClosure = &globals;
|
||||||
|
|
124
linux/linuxbt.c
124
linux/linuxbt.c
|
@ -42,7 +42,7 @@
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "strutils.h"
|
#include "strutils.h"
|
||||||
|
|
||||||
#define MAX_CLIENTS 3
|
#define MAX_CLIENTS 1
|
||||||
|
|
||||||
#if defined BT_USE_L2CAP
|
#if defined BT_USE_L2CAP
|
||||||
# define L2_RF_ADDR struct sockaddr_l2
|
# define L2_RF_ADDR struct sockaddr_l2
|
||||||
|
@ -50,81 +50,22 @@
|
||||||
# define L2_RF_ADDR struct sockaddr_rc
|
# define L2_RF_ADDR struct sockaddr_rc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct BtaddrSockMap {
|
|
||||||
bdaddr_t btaddr;
|
|
||||||
int sock;
|
|
||||||
} BtaddrSockMap;
|
|
||||||
|
|
||||||
typedef struct LinBtStuff {
|
typedef struct LinBtStuff {
|
||||||
CommonGlobals* globals;
|
CommonGlobals* globals;
|
||||||
|
void* sockStorage;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
BtaddrSockMap socks[MAX_CLIENTS];
|
|
||||||
int listener; /* socket */
|
int listener; /* socket */
|
||||||
XP_U16 nSocks;
|
|
||||||
XP_Bool threadDie;
|
XP_Bool threadDie;
|
||||||
sdp_session_t* session;
|
sdp_session_t* session;
|
||||||
} master;
|
} master;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
|
/* A single socket's fine as long as there's only one client allowed. */
|
||||||
|
int socket;
|
||||||
XP_Bool amMaster;
|
XP_Bool amMaster;
|
||||||
} LinBtStuff;
|
} LinBtStuff;
|
||||||
|
|
||||||
static void
|
|
||||||
lbt_addSock( LinBtStuff* btStuff, const bdaddr_t* btaddr, int sock )
|
|
||||||
{
|
|
||||||
XP_U16 i;
|
|
||||||
XP_Bool done = XP_FALSE;
|
|
||||||
|
|
||||||
XP_ASSERT( btStuff->amMaster );
|
|
||||||
XP_ASSERT( btStuff->u.master.nSocks < MAX_CLIENTS - 1 );
|
|
||||||
|
|
||||||
/* first look for an older entry for the same device. If found, close the
|
|
||||||
socket and replace. No change in nSocks. */
|
|
||||||
for ( i = 0; i < MAX_CLIENTS; ++i ) {
|
|
||||||
BtaddrSockMap* mp = &btStuff->u.master.socks[i];
|
|
||||||
if ( (mp->sock != -1) && (0 == memcmp( btaddr, &mp->btaddr, sizeof(*btaddr) )) ) {
|
|
||||||
(void)close( mp->sock );
|
|
||||||
mp->sock = sock;
|
|
||||||
done = XP_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !done ) {
|
|
||||||
for ( i = 0; i < MAX_CLIENTS; ++i ) {
|
|
||||||
BtaddrSockMap* mp = &btStuff->u.master.socks[i];
|
|
||||||
if ( mp->sock == -1 ) {
|
|
||||||
XP_MEMCPY( &mp->btaddr, btaddr, sizeof(mp->btaddr) );
|
|
||||||
mp->sock = sock;
|
|
||||||
++btStuff->u.master.nSocks;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XP_ASSERT( i < MAX_CLIENTS );
|
|
||||||
} /* lbt_addSock */
|
|
||||||
|
|
||||||
static void
|
|
||||||
lbt_removeSock( LinBtStuff* btStuff, int sock )
|
|
||||||
{
|
|
||||||
XP_U16 i;
|
|
||||||
|
|
||||||
XP_ASSERT( btStuff->amMaster );
|
|
||||||
|
|
||||||
for ( i = 0; i < MAX_CLIENTS; ++i ) {
|
|
||||||
BtaddrSockMap* mp = &btStuff->u.master.socks[i];
|
|
||||||
if ( mp->sock == sock ) {
|
|
||||||
mp->sock = -1;
|
|
||||||
XP_ASSERT( btStuff->u.master.nSocks > 0 );
|
|
||||||
--btStuff->u.master.nSocks;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* lbt_removeSock */
|
|
||||||
|
|
||||||
static LinBtStuff*
|
static LinBtStuff*
|
||||||
lbt_make( MPFORMAL XP_Bool amMaster )
|
lbt_make( MPFORMAL XP_Bool amMaster )
|
||||||
{
|
{
|
||||||
|
@ -132,13 +73,7 @@ lbt_make( MPFORMAL XP_Bool amMaster )
|
||||||
XP_MEMSET( btStuff, 0, sizeof(*btStuff) );
|
XP_MEMSET( btStuff, 0, sizeof(*btStuff) );
|
||||||
|
|
||||||
btStuff->amMaster = amMaster;
|
btStuff->amMaster = amMaster;
|
||||||
|
btStuff->socket = -1;
|
||||||
if ( amMaster ) {
|
|
||||||
XP_U16 i;
|
|
||||||
for ( i = 0; i < MAX_CLIENTS; ++i ) {
|
|
||||||
btStuff->u.master.socks[i].sock = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return btStuff;
|
return btStuff;
|
||||||
} /* lbt_make */
|
} /* lbt_make */
|
||||||
|
@ -217,6 +152,7 @@ getL2Addr( const CommsAddrRec const* addrP, L2_RF_ADDR* const saddr )
|
||||||
sdp_close( session );
|
sdp_close( session );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_RETURNF( "%p", result );
|
||||||
return result;
|
return result;
|
||||||
} /* getL2Addr */
|
} /* getL2Addr */
|
||||||
|
|
||||||
|
@ -224,6 +160,7 @@ static void
|
||||||
lbt_connectSocket( LinBtStuff* btStuff, const CommsAddrRec* addrP )
|
lbt_connectSocket( LinBtStuff* btStuff, const CommsAddrRec* addrP )
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
|
LOG_FUNC();
|
||||||
|
|
||||||
// allocate a socket
|
// allocate a socket
|
||||||
sock = socket( AF_BLUETOOTH,
|
sock = socket( AF_BLUETOOTH,
|
||||||
|
@ -244,7 +181,8 @@ lbt_connectSocket( LinBtStuff* btStuff, const CommsAddrRec* addrP )
|
||||||
&& (0 == connect( sock, (struct sockaddr *)&saddr, sizeof(saddr) )) ) {
|
&& (0 == connect( sock, (struct sockaddr *)&saddr, sizeof(saddr) )) ) {
|
||||||
CommonGlobals* globals = btStuff->globals;
|
CommonGlobals* globals = btStuff->globals;
|
||||||
(*globals->socketChanged)( globals->socketChangedClosure,
|
(*globals->socketChanged)( globals->socketChangedClosure,
|
||||||
-1, sock );
|
-1, sock, &btStuff->sockStorage );
|
||||||
|
btStuff->socket = sock;
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "%s: connect->%s; closing socket %d", __FUNCTION__, strerror(errno), sock );
|
XP_LOGF( "%s: connect->%s; closing socket %d", __FUNCTION__, strerror(errno), sock );
|
||||||
close( sock );
|
close( sock );
|
||||||
|
@ -272,13 +210,10 @@ lbt_accept( int listener, void* ctxt )
|
||||||
|
|
||||||
success = sock >= 0;
|
success = sock >= 0;
|
||||||
if ( success ) {
|
if ( success ) {
|
||||||
#if defined BT_USE_L2CAP
|
|
||||||
lbt_addSock( btStuff, &inaddr.l2_bdaddr, sock );
|
|
||||||
#elif defined BT_USE_RFCOMM
|
|
||||||
lbt_addSock( btStuff, &inaddr.rc_bdaddr, sock );
|
|
||||||
#endif
|
|
||||||
(*globals->socketChanged)( globals->socketChangedClosure,
|
(*globals->socketChanged)( globals->socketChangedClosure,
|
||||||
-1, sock );
|
-1, sock, &btStuff->sockStorage );
|
||||||
|
XP_ASSERT( btStuff->socket == -1 );
|
||||||
|
btStuff->socket = sock;
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "%s: accept->%s", __FUNCTION__, strerror(errno) );
|
XP_LOGF( "%s: accept->%s", __FUNCTION__, strerror(errno) );
|
||||||
}
|
}
|
||||||
|
@ -423,12 +358,14 @@ linux_bt_open( CommonGlobals* globals, XP_Bool amMaster )
|
||||||
btStuff = globals->btStuff
|
btStuff = globals->btStuff
|
||||||
= lbt_make( MPPARM(globals->params->util->mpool) amMaster );
|
= lbt_make( MPPARM(globals->params->util->mpool) amMaster );
|
||||||
btStuff->globals = globals;
|
btStuff->globals = globals;
|
||||||
|
btStuff->socket = -1;
|
||||||
|
|
||||||
globals->btStuff = btStuff;
|
globals->btStuff = btStuff;
|
||||||
|
|
||||||
if ( amMaster ) {
|
if ( amMaster ) {
|
||||||
lbt_listenerSetup( globals );
|
lbt_listenerSetup( globals );
|
||||||
} else {
|
} else {
|
||||||
if ( globals->socket < 0 ) {
|
if ( btStuff->socket < 0 ) {
|
||||||
CommsAddrRec addr;
|
CommsAddrRec addr;
|
||||||
comms_getAddr( globals->game.comms, &addr );
|
comms_getAddr( globals->game.comms, &addr );
|
||||||
lbt_connectSocket( btStuff, &addr );
|
lbt_connectSocket( btStuff, &addr );
|
||||||
|
@ -451,7 +388,6 @@ void
|
||||||
linux_bt_close( CommonGlobals* globals )
|
linux_bt_close( CommonGlobals* globals )
|
||||||
{
|
{
|
||||||
LinBtStuff* btStuff = globals->btStuff;
|
LinBtStuff* btStuff = globals->btStuff;
|
||||||
XP_U16 i;
|
|
||||||
|
|
||||||
if ( !!btStuff ) {
|
if ( !!btStuff ) {
|
||||||
if ( btStuff->amMaster ) {
|
if ( btStuff->amMaster ) {
|
||||||
|
@ -459,18 +395,17 @@ linux_bt_close( CommonGlobals* globals )
|
||||||
close( btStuff->u.master.listener );
|
close( btStuff->u.master.listener );
|
||||||
btStuff->u.master.listener = -1;
|
btStuff->u.master.listener = -1;
|
||||||
|
|
||||||
for ( i = 0; i < MAX_CLIENTS; ++i ) {
|
|
||||||
BtaddrSockMap* mp = &btStuff->u.master.socks[i];
|
|
||||||
if ( mp->sock != -1 ) {
|
|
||||||
XP_LOGF( "%s: closing data socket %d", __func__, mp->sock );
|
|
||||||
(void)close( mp->sock );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sdp_close( btStuff->u.master.session );
|
sdp_close( btStuff->u.master.session );
|
||||||
XP_LOGF( "sleeping for Palm's sake..." );
|
XP_LOGF( "sleeping for Palm's sake..." );
|
||||||
sleep( 2 ); /* see if this gives palm a chance to not hang */
|
sleep( 2 ); /* see if this gives palm a chance to not hang */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( btStuff->socket != -1 ) {
|
||||||
|
(*globals->socketChanged)( globals->socketChangedClosure,
|
||||||
|
btStuff->socket, -1, &btStuff->sockStorage );
|
||||||
|
(void)close( btStuff->socket );
|
||||||
|
}
|
||||||
|
|
||||||
XP_FREE( globals->params->util->mpool, btStuff );
|
XP_FREE( globals->params->util->mpool, btStuff );
|
||||||
globals->btStuff = NULL;
|
globals->btStuff = NULL;
|
||||||
}
|
}
|
||||||
|
@ -495,17 +430,17 @@ linux_bt_send( const XP_U8* buf, XP_U16 buflen,
|
||||||
addrP = &addr;
|
addrP = &addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( globals->socket < 0 && !btStuff->amMaster ) {
|
if ( btStuff->socket < 0 && !btStuff->amMaster ) {
|
||||||
lbt_connectSocket( btStuff, addrP );
|
lbt_connectSocket( btStuff, addrP );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( globals->socket >= 0 ) {
|
if ( btStuff->socket >= 0 ) {
|
||||||
#if defined BT_USE_RFCOMM
|
#if defined BT_USE_RFCOMM
|
||||||
unsigned short len = htons(buflen);
|
unsigned short len = htons(buflen);
|
||||||
nSent = write( globals->socket, &len, sizeof(len) );
|
nSent = write( btStuff->socket, &len, sizeof(len) );
|
||||||
assert( nSent == sizeof(len) );
|
assert( nSent == sizeof(len) );
|
||||||
#endif
|
#endif
|
||||||
nSent = write( globals->socket, buf, buflen );
|
nSent = write( btStuff->socket, buf, buflen );
|
||||||
if ( nSent < 0 ) {
|
if ( nSent < 0 ) {
|
||||||
XP_LOGF( "%s: send->%s", __FUNCTION__, strerror(errno) );
|
XP_LOGF( "%s: send->%s", __FUNCTION__, strerror(errno) );
|
||||||
} else if ( nSent < buflen ) {
|
} else if ( nSent < buflen ) {
|
||||||
|
@ -569,10 +504,9 @@ void
|
||||||
linux_bt_socketclosed( CommonGlobals* globals, int sock )
|
linux_bt_socketclosed( CommonGlobals* globals, int sock )
|
||||||
{
|
{
|
||||||
LinBtStuff* btStuff = globals->btStuff;
|
LinBtStuff* btStuff = globals->btStuff;
|
||||||
if ( btStuff->amMaster ) {
|
LOG_FUNC();
|
||||||
lbt_removeSock( btStuff, sock );
|
XP_ASSERT( sock == btStuff->socket );
|
||||||
}
|
btStuff->socket = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* XWFEATURE_BLUETOOTH */
|
#endif /* XWFEATURE_BLUETOOTH */
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
#include "linuxmain.h"
|
#include "linuxmain.h"
|
||||||
#include "linuxbt.h"
|
#include "linuxbt.h"
|
||||||
|
#include "linuxudp.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#ifdef PLATFORM_NCURSES
|
#ifdef PLATFORM_NCURSES
|
||||||
# include "cursesmain.h"
|
# include "cursesmain.h"
|
||||||
|
@ -57,7 +58,7 @@
|
||||||
#include "memstream.h"
|
#include "memstream.h"
|
||||||
#include "LocalizedStrIncludes.h"
|
#include "LocalizedStrIncludes.h"
|
||||||
|
|
||||||
#define DEFAULT_SEND_PORT 10999
|
#define DEFAULT_PORT 10999
|
||||||
#define DEFAULT_LISTEN_PORT 4998
|
#define DEFAULT_LISTEN_PORT 4998
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -266,24 +267,30 @@ usage( char* appName, char* msg )
|
||||||
"\t [-B n:name|a:00:11:22:33:44:55]\n"
|
"\t [-B n:name|a:00:11:22:33:44:55]\n"
|
||||||
"\t\t\t# connect via bluetooth [param ignored if -s]\n"
|
"\t\t\t# connect via bluetooth [param ignored if -s]\n"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
"\t [-D host_addr]\t\t\tConnect directly to host [param ignored if -s]\n"
|
||||||
|
"\t [-p host_port] # put/look for host on this port\n"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* "# --------------- OR client-only ----------\n" */
|
/* "# --------------- OR client-only ----------\n" */
|
||||||
/* "\t [-p client_port] # must != server's port if on same device" */
|
/* "\t [-p client_port] # must != server's port if on same device" */
|
||||||
"\nexample: \n"
|
|
||||||
"\tserver: ./xwords -d dict.xwd -s -r Eric -N"
|
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
" -a localhost -p 10999"
|
"\nrelay example: \n"
|
||||||
|
"\t host: ./xwords -d dict.xwd -r Eric -s -N -a localhost -p 10999 -C COOKIE\n"
|
||||||
|
"\tguest: ./xwords -d dict.xwd -r Kati -a localhost -p 10999 -C COOKIE"
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
" -B ignored "
|
"\nBluetooth example: \n"
|
||||||
|
"\t host: ./xwords -d dict.xwd -r Eric -s -N -B ignored\n"
|
||||||
|
"\tguest: ./xwords -d dict.xwd -r Kati -B n:treo_bt_name (OR b:11:22:33:44:55:66)"
|
||||||
#endif
|
#endif
|
||||||
"\n"
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
"\tclient: ./xwords -d dict.xwd -r Kati"
|
"\nDirect example: \n"
|
||||||
#ifdef XWFEATURE_RELAY
|
"\t host: ./xwords -d dict.xwd -r Eric -s -N -N -D localhost -p 10999\n"
|
||||||
" -a localhost -p 10999"
|
"\tguest: ./xwords -d dict.xwd -r Kati -D localhost -p 10999\n"
|
||||||
#endif
|
"\tguest: ./xwords -d dict.xwd -r Ariynn -D localhost -p 10999"
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
|
||||||
" -B a:11:22:33:44:55:66 | n:my_treo "
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
"\n"
|
"\n"
|
||||||
, appName );
|
, appName );
|
||||||
fprintf( stderr, "\n(revision: %s)\n", SVN_REV);
|
fprintf( stderr, "\n(revision: %s)\n", SVN_REV);
|
||||||
|
@ -394,7 +401,8 @@ linux_tcp_send( const XP_U8* buf, XP_U16 buflen,
|
||||||
if ( socket != -1 ) {
|
if ( socket != -1 ) {
|
||||||
assert( globals->socket == socket );
|
assert( globals->socket == socket );
|
||||||
(*globals->socketChanged)( globals->socketChangedClosure,
|
(*globals->socketChanged)( globals->socketChangedClosure,
|
||||||
-1, socket );
|
-1, socket,
|
||||||
|
&globals->storage );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +418,7 @@ linux_tcp_send( const XP_U8* buf, XP_U16 buflen,
|
||||||
XP_STATUSF( "closing non-functional socket" );
|
XP_STATUSF( "closing non-functional socket" );
|
||||||
close( socket );
|
close( socket );
|
||||||
(*globals->socketChanged)( globals->socketChangedClosure,
|
(*globals->socketChanged)( globals->socketChangedClosure,
|
||||||
socket, -1 );
|
socket, -1, &globals->storage );
|
||||||
globals->socket = -1;
|
globals->socket = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +428,17 @@ linux_tcp_send( const XP_U8* buf, XP_U16 buflen,
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} /* linux_tcp_send */
|
} /* linux_tcp_send */
|
||||||
#endif
|
|
||||||
|
static void
|
||||||
|
linux_tcp_reset( CommonGlobals* globals )
|
||||||
|
{
|
||||||
|
LOG_FUNC();
|
||||||
|
if ( globals->socket != -1 ) {
|
||||||
|
(void)close( globals->socket );
|
||||||
|
globals->socket = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* XWFEATURE_RELAY */
|
||||||
|
|
||||||
#ifdef COMMS_HEARTBEAT
|
#ifdef COMMS_HEARTBEAT
|
||||||
void
|
void
|
||||||
|
@ -432,6 +450,14 @@ linux_reset( void* closure )
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
} else if ( conType == COMMS_CONN_BT ) {
|
} else if ( conType == COMMS_CONN_BT ) {
|
||||||
linux_bt_reset( globals );
|
linux_bt_reset( globals );
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
} else if ( conType == COMMS_CONN_IP_DIRECT ) {
|
||||||
|
linux_udp_reset( globals );
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
|
} else if ( conType == COMMS_CONN_RELAY ) {
|
||||||
|
linux_tcp_reset( globals );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,11 +484,18 @@ linux_send( const XP_U8* buf, XP_U16 buflen,
|
||||||
} else if ( conType == COMMS_CONN_RELAY ) {
|
} else if ( conType == COMMS_CONN_RELAY ) {
|
||||||
nSent = linux_tcp_send( buf, buflen, addrRec, globals );
|
nSent = linux_tcp_send( buf, buflen, addrRec, globals );
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#if defined XWFEATURE_BLUETOOTH
|
||||||
} else if ( conType == COMMS_CONN_BT ) {
|
} else if ( conType == COMMS_CONN_BT ) {
|
||||||
XP_Bool isServer = comms_getIsServer( globals->game.comms );
|
XP_Bool isServer = comms_getIsServer( globals->game.comms );
|
||||||
linux_bt_open( globals, isServer );
|
linux_bt_open( globals, isServer );
|
||||||
nSent = linux_bt_send( buf, buflen, addrRec, globals );
|
nSent = linux_bt_send( buf, buflen, addrRec, globals );
|
||||||
|
#endif
|
||||||
|
#if defined XWFEATURE_IP_DIRECT
|
||||||
|
} else if ( conType == COMMS_CONN_IP_DIRECT ) {
|
||||||
|
CommsAddrRec addr;
|
||||||
|
comms_getAddr( globals->game.comms, &addr );
|
||||||
|
linux_udp_open( globals, &addr );
|
||||||
|
nSent = linux_udp_send( buf, buflen, addrRec, globals );
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
XP_ASSERT(0);
|
XP_ASSERT(0);
|
||||||
|
@ -470,6 +503,7 @@ linux_send( const XP_U8* buf, XP_U16 buflen,
|
||||||
return nSent;
|
return nSent;
|
||||||
} /* linux_send */
|
} /* linux_send */
|
||||||
|
|
||||||
|
#ifdef XWFEATURE_RELAY
|
||||||
static void
|
static void
|
||||||
linux_close_socket( CommonGlobals* cGlobals )
|
linux_close_socket( CommonGlobals* cGlobals )
|
||||||
{
|
{
|
||||||
|
@ -502,6 +536,7 @@ linux_relay_receive( CommonGlobals* cGlobals, unsigned char* buf, int bufSize )
|
||||||
}
|
}
|
||||||
return nRead;
|
return nRead;
|
||||||
} /* linuxReceive */
|
} /* linuxReceive */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Create a stream for the incoming message buffer, and read in any
|
/* Create a stream for the incoming message buffer, and read in any
|
||||||
information specific to our platform's comms layer (return address, say)
|
information specific to our platform's comms layer (return address, say)
|
||||||
|
@ -684,9 +719,9 @@ linux_util_getUserString( XW_UtilCtxt* XP_UNUSED(uc), XP_U16 code )
|
||||||
|
|
||||||
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_RELAY
|
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_RELAY
|
||||||
static void
|
static void
|
||||||
linux_util_addrChange( XW_UtilCtxt* XP_UNUSED_BT(uc),
|
linux_util_addrChange( XW_UtilCtxt* uc,
|
||||||
const CommsAddrRec* XP_UNUSED(oldAddr),
|
const CommsAddrRec* XP_UNUSED(oldAddr),
|
||||||
const CommsAddrRec* XP_UNUSED_BT(newAddr) )
|
const CommsAddrRec* newAddr )
|
||||||
{
|
{
|
||||||
if ( 0 ) {
|
if ( 0 ) {
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
|
@ -694,6 +729,11 @@ linux_util_addrChange( XW_UtilCtxt* XP_UNUSED_BT(uc),
|
||||||
CommonGlobals* cGlobals = (CommonGlobals*)uc->closure;
|
CommonGlobals* cGlobals = (CommonGlobals*)uc->closure;
|
||||||
XP_Bool isServer = comms_getIsServer( cGlobals->game.comms );
|
XP_Bool isServer = comms_getIsServer( cGlobals->game.comms );
|
||||||
linux_bt_open( cGlobals, isServer );
|
linux_bt_open( cGlobals, isServer );
|
||||||
|
#endif
|
||||||
|
#if defined XWFEATURE_IP_DIRECT
|
||||||
|
} else if ( newAddr->conType == COMMS_CONN_IP_DIRECT ) {
|
||||||
|
CommonGlobals* cGlobals = (CommonGlobals*)uc->closure;
|
||||||
|
linux_udp_open( cGlobals, newAddr );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -757,8 +797,8 @@ main( int argc, char** argv )
|
||||||
int opt;
|
int opt;
|
||||||
int totalPlayerCount = 0;
|
int totalPlayerCount = 0;
|
||||||
XP_Bool isServer = XP_FALSE;
|
XP_Bool isServer = XP_FALSE;
|
||||||
char* sendPortNumString = NULL;
|
char* portNum = "10999";
|
||||||
char* relayName = "localhost";
|
char* hostName = "localhost";
|
||||||
unsigned int seed = defaultRandomSeed();
|
unsigned int seed = defaultRandomSeed();
|
||||||
LaunchParams mainParams;
|
LaunchParams mainParams;
|
||||||
XP_U16 robotCount = 0;
|
XP_U16 robotCount = 0;
|
||||||
|
@ -798,9 +838,12 @@ main( int argc, char** argv )
|
||||||
|
|
||||||
/* defaults */
|
/* defaults */
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
mainParams.connInfo.relay.defaultListenPort = DEFAULT_LISTEN_PORT;
|
mainParams.connInfo.relay.defaultSendPort = DEFAULT_PORT;
|
||||||
mainParams.connInfo.relay.defaultSendPort = DEFAULT_SEND_PORT;
|
|
||||||
mainParams.connInfo.relay.cookie = "COOKIE";
|
mainParams.connInfo.relay.cookie = "COOKIE";
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
mainParams.connInfo.ip.port = DEFAULT_PORT;
|
||||||
|
mainParams.connInfo.ip.hostName = "localhost";
|
||||||
#endif
|
#endif
|
||||||
mainParams.gi.boardSize = 15;
|
mainParams.gi.boardSize = 15;
|
||||||
mainParams.quitAfter = XP_FALSE;
|
mainParams.quitAfter = XP_FALSE;
|
||||||
|
@ -837,8 +880,14 @@ main( int argc, char** argv )
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
"a:p:C:H"
|
"a:p:C:H"
|
||||||
#endif
|
#endif
|
||||||
|
#if defined XWFEATURE_RELAY || defined XWFEATURE_IP_DIRECT
|
||||||
|
"p:"
|
||||||
|
#endif
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
"B:"
|
"B:"
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
"D:"
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
switch( opt ) {
|
switch( opt ) {
|
||||||
|
@ -856,6 +905,12 @@ main( int argc, char** argv )
|
||||||
conType = COMMS_CONN_RELAY;
|
conType = COMMS_CONN_RELAY;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case 'D':
|
||||||
|
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
|
||||||
|
conType == COMMS_CONN_IP_DIRECT );
|
||||||
|
hostName = optarg;
|
||||||
|
conType = COMMS_CONN_IP_DIRECT;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
mainParams.gi.dictName = copyString( mainParams.util->mpool,
|
mainParams.gi.dictName = copyString( mainParams.util->mpool,
|
||||||
(XP_UCHAR*)optarg );
|
(XP_UCHAR*)optarg );
|
||||||
|
@ -893,10 +948,8 @@ main( int argc, char** argv )
|
||||||
++mainParams.info.serverInfo.nRemotePlayers;
|
++mainParams.info.serverInfo.nRemotePlayers;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
sendPortNumString = optarg;
|
/* could be RELAY or IP_DIRECT */
|
||||||
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
|
portNum = optarg;
|
||||||
conType == COMMS_CONN_RELAY );
|
|
||||||
conType = COMMS_CONN_RELAY;
|
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
++robotCount;
|
++robotCount;
|
||||||
|
@ -928,7 +981,7 @@ main( int argc, char** argv )
|
||||||
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
|
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
|
||||||
conType == COMMS_CONN_RELAY );
|
conType == COMMS_CONN_RELAY );
|
||||||
conType = COMMS_CONN_RELAY;
|
conType = COMMS_CONN_RELAY;
|
||||||
relayName = optarg;
|
hostName = optarg;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
mainParams.quitAfter = XP_TRUE;
|
mainParams.quitAfter = XP_TRUE;
|
||||||
|
@ -1015,12 +1068,19 @@ main( int argc, char** argv )
|
||||||
if ( 0 ) {
|
if ( 0 ) {
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
} else if ( conType == COMMS_CONN_RELAY ) {
|
} else if ( conType == COMMS_CONN_RELAY ) {
|
||||||
mainParams.connInfo.relay.relayName = relayName;
|
mainParams.connInfo.relay.relayName = hostName;
|
||||||
|
|
||||||
/* convert strings to whatever */
|
/* convert strings to whatever */
|
||||||
if ( sendPortNumString != NULL ) {
|
if ( portNum != NULL ) {
|
||||||
mainParams.connInfo.relay.defaultSendPort =
|
mainParams.connInfo.relay.defaultSendPort =
|
||||||
atoi( sendPortNumString );
|
atoi( portNum );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
} else if ( conType == COMMS_CONN_IP_DIRECT ) {
|
||||||
|
mainParams.connInfo.ip.hostName = hostName;
|
||||||
|
if ( portNum != NULL ) {
|
||||||
|
mainParams.connInfo.ip.port = atoi( portNum );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
|
|
25
linux/main.h
25
linux/main.h
|
@ -65,19 +65,24 @@ typedef struct LaunchParams {
|
||||||
DeviceRole serverRole;
|
DeviceRole serverRole;
|
||||||
|
|
||||||
CommsConnType conType;
|
CommsConnType conType;
|
||||||
union {
|
struct {
|
||||||
#ifdef XWFEATURE_RELAY
|
#ifdef XWFEATURE_RELAY
|
||||||
struct {
|
struct {
|
||||||
char* relayName;
|
char* relayName;
|
||||||
char* cookie;
|
char* cookie;
|
||||||
short defaultSendPort;
|
short defaultSendPort;
|
||||||
short defaultListenPort;
|
|
||||||
} relay;
|
} relay;
|
||||||
#endif
|
#endif
|
||||||
#ifdef XWFEATURE_BLUETOOTH
|
#ifdef XWFEATURE_BLUETOOTH
|
||||||
struct {
|
struct {
|
||||||
bdaddr_t hostAddr; /* unused if a host */
|
bdaddr_t hostAddr; /* unused if a host */
|
||||||
} bt;
|
} bt;
|
||||||
|
#endif
|
||||||
|
#ifdef XWFEATURE_IP_DIRECT
|
||||||
|
struct {
|
||||||
|
const char* hostName;
|
||||||
|
int port;
|
||||||
|
} ip;
|
||||||
#endif
|
#endif
|
||||||
} connInfo;
|
} connInfo;
|
||||||
|
|
||||||
|
@ -90,7 +95,8 @@ typedef struct LaunchParams {
|
||||||
|
|
||||||
typedef struct CommonGlobals CommonGlobals;
|
typedef struct CommonGlobals CommonGlobals;
|
||||||
|
|
||||||
typedef void (*SocketChangedFunc)(void* closure, int oldsock, int newsock );
|
typedef void (*SocketChangedFunc)(void* closure, int oldsock, int newsock,
|
||||||
|
void** storage );
|
||||||
typedef XP_Bool (*Acceptor)( int sock, void* ctxt );
|
typedef XP_Bool (*Acceptor)( int sock, void* ctxt );
|
||||||
typedef void (*AddAcceptorFunc)(int listener, Acceptor func,
|
typedef void (*AddAcceptorFunc)(int listener, Acceptor func,
|
||||||
CommonGlobals* globals );
|
CommonGlobals* globals );
|
||||||
|
@ -109,13 +115,18 @@ struct CommonGlobals {
|
||||||
AddAcceptorFunc addAcceptor;
|
AddAcceptorFunc addAcceptor;
|
||||||
Acceptor acceptor;
|
Acceptor acceptor;
|
||||||
|
|
||||||
int socket; /* either relay or bt */
|
#ifdef XWFEATURE_RELAY
|
||||||
|
int socket; /* relay */
|
||||||
/* Used only for relay case */
|
void* storage;
|
||||||
char* defaultServerName;
|
char* defaultServerName;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Used only for bluetooth case */
|
#if defined XWFEATURE_BLUETOOTH
|
||||||
struct LinBtStuff* btStuff;
|
struct LinBtStuff* btStuff;
|
||||||
|
#endif
|
||||||
|
#if defined XWFEATURE_IP_DIRECT
|
||||||
|
struct LinUDPStuff* udpStuff;
|
||||||
|
#endif
|
||||||
|
|
||||||
XWTimerProc timerProcs[NUM_TIMERS_PLUS_ONE];
|
XWTimerProc timerProcs[NUM_TIMERS_PLUS_ONE];
|
||||||
void* timerClosures[NUM_TIMERS_PLUS_ONE];
|
void* timerClosures[NUM_TIMERS_PLUS_ONE];
|
||||||
|
|
Loading…
Reference in a new issue