diff --git a/common/comms.c b/common/comms.c index 52750830c..f105fec8e 100644 --- a/common/comms.c +++ b/common/comms.c @@ -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 diff --git a/common/comms.h b/common/comms.h index 52a1daf5c..3dd1defd9 100644 --- a/common/comms.h +++ b/common/comms.h @@ -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, diff --git a/linux/Makefile b/linux/Makefile index 45d539974..5129afad5 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -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 \ diff --git a/linux/cursesmain.c b/linux/cursesmain.c index c4775e8d1..94ef9dcbb 100644 --- a/linux/cursesmain.c +++ b/linux/cursesmain.c @@ -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; diff --git a/linux/gtkmain.c b/linux/gtkmain.c index 84185b84d..abad94f49 100644 --- a/linux/gtkmain.c +++ b/linux/gtkmain.c @@ -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, ¶ms->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; diff --git a/linux/linuxbt.c b/linux/linuxbt.c index 38b998b62..37d76b999 100644 --- a/linux/linuxbt.c +++ b/linux/linuxbt.c @@ -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 */ - diff --git a/linux/linuxmain.c b/linux/linuxmain.c index 1fdfa2775..14ebccf10 100644 --- a/linux/linuxmain.c +++ b/linux/linuxmain.c @@ -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 diff --git a/linux/main.h b/linux/main.h index 342f6b93b..488efe389 100644 --- a/linux/main.h +++ b/linux/main.h @@ -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];