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:
ehouse 2007-11-26 02:58:25 +00:00
parent 044a889d6d
commit 42615345c9
8 changed files with 373 additions and 264 deletions

View file

@ -53,14 +53,15 @@ typedef struct MsgQueueElem {
XP_U8* msg;
XP_U16 len;
XP_U16 channelNo;
XP_U16 sendCount; /* how many times sent? */
MsgID msgID; /* saved for ease of deletion */
} MsgQueueElem;
typedef struct AddressRecord {
struct AddressRecord* next;
CommsAddrRec addr;
#ifdef DEBUG
XP_U16 lastACK;
#ifdef DEBUG
XP_U16 nUniqueBytes;
#endif
MsgID nextMsgID; /* on a per-channel basis */
@ -136,11 +137,12 @@ struct CommsCtxt {
MPSLOT
};
#ifdef XWFEATURE_BLUETOOTH
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
typedef enum {
BTMSG_DATA = 0
,BTMSG_RESET
} BTMsgType;
BTIPMSG_NONE = 0
,BTIPMSG_DATA
,BTIPMSG_RESET
} BTIPMsgType;
#endif
/****************************************************************************
@ -157,6 +159,8 @@ static AddressRecord* getRecordFor( CommsCtxt* comms,
static XP_S16 sendMsg( CommsCtxt* comms, MsgQueueElem* elem );
static void addToQueue( CommsCtxt* comms, MsgQueueElem* newMsgElem );
static XP_U16 countAddrRecs( const CommsCtxt* comms );
static void sendConnect( CommsCtxt* comms );
#ifdef XWFEATURE_RELAY
static void relayConnect( CommsCtxt* comms );
static void relayDisconnect( CommsCtxt* comms );
@ -166,12 +170,13 @@ static XWHostID getDestID( CommsCtxt* comms, XP_PlayerAddr channelNo );
#endif
#if defined XWFEATURE_RELAY || defined COMMS_HEARTBEAT
static void setHeartbeatTimer( CommsCtxt* comms );
#else
# define setHeartbeatTimer( comms )
#endif
#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 );
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
static XP_S16 send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType typ,
XP_PlayerAddr channelNo,
void* data, int dlen );
#endif
/****************************************************************************
@ -299,7 +304,7 @@ addrFromStream( CommsAddrRec* addrP, XWStreamCtxt* stream )
case COMMS_CONN_IR:
/* nothing to save */
break;
case COMMS_CONN_IP_NOUSE:
case COMMS_CONN_IP_DIRECT:
stringFromStreamHere( stream, addr.u.ip.hostName_ip,
sizeof(addr.u.ip.hostName_ip) );
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->msgID = stream_getU32( stream );
#ifdef COMMS_HEARTBEAT
msg->sendCount = 0;
#endif
msg->len = stream_getU16( stream );
msg->msg = (XP_U8*)XP_MALLOC( mpool, msg->len );
stream_getBytes( stream, msg->msg, msg->len );
@ -419,21 +426,36 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util,
void
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
comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR;
#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 */
static void
@ -460,7 +482,7 @@ addrToStream( XWStreamCtxt* stream, const CommsAddrRec* addrP )
case COMMS_CONN_IR:
/* nothing to save */
break;
case COMMS_CONN_IP_NOUSE:
case COMMS_CONN_IP_DIRECT:
stringToStream( stream, addr.u.ip.hostName_ip );
stream_putU32( stream, addr.u.ip.ipAddr_ip );
stream_putU16( stream, addr.u.ip.port_ip );
@ -546,22 +568,16 @@ void
comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr )
{
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 );
#endif
XP_MEMCPY( &comms->addr, addr, sizeof(comms->addr) );
if ( 0 ) {
#ifdef XWFEATURE_RELAY
/* We should now have a cookie so we can connect??? */
} else if ( addr->conType == COMMS_CONN_RELAY ) {
relayConnect( comms );
#ifdef COMMS_HEARTBEAT
comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR;
#endif
#ifdef XWFEATURE_BLUETOOTH
} else if ( addr->conType == COMMS_CONN_BT ) {
btConnect( comms );
#endif
}
sendConnect( comms );
#ifdef COMMS_HEARTBEAT
comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR;
#endif
@ -601,9 +617,9 @@ comms_getIsServer( const CommsCtxt* comms )
return comms->isServer;
}
static XP_S16
sendWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
XP_PlayerAddr channelNo, XWStreamCtxt* stream )
static MsgQueueElem*
makeElemWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
XP_PlayerAddr channelNo, XWStreamCtxt* stream )
{
XP_U16 headerLen;
XP_U16 streamSize = NULL == stream? 0 : stream_getSize( stream );
@ -623,6 +639,9 @@ sendWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
sizeof( *newMsgElem ) );
newMsgElem->channelNo = channelNo;
newMsgElem->msgID = msgID;
#ifdef COMMS_HEARTBEAT
newMsgElem->sendCount = 0;
#endif
msgStream = mem_stream_make( MPPARM(comms->mpool)
util_getVTManager(comms->util),
@ -646,10 +665,8 @@ sendWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
stream_getBytes( stream, newMsgElem->msg + headerLen, streamSize );
}
addToQueue( comms, newMsgElem );
return sendMsg( comms, newMsgElem );
} /* sendWithID */
return newMsgElem;
} /* makeElemWithID */
/* Send a message using the sequentially next MsgID. Save the message so
* resend can work. */
@ -659,9 +676,17 @@ comms_send( CommsCtxt* comms, XWStreamCtxt* stream )
XP_PlayerAddr channelNo = stream_getAddress( stream );
AddressRecord* rec = getRecordFor( comms, channelNo );
MsgID msgID = (!!rec)? ++rec->nextMsgID : 0;
MsgQueueElem* elem;
XP_S16 result = -1;
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 */
/* 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
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
* 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
@ -737,8 +769,7 @@ removeFromQueue( CommsCtxt* comms, XP_PlayerAddr channelNo, MsgID msgID )
}
if ( !knownGood && (elem->msgID <= msgID) ) {
XP_FREE( comms->mpool, elem->msg );
XP_FREE( comms->mpool, elem );
freeElem( comms, elem );
--comms->queueLen;
} else {
keep->next = elem;
@ -762,7 +793,7 @@ removeFromQueue( CommsCtxt* comms, XP_PlayerAddr channelNo, MsgID msgID )
static XP_S16
sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
{
XP_S16 result = 0;
XP_S16 result = -1;
XP_PlayerAddr channelNo;
#if defined XWFEATURE_RELAY || defined XWFEATURE_BLUETOOTH
CommsConnType conType = comms_getConType( comms );
@ -781,10 +812,13 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
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 );
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
} else if ( conType == COMMS_CONN_BT || conType == COMMS_CONN_IP_DIRECT ) {
result = send_via_bt_or_ip( comms, BTIPMSG_DATA, channelNo,
elem->msg, elem->len );
#ifdef COMMS_HEARTBEAT
setHeartbeatTimer( comms );
#endif
#endif
} else {
const CommsAddrRec* addr;
@ -794,6 +828,12 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
result = (*comms->sendproc)( elem->msg, elem->len, addr,
comms->sendClosure );
}
if ( result == elem->len ) {
++elem->sendCount;
XP_LOGF( "sendCount now %d", elem->sendCount );
}
return result;
} /* sendMsg */
@ -898,22 +938,51 @@ relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID )
} /* relayPreProcess */
#endif
#ifdef XWFEATURE_BLUETOOTH
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
static XP_Bool
btPreProcess( CommsCtxt* comms, XWStreamCtxt* stream )
btIpPreProcess( CommsCtxt* comms, XWStreamCtxt* stream )
{
BTMsgType typ = (BTMsgType)stream_getU8( stream );
XP_Bool consumed = typ != BTMSG_DATA;
BTIPMsgType typ = (BTIPMsgType)stream_getU8( stream );
XP_Bool consumed = typ != BTIPMSG_DATA;
if ( consumed ) {
XP_ASSERT( typ == BTMSG_RESET );
/* This is all there is so far */
XP_ASSERT( typ == BTIPMSG_RESET );
(void)comms_resendAll( comms );
}
return consumed;
} /* btPreProcess */
} /* btIpPreProcess */
#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
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 */
XP_Bool usingRelay = XP_FALSE;
XP_Bool channelWas0 = XP_FALSE;
XP_Bool done = XP_FALSE;
XP_ASSERT( addr == NULL || comms->addr.conType == addr->conType );
if ( 0 ) {
#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 ( !preProcess( comms, stream, &usingRelay, &senderID ) ) {
if ( stream_getSize( stream ) >= sizeof(connID) ) {
connID = stream_getU32( stream );
XP_STATUSF( "%s: read connID of %lx", __func__, connID );
@ -1073,14 +1125,16 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
}
#ifdef DEBUG
if ( !!recs ) {
XP_ASSERT( lastMsgRcd <= recs->nextMsgID );
/* XP_ASSERT( lastMsgRcd <= recs->nextMsgID ); */
if ( lastMsgRcd > recs->nextMsgID ) {
XP_LOGF( "bad: got lastMsgRcd of %ld, "
"nextMsgID is %ld",
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
}
@ -1146,7 +1200,9 @@ heartbeat_checks( CommsCtxt* comms )
for ( elem = comms->msgQueueHead; !!elem; elem = elem->next ) {
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 );
@ -1154,17 +1210,27 @@ heartbeat_checks( CommsCtxt* comms )
for ( rec = comms->recs; !!rec; rec = rec->next ) {
XP_U32 lastMsgRcvdTime = rec->lastMsgRcvdTime;
if ( lastMsgRcvdTime == 0 ) { /* nothing received yet */
XP_LOGF( "no last message" );
/* do nothing; or should we send? */
} 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);
resetTimer = XP_FALSE;
break;
} else if ( 0 == pendingPacks[rec->channelNo] ) {
XP_LOGF( "sending heartbeat on channel %d", rec->channelNo );
sendWithID( comms, rec->lastMsgReceived, rec, rec->channelNo, NULL );
MsgQueueElem* hb;
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 {
XP_LOGF( "All's well" );
XP_LOGF( "All's well (%d pending)", pendingPacks[rec->channelNo] );
resetTimer = XP_TRUE;
}
}
@ -1199,6 +1265,7 @@ p_comms_timerFired( void* closure, XWTimerReason XP_UNUSED_DBG(why) )
static void
setHeartbeatTimer( CommsCtxt* comms )
{
LOG_FUNC();
#ifdef RELAY_HEARTBEAT
if ( comms->addr.conType == COMMS_CONN_RELAY ) {
util_setTimer( comms->util, TIMER_HEARTBEAT, comms->r.heartbeat,
@ -1463,22 +1530,10 @@ relayConnect( CommsCtxt* comms )
} /* relayConnect */
#endif
#ifdef XWFEATURE_BLUETOOTH
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 */
#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_IP_DIRECT
static XP_S16
send_via_bt( CommsCtxt* comms, BTMsgType typ, XP_PlayerAddr channelNo,
void* data, int dlen )
send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType typ, XP_PlayerAddr channelNo,
void* data, int dlen )
{
XP_U8* buf;
XP_S16 nSent = -1;
@ -1499,7 +1554,7 @@ send_via_bt( CommsCtxt* comms, BTMsgType typ, XP_PlayerAddr channelNo,
setHeartbeatTimer( comms );
}
return nSent;
} /* send_via_bt */
} /* send_via_bt_or_ip */
#endif

View file

@ -35,7 +35,7 @@ typedef XP_U8 XWHostID;
typedef enum {
COMMS_CONN_UNUSED, /* I want errors on uninited case */
COMMS_CONN_IR,
COMMS_CONN_IP_NOUSE,
COMMS_CONN_IP_DIRECT,
COMMS_CONN_RELAY,
COMMS_CONN_BT,

View file

@ -70,6 +70,10 @@ BLUETOOTH = -DXWFEATURE_BLUETOOTH -DBT_USE_L2CAP
DEFINES += ${BLUETOOTH}
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
# with same -D) works with comms on heartbeat. Works only with relay.
# COMMS_HEARTBEAT should work on any comms transport (even IR, but
@ -106,6 +110,7 @@ OBJ = $(PLATFORM)/linuxmain.o \
$(PLATFORM)/cursesletterask.o \
$(PLATFORM)/filestream.o \
$(PLATFORM)/linuxbt.o \
$(PLATFORM)/linuxudp.o \
# $(PLATFORM)/linuxcommpipe.o \

View file

@ -665,11 +665,12 @@ static void
curses_stop_listening( CursesAppGlobals* globals, int sock )
{
int count = globals->fdCount;
int i, found = 0;
int i;
bool found = false;
for ( i = 0; i < count; ++i ) {
if ( globals->fdArray[i].fd == sock ) {
found = 1;
found = true;
} else if ( found ) {
globals->fdArray[i-1].fd = globals->fdArray[i].fd;
}
@ -680,7 +681,8 @@ curses_stop_listening( CursesAppGlobals* globals, int sock )
} /* curses_stop_listening */
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;
if ( oldSock != -1 ) {
@ -1014,7 +1016,9 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
globals.amServer = isServer;
globals.cGlobals.params = params;
#ifdef XWFEATURE_RELAY
globals.cGlobals.socket = -1;
#endif
globals.cGlobals.socketChanged = curses_socket_changed;
globals.cGlobals.socketChangedClosure = &globals;

View file

@ -42,6 +42,7 @@
#include "main.h"
#include "linuxmain.h"
#include "linuxbt.h"
#include "linuxudp.h"
/* #include "gtkmain.h" */
#include "draw.h"
@ -59,7 +60,6 @@
/* static guint gtkSetupClientSocket( GtkAppGlobals* globals, int sock ); */
static void sendOnClose( XWStreamCtxt* stream, void* closure );
static XP_Bool file_exists( const char* fileName );
static void gtkListenOnSocket( GtkAppGlobals* globals, int newSock );
static void setCtrlsForTray( GtkAppGlobals* globals );
static void printFinalScores( GtkAppGlobals* globals );
@ -317,6 +317,7 @@ createOrLoadObjects( GtkAppGlobals* globals )
XP_U16 gameID;
CommsAddrRec addr;
XP_MEMSET( &addr, 0, sizeof(addr) );
addr.conType = params->conType;
gameID = (XP_U16)util_getCurSeconds( globals->cGlobals.params->util );
@ -354,6 +355,12 @@ createOrLoadObjects( GtkAppGlobals* globals )
>= sizeof(params->connInfo.bt.hostAddr));
XP_MEMCPY( &addr.u.bt.btAddr, &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
}
@ -378,6 +385,10 @@ createOrLoadObjects( GtkAppGlobals* globals )
}
}
if ( !!globals->cGlobals.game.comms ) {
comms_start( globals->cGlobals.game.comms );
}
server_do( globals->cGlobals.game.server );
} /* createOrLoadObjects */
@ -548,6 +559,9 @@ quit( void* XP_UNUSED(dunno), GtkAppGlobals* globals )
#ifdef XWFEATURE_BLUETOOTH
linux_bt_close( &globals->cGlobals );
#endif
#ifdef XWFEATURE_IP_DIRECT
linux_udp_close( &globals->cGlobals );
#endif
vtmgr_destroy( MEMPOOL globals->cGlobals.params->vtMgr );
@ -1201,7 +1215,7 @@ score_timer_func( gpointer data )
return XP_FALSE;
} /* score_timer_func */
#ifdef XWFEATURE_RELAY
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
static gint
heartbeat_timer_func( gpointer data )
{
@ -1217,7 +1231,7 @@ heartbeat_timer_func( gpointer data )
static void
gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
XP_U16 XP_UNUSED_RELAY(when),
XP_U16 when,
XWTimerProc proc, void* closure )
{
GtkAppGlobals* globals = (GtkAppGlobals*)uc->closure;
@ -1236,7 +1250,7 @@ gtk_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why,
(void)gettimeofday( &globals->scoreTv, NULL );
newSrc = g_timeout_add( 1000, score_timer_func, globals );
#ifdef XWFEATURE_RELAY
#if defined RELAY_HEARTBEAT || defined COMMS_HEARTBEAT
} else if ( why == TIMER_HEARTBEAT ) {
newSrc = g_timeout_add( 1000 * when, heartbeat_timer_func, globals );
#endif
@ -1570,17 +1584,26 @@ newConnectionInput( GIOChannel *source,
if ( (condition & (G_IO_HUP | G_IO_ERR)) != 0 ) {
XP_LOGF( "dropping socket %d", sock );
close( sock );
#ifdef XWFEATURE_RELAY
globals->cGlobals.socket = -1;
#ifdef XWFEATURE_BLUETOOTH
if ( COMMS_CONN_BT == globals->cGlobals.params->conType ) {
linux_bt_socketclosed( &globals->cGlobals, sock );
}
#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 */
} else if ( (condition & G_IO_IN) != 0 ) {
ssize_t nRead;
unsigned char buf[512];
CommsAddrRec addr;
CommsAddrRec* addrp = NULL;
if ( 0 ) {
#ifdef XWFEATURE_RELAY
@ -1591,6 +1614,11 @@ newConnectionInput( GIOChannel *source,
#ifdef XWFEATURE_BLUETOOTH
} else if ( globals->cGlobals.params->conType == COMMS_CONN_BT ) {
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
} else {
XP_ASSERT( 0 );
@ -1603,7 +1631,7 @@ newConnectionInput( GIOChannel *source,
inboundS = stream_from_msgbuf( &globals->cGlobals, buf, nRead );
if ( !!inboundS ) {
if ( comms_checkIncomingStream( globals->cGlobals.game.comms,
inboundS, NULL ) ) {
inboundS, addrp ) ) {
redraw =
server_receiveMessage(globals->cGlobals.game.server,
inboundS );
@ -1631,40 +1659,50 @@ newConnectionInput( GIOChannel *source,
return keepSource; /* FALSE means to remove event source */
} /* newConnectionInput */
/* Make gtk listen for events on the socket that clients will use to
* connect to us.
*/
static void
gtkListenOnSocket( GtkAppGlobals* globals, int newSock )
{
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 */
typedef struct SockInfo {
GIOChannel* channel;
guint watch;
int socket;
} SockInfo;
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;
SockInfo* info = (SockInfo*)*storage;
XP_LOGF( "%s(old:%d; new:%d)", __func__, oldSock, newSock );
if ( oldSock != -1 ) {
g_source_remove( oldSock );
XP_LOGF( "Removed %d from gtk's list of listened-to sockets" );
XP_ASSERT( info != NULL );
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 ) {
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;
#endif
/* A hack for the bluetooth case. */
CommsCtxt* comms = globals->cGlobals.game.comms;
if ( comms != NULL ) {
if ( (comms != NULL) && (comms_getConType(comms) == COMMS_CONN_BT) ) {
comms_resendAll( comms );
}
LOG_RETURN_VOID();
}
static gboolean
@ -1739,7 +1777,9 @@ gtkmain( LaunchParams* params, int argc, char *argv[] )
globals.cGlobals.params = params;
globals.cGlobals.lastNTilesToUse = MAX_TRAY_TILES;
#ifdef XWFEATURE_RELAY
globals.cGlobals.socket = -1;
#endif
globals.cGlobals.socketChanged = gtk_socket_changed;
globals.cGlobals.socketChangedClosure = &globals;

View file

@ -42,7 +42,7 @@
#include "comms.h"
#include "strutils.h"
#define MAX_CLIENTS 3
#define MAX_CLIENTS 1
#if defined BT_USE_L2CAP
# define L2_RF_ADDR struct sockaddr_l2
@ -50,81 +50,22 @@
# define L2_RF_ADDR struct sockaddr_rc
#endif
typedef struct BtaddrSockMap {
bdaddr_t btaddr;
int sock;
} BtaddrSockMap;
typedef struct LinBtStuff {
CommonGlobals* globals;
void* sockStorage;
union {
struct {
BtaddrSockMap socks[MAX_CLIENTS];
int listener; /* socket */
XP_U16 nSocks;
XP_Bool threadDie;
sdp_session_t* session;
} master;
} u;
/* A single socket's fine as long as there's only one client allowed. */
int socket;
XP_Bool amMaster;
} 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*
lbt_make( MPFORMAL XP_Bool amMaster )
{
@ -132,13 +73,7 @@ lbt_make( MPFORMAL XP_Bool amMaster )
XP_MEMSET( btStuff, 0, sizeof(*btStuff) );
btStuff->amMaster = amMaster;
if ( amMaster ) {
XP_U16 i;
for ( i = 0; i < MAX_CLIENTS; ++i ) {
btStuff->u.master.socks[i].sock = -1;
}
}
btStuff->socket = -1;
return btStuff;
} /* lbt_make */
@ -217,6 +152,7 @@ getL2Addr( const CommsAddrRec const* addrP, L2_RF_ADDR* const saddr )
sdp_close( session );
}
LOG_RETURNF( "%p", result );
return result;
} /* getL2Addr */
@ -224,6 +160,7 @@ static void
lbt_connectSocket( LinBtStuff* btStuff, const CommsAddrRec* addrP )
{
int sock;
LOG_FUNC();
// allocate a socket
sock = socket( AF_BLUETOOTH,
@ -244,7 +181,8 @@ lbt_connectSocket( LinBtStuff* btStuff, const CommsAddrRec* addrP )
&& (0 == connect( sock, (struct sockaddr *)&saddr, sizeof(saddr) )) ) {
CommonGlobals* globals = btStuff->globals;
(*globals->socketChanged)( globals->socketChangedClosure,
-1, sock );
-1, sock, &btStuff->sockStorage );
btStuff->socket = sock;
} else {
XP_LOGF( "%s: connect->%s; closing socket %d", __FUNCTION__, strerror(errno), sock );
close( sock );
@ -272,13 +210,10 @@ lbt_accept( int listener, void* ctxt )
success = sock >= 0;
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,
-1, sock );
-1, sock, &btStuff->sockStorage );
XP_ASSERT( btStuff->socket == -1 );
btStuff->socket = sock;
} else {
XP_LOGF( "%s: accept->%s", __FUNCTION__, strerror(errno) );
}
@ -423,12 +358,14 @@ linux_bt_open( CommonGlobals* globals, XP_Bool amMaster )
btStuff = globals->btStuff
= lbt_make( MPPARM(globals->params->util->mpool) amMaster );
btStuff->globals = globals;
btStuff->socket = -1;
globals->btStuff = btStuff;
if ( amMaster ) {
lbt_listenerSetup( globals );
} else {
if ( globals->socket < 0 ) {
if ( btStuff->socket < 0 ) {
CommsAddrRec addr;
comms_getAddr( globals->game.comms, &addr );
lbt_connectSocket( btStuff, &addr );
@ -451,7 +388,6 @@ void
linux_bt_close( CommonGlobals* globals )
{
LinBtStuff* btStuff = globals->btStuff;
XP_U16 i;
if ( !!btStuff ) {
if ( btStuff->amMaster ) {
@ -459,18 +395,17 @@ linux_bt_close( CommonGlobals* globals )
close( btStuff->u.master.listener );
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 );
XP_LOGF( "sleeping for Palm's sake..." );
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 );
globals->btStuff = NULL;
}
@ -495,17 +430,17 @@ linux_bt_send( const XP_U8* buf, XP_U16 buflen,
addrP = &addr;
}
if ( globals->socket < 0 && !btStuff->amMaster ) {
if ( btStuff->socket < 0 && !btStuff->amMaster ) {
lbt_connectSocket( btStuff, addrP );
}
if ( globals->socket >= 0 ) {
if ( btStuff->socket >= 0 ) {
#if defined BT_USE_RFCOMM
unsigned short len = htons(buflen);
nSent = write( globals->socket, &len, sizeof(len) );
nSent = write( btStuff->socket, &len, sizeof(len) );
assert( nSent == sizeof(len) );
#endif
nSent = write( globals->socket, buf, buflen );
nSent = write( btStuff->socket, buf, buflen );
if ( nSent < 0 ) {
XP_LOGF( "%s: send->%s", __FUNCTION__, strerror(errno) );
} else if ( nSent < buflen ) {
@ -569,10 +504,9 @@ void
linux_bt_socketclosed( CommonGlobals* globals, int sock )
{
LinBtStuff* btStuff = globals->btStuff;
if ( btStuff->amMaster ) {
lbt_removeSock( btStuff, sock );
}
LOG_FUNC();
XP_ASSERT( sock == btStuff->socket );
btStuff->socket = -1;
}
#endif /* XWFEATURE_BLUETOOTH */

View file

@ -42,6 +42,7 @@
#include "linuxmain.h"
#include "linuxbt.h"
#include "linuxudp.h"
#include "main.h"
#ifdef PLATFORM_NCURSES
# include "cursesmain.h"
@ -57,7 +58,7 @@
#include "memstream.h"
#include "LocalizedStrIncludes.h"
#define DEFAULT_SEND_PORT 10999
#define DEFAULT_PORT 10999
#define DEFAULT_LISTEN_PORT 4998
#ifdef DEBUG
@ -266,24 +267,30 @@ usage( char* appName, char* msg )
"\t [-B n:name|a:00:11:22:33:44:55]\n"
"\t\t\t# connect via bluetooth [param ignored if -s]\n"
#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" */
/* "\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
" -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
#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
"\n"
"\tclient: ./xwords -d dict.xwd -r Kati"
#ifdef XWFEATURE_RELAY
" -a localhost -p 10999"
#endif
#ifdef XWFEATURE_BLUETOOTH
" -B a:11:22:33:44:55:66 | n:my_treo "
#ifdef XWFEATURE_IP_DIRECT
"\nDirect example: \n"
"\t host: ./xwords -d dict.xwd -r Eric -s -N -N -D localhost -p 10999\n"
"\tguest: ./xwords -d dict.xwd -r Kati -D localhost -p 10999\n"
"\tguest: ./xwords -d dict.xwd -r Ariynn -D localhost -p 10999"
#endif
"\n"
, appName );
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 ) {
assert( globals->socket == socket );
(*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" );
close( socket );
(*globals->socketChanged)( globals->socketChangedClosure,
socket, -1 );
socket, -1, &globals->storage );
globals->socket = -1;
}
@ -420,7 +428,17 @@ linux_tcp_send( const XP_U8* buf, XP_U16 buflen,
return result;
} /* 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
void
@ -432,6 +450,14 @@ linux_reset( void* closure )
#ifdef XWFEATURE_BLUETOOTH
} else if ( conType == COMMS_CONN_BT ) {
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
}
@ -458,11 +484,18 @@ linux_send( const XP_U8* buf, XP_U16 buflen,
} else if ( conType == COMMS_CONN_RELAY ) {
nSent = linux_tcp_send( buf, buflen, addrRec, globals );
#endif
#ifdef XWFEATURE_BLUETOOTH
#if defined XWFEATURE_BLUETOOTH
} else if ( conType == COMMS_CONN_BT ) {
XP_Bool isServer = comms_getIsServer( globals->game.comms );
linux_bt_open( globals, isServer );
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
} else {
XP_ASSERT(0);
@ -470,6 +503,7 @@ linux_send( const XP_U8* buf, XP_U16 buflen,
return nSent;
} /* linux_send */
#ifdef XWFEATURE_RELAY
static void
linux_close_socket( CommonGlobals* cGlobals )
{
@ -502,6 +536,7 @@ linux_relay_receive( CommonGlobals* cGlobals, unsigned char* buf, int bufSize )
}
return nRead;
} /* linuxReceive */
#endif
/* Create a stream for the incoming message buffer, and read in any
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
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_BT(newAddr) )
const CommsAddrRec* newAddr )
{
if ( 0 ) {
#ifdef XWFEATURE_BLUETOOTH
@ -694,6 +729,11 @@ linux_util_addrChange( XW_UtilCtxt* XP_UNUSED_BT(uc),
CommonGlobals* cGlobals = (CommonGlobals*)uc->closure;
XP_Bool isServer = comms_getIsServer( cGlobals->game.comms );
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
}
}
@ -757,8 +797,8 @@ main( int argc, char** argv )
int opt;
int totalPlayerCount = 0;
XP_Bool isServer = XP_FALSE;
char* sendPortNumString = NULL;
char* relayName = "localhost";
char* portNum = "10999";
char* hostName = "localhost";
unsigned int seed = defaultRandomSeed();
LaunchParams mainParams;
XP_U16 robotCount = 0;
@ -798,9 +838,12 @@ main( int argc, char** argv )
/* defaults */
#ifdef XWFEATURE_RELAY
mainParams.connInfo.relay.defaultListenPort = DEFAULT_LISTEN_PORT;
mainParams.connInfo.relay.defaultSendPort = DEFAULT_SEND_PORT;
mainParams.connInfo.relay.defaultSendPort = DEFAULT_PORT;
mainParams.connInfo.relay.cookie = "COOKIE";
#endif
#ifdef XWFEATURE_IP_DIRECT
mainParams.connInfo.ip.port = DEFAULT_PORT;
mainParams.connInfo.ip.hostName = "localhost";
#endif
mainParams.gi.boardSize = 15;
mainParams.quitAfter = XP_FALSE;
@ -837,8 +880,14 @@ main( int argc, char** argv )
#ifdef XWFEATURE_RELAY
"a:p:C:H"
#endif
#if defined XWFEATURE_RELAY || defined XWFEATURE_IP_DIRECT
"p:"
#endif
#ifdef XWFEATURE_BLUETOOTH
"B:"
#endif
#ifdef XWFEATURE_IP_DIRECT
"D:"
#endif
);
switch( opt ) {
@ -856,6 +905,12 @@ main( int argc, char** argv )
conType = COMMS_CONN_RELAY;
break;
#endif
case 'D':
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
conType == COMMS_CONN_IP_DIRECT );
hostName = optarg;
conType = COMMS_CONN_IP_DIRECT;
break;
case 'd':
mainParams.gi.dictName = copyString( mainParams.util->mpool,
(XP_UCHAR*)optarg );
@ -893,10 +948,8 @@ main( int argc, char** argv )
++mainParams.info.serverInfo.nRemotePlayers;
break;
case 'p':
sendPortNumString = optarg;
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
conType == COMMS_CONN_RELAY );
conType = COMMS_CONN_RELAY;
/* could be RELAY or IP_DIRECT */
portNum = optarg;
break;
case 'r':
++robotCount;
@ -928,7 +981,7 @@ main( int argc, char** argv )
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
conType == COMMS_CONN_RELAY );
conType = COMMS_CONN_RELAY;
relayName = optarg;
hostName = optarg;
break;
case 'q':
mainParams.quitAfter = XP_TRUE;
@ -1015,12 +1068,19 @@ main( int argc, char** argv )
if ( 0 ) {
#ifdef XWFEATURE_RELAY
} else if ( conType == COMMS_CONN_RELAY ) {
mainParams.connInfo.relay.relayName = relayName;
mainParams.connInfo.relay.relayName = hostName;
/* convert strings to whatever */
if ( sendPortNumString != NULL ) {
if ( portNum != NULL ) {
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
#ifdef XWFEATURE_BLUETOOTH

View file

@ -65,19 +65,24 @@ typedef struct LaunchParams {
DeviceRole serverRole;
CommsConnType conType;
union {
struct {
#ifdef XWFEATURE_RELAY
struct {
char* relayName;
char* cookie;
short defaultSendPort;
short defaultListenPort;
} relay;
#endif
#ifdef XWFEATURE_BLUETOOTH
struct {
bdaddr_t hostAddr; /* unused if a host */
} bt;
#endif
#ifdef XWFEATURE_IP_DIRECT
struct {
const char* hostName;
int port;
} ip;
#endif
} connInfo;
@ -90,7 +95,8 @@ typedef struct LaunchParams {
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 void (*AddAcceptorFunc)(int listener, Acceptor func,
CommonGlobals* globals );
@ -109,13 +115,18 @@ struct CommonGlobals {
AddAcceptorFunc addAcceptor;
Acceptor acceptor;
int socket; /* either relay or bt */
/* Used only for relay case */
#ifdef XWFEATURE_RELAY
int socket; /* relay */
void* storage;
char* defaultServerName;
#endif
/* Used only for bluetooth case */
#if defined XWFEATURE_BLUETOOTH
struct LinBtStuff* btStuff;
#endif
#if defined XWFEATURE_IP_DIRECT
struct LinUDPStuff* udpStuff;
#endif
XWTimerProc timerProcs[NUM_TIMERS_PLUS_ONE];
void* timerClosures[NUM_TIMERS_PLUS_ONE];