mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
snapshot of work toward communicating when two addresses are in use.
An invitation works with relay and (fake) SMS on, and the invited client connects successfully using both (the second to arrive being correctly identified as a dupe.) While the game can be played after, only SMS messages are being received. And opening a saved game crashes.
This commit is contained in:
parent
fc6ccf217f
commit
17bc0ab47c
12 changed files with 481 additions and 494 deletions
|
@ -1,6 +1,6 @@
|
|||
/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */
|
||||
/*
|
||||
* Copyright 2001 - 2012 by Eric House (xwords@eehouse.org). All rights
|
||||
* Copyright 2001 - 2014 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -169,6 +169,8 @@ static AddressRecord* rememberChannelAddress( CommsCtxt* comms,
|
|||
XP_PlayerAddr channelNo,
|
||||
XWHostID id,
|
||||
const CommsAddrRec* addr );
|
||||
static void augmentChannelAddr( CommsCtxt* comms, AddressRecord* rec,
|
||||
const CommsAddrRec* addr );
|
||||
static void updateChannelAddress( AddressRecord* rec, const CommsAddrRec* addr );
|
||||
static XP_Bool channelToAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
|
||||
const CommsAddrRec** addr );
|
||||
|
@ -199,6 +201,8 @@ static void putDevID( const CommsCtxt* comms, XWStreamCtxt* stream );
|
|||
# ifdef DEBUG
|
||||
static const char* relayCmdToStr( XWRELAY_Cmd cmd );
|
||||
static void printQueue( const CommsCtxt* comms );
|
||||
static void logAddr( CommsCtxt* comms, const CommsAddrRec* addr,
|
||||
const char* caller );
|
||||
# else
|
||||
# define printQueue( comms )
|
||||
# endif
|
||||
|
@ -568,6 +572,7 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util,
|
|||
|
||||
isServer = stream_getU8( stream );
|
||||
addrFromStream( &addr, stream );
|
||||
logAddr( comms, &addr, __func__ );
|
||||
|
||||
if ( addr_hasType( &addr, COMMS_CONN_RELAY ) ) {
|
||||
nPlayersHere = (XP_U16)stream_getBits( stream, 4 );
|
||||
|
@ -610,6 +615,7 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util,
|
|||
AddressRecord* rec = (AddressRecord*)XP_CALLOC( mpool, sizeof(*rec));
|
||||
|
||||
addrFromStream( &rec->addr, stream );
|
||||
logAddr( comms, &rec->addr, __func__ );
|
||||
|
||||
rec->nextMsgID = stream_getU16( stream );
|
||||
rec->lastMsgSaved = rec->lastMsgRcd = stream_getU16( stream );
|
||||
|
@ -776,6 +782,7 @@ comms_writeToStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
|||
MsgQueueElem* msg;
|
||||
|
||||
stream_putU8( stream, (XP_U8)comms->isServer );
|
||||
logAddr( comms, &comms->addr, __func__ );
|
||||
addrToStream( stream, &comms->addr );
|
||||
if ( addr_hasType( &comms->addr, COMMS_CONN_RELAY ) ) {
|
||||
stream_putBits( stream, 4, comms->rr.nPlayersHere );
|
||||
|
@ -802,6 +809,7 @@ comms_writeToStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
|||
|
||||
CommsAddrRec* addr = &rec->addr;
|
||||
addrToStream( stream, addr );
|
||||
logAddr( comms, addr, __func__ );
|
||||
|
||||
stream_putU16( stream, (XP_U16)rec->nextMsgID );
|
||||
stream_putU16( stream, (XP_U16)rec->lastMsgRcd );
|
||||
|
@ -993,7 +1001,7 @@ static MsgQueueElem*
|
|||
makeElemWithID( CommsCtxt* comms, MsgID msgID, AddressRecord* rec,
|
||||
XP_PlayerAddr channelNo, XWStreamCtxt* stream )
|
||||
{
|
||||
XP_LOGF( "%s(channelNo=%x)", __func__, channelNo );
|
||||
XP_LOGF( "%s(channelNo=%X)", __func__, channelNo );
|
||||
XP_U16 headerLen;
|
||||
XP_U16 streamSize = NULL == stream? 0 : stream_getSize( stream );
|
||||
MsgID lastMsgSaved = (!!rec)? rec->lastMsgSaved : 0;
|
||||
|
@ -1046,8 +1054,8 @@ XP_U16
|
|||
comms_getChannelSeed( CommsCtxt* comms )
|
||||
{
|
||||
while ( 0 == (comms->channelSeed & ~CHANNEL_MASK) ) {
|
||||
comms->channelSeed = XP_RANDOM();
|
||||
XP_LOGF( "%s: channelSeed: %.4X", __func__, comms->channelSeed );
|
||||
comms->channelSeed = XP_RANDOM() & ~CHANNEL_MASK;
|
||||
XP_LOGF( "%s: new channelSeed: %.4X", __func__, comms->channelSeed );
|
||||
}
|
||||
return comms->channelSeed;
|
||||
}
|
||||
|
@ -1062,7 +1070,7 @@ comms_send( CommsCtxt* comms, XWStreamCtxt* stream )
|
|||
XP_LOGF( "%s: dropping 0-len message", __func__ );
|
||||
} else {
|
||||
XP_PlayerAddr channelNo = stream_getAddress( stream );
|
||||
XP_LOGF( "%s: channelNo=%x", __func__, channelNo );
|
||||
XP_LOGF( "%s: channelNo=%X", __func__, channelNo );
|
||||
AddressRecord* rec = getRecordFor( comms, NULL, channelNo, XP_FALSE );
|
||||
MsgID msgID = (!!rec)? ++rec->nextMsgID : 0;
|
||||
MsgQueueElem* elem;
|
||||
|
@ -1071,7 +1079,7 @@ comms_send( CommsCtxt* comms, XWStreamCtxt* stream )
|
|||
channelNo = comms_getChannelSeed(comms) & ~CHANNEL_MASK;
|
||||
}
|
||||
|
||||
XP_DEBUGF( "%s: assigning msgID=" XP_LD " on chnl %x", __func__,
|
||||
XP_DEBUGF( "%s: assigning msgID=" XP_LD " on chnl %X", __func__,
|
||||
msgID, channelNo );
|
||||
|
||||
elem = makeElemWithID( comms, msgID, rec, channelNo, stream );
|
||||
|
@ -1126,7 +1134,7 @@ printQueue( const CommsCtxt* comms )
|
|||
|
||||
for ( elem = comms->msgQueueHead, ii = 0; ii < comms->queueLen;
|
||||
elem = elem->next, ++ii ) {
|
||||
XP_LOGF( "\t%d: channel: %x; msgID=" XP_LD
|
||||
XP_LOGF( "\t%d: channel: %X; msgID=" XP_LD
|
||||
#ifdef COMMS_CHECKSUM
|
||||
"; check=%s"
|
||||
#endif
|
||||
|
@ -1173,6 +1181,7 @@ freeElem( const CommsCtxt* XP_UNUSED_DBG(comms), MsgQueueElem* elem )
|
|||
{
|
||||
XP_FREE( comms->mpool, elem->msg );
|
||||
#ifdef COMMS_CHECKSUM
|
||||
XP_LOGF( "%s: freeing msg with sum %s", __func__, elem->checksum );
|
||||
XP_FREE( comms->mpool, elem->checksum );
|
||||
#endif
|
||||
XP_FREE( comms->mpool, elem );
|
||||
|
@ -1187,7 +1196,7 @@ freeElem( const CommsCtxt* XP_UNUSED_DBG(comms), MsgQueueElem* elem )
|
|||
static void
|
||||
removeFromQueue( CommsCtxt* comms, XP_PlayerAddr channelNo, MsgID msgID )
|
||||
{
|
||||
XP_LOGF( "%s: remove msgs <= " XP_LD " for channel %x (queueLen: %d)",
|
||||
XP_LOGF( "%s: remove msgs <= " XP_LD " for channel %X (queueLen: %d)",
|
||||
__func__, msgID, channelNo, comms->queueLen );
|
||||
|
||||
if ( (channelNo == 0) || !!getRecordFor( comms, NULL, channelNo,
|
||||
|
@ -1272,18 +1281,20 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
|||
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( &comms->addr, &typ, &st ); ) {
|
||||
XP_LOGF( "%s: sending using typ %s", __func__, ConnType2Str(typ) );
|
||||
XP_S16 nSent = -1;
|
||||
XP_LOGF( "%s: sending msg with sum %s using typ %s", __func__, elem->checksum,
|
||||
ConnType2Str(typ) );
|
||||
switch ( typ ) {
|
||||
#ifdef XWFEATURE_RELAY
|
||||
case COMMS_CONN_RELAY: {
|
||||
XWHostID destID = getDestID( comms, channelNo );
|
||||
if ( haveRelayID( comms ) && sendNoConn( comms, elem, destID ) ) {
|
||||
/* do nothing */
|
||||
result = elem->len;
|
||||
nSent = elem->len;
|
||||
} else if ( comms->rr.relayState >= COMMS_RELAYSTATE_CONNECTED ) {
|
||||
if ( send_via_relay( comms, XWRELAY_MSG_TORELAY, destID,
|
||||
elem->msg, elem->len ) ){
|
||||
result = elem->len;
|
||||
nSent = elem->len;
|
||||
}
|
||||
} else {
|
||||
XP_LOGF( "%s: skipping message: not connected", __func__ );
|
||||
|
@ -1294,8 +1305,8 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
|||
#if defined XWFEATURE_IP_DIRECT
|
||||
case COMMS_CONN_BT:
|
||||
case COMMS_CONN_IP_DIRECT:
|
||||
result = send_via_ip( comms, BTIPMSG_DATA, channelNo,
|
||||
elem->msg, elem->len );
|
||||
nSent = send_via_ip( comms, BTIPMSG_DATA, channelNo,
|
||||
elem->msg, elem->len );
|
||||
#ifdef COMMS_HEARTBEAT
|
||||
setHeartbeatTimer( comms );
|
||||
#endif
|
||||
|
@ -1307,6 +1318,7 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
|||
(void)channelToAddress( comms, channelNo, &addrP );
|
||||
|
||||
if ( NULL == addrP ) {
|
||||
XP_LOGF( "%s: no addr for channel so using comms'", __func__ );
|
||||
comms_getAddr( comms, &addr );
|
||||
} else {
|
||||
addr = *addrP;
|
||||
|
@ -1314,16 +1326,16 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
|
|||
|
||||
XP_U32 gameid = gameID( comms );
|
||||
XP_ASSERT( !!comms->procs.send );
|
||||
// addr._conTypes = 1 << (typ - 1);
|
||||
XP_S16 nSent = (*comms->procs.send)( elem->msg, elem->len, &addr,
|
||||
typ, gameid,
|
||||
comms->procs.closure );
|
||||
if ( nSent > result ) {
|
||||
result = nSent;
|
||||
}
|
||||
nSent = (*comms->procs.send)( elem->msg, elem->len, &addr, typ,
|
||||
gameid, comms->procs.closure );
|
||||
break;
|
||||
}
|
||||
} /* switch */
|
||||
XP_LOGF( "%s: send %d bytes using typ %s", __func__, nSent,
|
||||
ConnType2Str(typ) );
|
||||
if ( nSent > result ) {
|
||||
result = nSent;
|
||||
}
|
||||
}
|
||||
|
||||
if ( result == elem->len ) {
|
||||
|
@ -1394,7 +1406,7 @@ comms_ackAny( CommsCtxt* comms )
|
|||
#ifdef DEBUG
|
||||
++nSent;
|
||||
#endif
|
||||
XP_LOGF( "%s: channel %x; %d < %d: rec needs ack", __func__,
|
||||
XP_LOGF( "%s: channel %X; %d < %d: rec needs ack", __func__,
|
||||
rec->channelNo, rec->lastMsgAckd, rec->lastMsgRcd );
|
||||
sendEmptyMsg( comms, rec );
|
||||
}
|
||||
|
@ -1652,9 +1664,11 @@ relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID )
|
|||
|
||||
/* fallthru */
|
||||
default:
|
||||
XP_ASSERT( 0 ); /* while debugging multi-addr, this needs a fix! */
|
||||
XP_LOGF( "%s: dropping relay msg with cmd %d", __func__, (XP_U16)cmd );
|
||||
}
|
||||
|
||||
LOG_RETURNF( "%d", consumed );
|
||||
return consumed;
|
||||
} /* relayPreProcess */
|
||||
#endif
|
||||
|
@ -1699,9 +1713,13 @@ preProcess( CommsCtxt* comms, const CommsAddrRec* useAddr,
|
|||
XWHostID* XP_UNUSED_RELAY(senderID) )
|
||||
{
|
||||
XP_Bool consumed = XP_FALSE;
|
||||
// XWStreamPos pos = stream_getPos( stream, POS_READ);
|
||||
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( useAddr, &typ, &st ); ) {
|
||||
for ( XP_U32 st = 0; !consumed && addr_iter( useAddr, &typ, &st ); ) {
|
||||
XP_LOGF( "%s(typ=%s)", __func__, ConnType2Str(typ) );
|
||||
|
||||
// stream_setPos( stream, POS_READ, pos );
|
||||
switch ( typ ) {
|
||||
#ifdef XWFEATURE_RELAY
|
||||
/* relayPreProcess returns true if consumes the message. May just eat the
|
||||
|
@ -1718,8 +1736,13 @@ preProcess( CommsCtxt* comms, const CommsAddrRec* useAddr,
|
|||
case COMMS_CONN_IP_DIRECT:
|
||||
consumed = btIpPreProcess( comms, stream );
|
||||
break;
|
||||
#endif
|
||||
#if defined XWFEATURE_SMS
|
||||
case COMMS_CONN_SMS:
|
||||
break; /* nothing to grab */
|
||||
#endif
|
||||
default:
|
||||
XP_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1732,59 +1755,68 @@ getRecordFor( CommsCtxt* comms, const CommsAddrRec* addr,
|
|||
const XP_PlayerAddr channelNo, XP_Bool maskChannel )
|
||||
{
|
||||
LOG_FUNC();
|
||||
CommsConnType conType;
|
||||
AddressRecord* rec;
|
||||
XP_Bool matched = XP_FALSE;
|
||||
XP_U16 mask = maskChannel? ~CHANNEL_MASK : ~0;
|
||||
|
||||
/* Use addr if we have it. Otherwise use channelNo if non-0 */
|
||||
conType = !!addr? addr_getType( addr ) : COMMS_CONN_NONE;
|
||||
|
||||
for ( rec = comms->recs; !!rec; rec = rec->next ) {
|
||||
XP_ASSERT( !addr || (conType == addr_getType( &rec->addr ) ) );
|
||||
switch( conType ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
XP_ASSERT(0); /* is this being used? */
|
||||
if ( (addr->u.ip_relay.ipAddr == rec->addr.u.ip_relay.ipAddr)
|
||||
&& (addr->u.ip_relay.port == rec->addr.u.ip_relay.port ) ) {
|
||||
matched = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
if ( 0 == XP_MEMCMP( &addr->u.bt.btAddr, &rec->addr.u.bt.btAddr,
|
||||
sizeof(addr->u.bt.btAddr) ) ) {
|
||||
matched = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
case COMMS_CONN_IP_DIRECT:
|
||||
if ( (addr->u.ip.ipAddr_ip == rec->addr.u.ip.ipAddr_ip)
|
||||
&& (addr->u.ip.port_ip == rec->addr.u.ip.port_ip) ) {
|
||||
matched = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
case COMMS_CONN_IR: /* no way to test */
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
|
||||
XP_LOGF( "%s: comparing rec channel %X with addr channel %X", __func__,
|
||||
(rec->channelNo & ~CHANNEL_MASK), (channelNo & ~CHANNEL_MASK) );
|
||||
|
||||
if ( (rec->channelNo & ~CHANNEL_MASK) == (channelNo & ~CHANNEL_MASK) ) {
|
||||
XP_LOGF( "%s: match based on channels!!!", __func__ );
|
||||
augmentChannelAddr( comms, rec, addr );
|
||||
matched = XP_TRUE;
|
||||
} else {
|
||||
CommsConnType conType = !!addr ?
|
||||
addr_getType( addr ) : COMMS_CONN_NONE;
|
||||
switch( conType ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
XP_ASSERT(0); /* is this being used? */
|
||||
if ( (addr->u.ip_relay.ipAddr == rec->addr.u.ip_relay.ipAddr)
|
||||
&& (addr->u.ip_relay.port == rec->addr.u.ip_relay.port ) ) {
|
||||
matched = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
case COMMS_CONN_BT:
|
||||
if ( 0 == XP_MEMCMP( &addr->u.bt.btAddr, &rec->addr.u.bt.btAddr,
|
||||
sizeof(addr->u.bt.btAddr) ) ) {
|
||||
matched = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
case COMMS_CONN_IP_DIRECT:
|
||||
if ( (addr->u.ip.ipAddr_ip == rec->addr.u.ip.ipAddr_ip)
|
||||
&& (addr->u.ip.port_ip == rec->addr.u.ip.port_ip) ) {
|
||||
matched = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
case COMMS_CONN_IR: /* no way to test */
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
#ifdef XWFEATURE_SMS
|
||||
if ( util_phoneNumbersSame( comms->util, addr->u.sms.phone,
|
||||
rec->addr.u.sms.phone )
|
||||
&& addr->u.sms.port == rec->addr.u.sms.port ) {
|
||||
matched = XP_TRUE;
|
||||
}
|
||||
if ( util_phoneNumbersSame( comms->util, addr->u.sms.phone,
|
||||
rec->addr.u.sms.phone )
|
||||
&& addr->u.sms.port == rec->addr.u.sms.port ) {
|
||||
matched = XP_TRUE;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case COMMS_CONN_NONE:
|
||||
matched = channelNo == (rec->channelNo & mask);
|
||||
break;
|
||||
default:
|
||||
XP_ASSERT(0);
|
||||
break;
|
||||
break;
|
||||
case COMMS_CONN_NONE:
|
||||
matched = channelNo == (rec->channelNo & mask);
|
||||
break;
|
||||
default:
|
||||
XP_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( matched ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
XP_LOGF( "%s(channelNo=%x, maskChannel=%s) => %p", __func__,
|
||||
XP_LOGF( "%s(channelNo=%X, maskChannel=%s) => %p", __func__,
|
||||
channelNo, maskChannel? "true":"false", rec );
|
||||
return rec;
|
||||
} /* getRecordFor */
|
||||
|
@ -1814,6 +1846,8 @@ validateInitialMessage( CommsCtxt* comms,
|
|||
{
|
||||
AddressRecord* rec = NULL;
|
||||
LOG_FUNC();
|
||||
XP_U32 clientID = *channelNo & CHANNEL_MASK;
|
||||
XP_LOGF( "%s(): clientID = 0x%x", __func__, clientID );
|
||||
if ( 0 ) {
|
||||
#ifdef COMMS_HEARTBEAT
|
||||
} else if ( comms->doHeartbeat ) {
|
||||
|
@ -1838,7 +1872,7 @@ validateInitialMessage( CommsCtxt* comms,
|
|||
|
||||
if ( addRec ) {
|
||||
if ( comms->isServer ) {
|
||||
XP_LOGF( "%s: looking at channelNo: %x", __func__, *channelNo );
|
||||
XP_LOGF( "%s: looking at channelNo: %X", __func__, *channelNo );
|
||||
XP_ASSERT( (*channelNo & CHANNEL_MASK) == 0 );
|
||||
*channelNo |= ++comms->nextChannelNo;
|
||||
XP_ASSERT( comms->nextChannelNo <= CHANNEL_MASK );
|
||||
|
@ -1852,11 +1886,14 @@ validateInitialMessage( CommsCtxt* comms,
|
|||
}
|
||||
#endif
|
||||
} else {
|
||||
XP_LOGF( "%s: looking at channelNo: %x", __func__, *channelNo );
|
||||
XP_LOGF( "%s: looking at channelNo: %X", __func__, *channelNo );
|
||||
rec = getRecordFor( comms, addr, *channelNo, XP_TRUE );
|
||||
if ( !!rec ) {
|
||||
/* reject: we've already seen init message on channel */
|
||||
XP_LOGF( "%s: rejecting duplicate INIT message", __func__ );
|
||||
/* if ( !!addr && (addr->_conTypes != rec->addr._conTypes) ) { */
|
||||
/* augmentChannelAddr( comms, rec, addr ); */
|
||||
/* } */
|
||||
rec = NULL;
|
||||
} else {
|
||||
if ( comms->isServer ) {
|
||||
|
@ -1906,7 +1943,7 @@ validateChannelMessage( CommsCtxt* comms, const CommsAddrRec* addr,
|
|||
rec = NULL;
|
||||
}
|
||||
} else {
|
||||
XP_LOGF( "%s: no rec for channelNo %x", __func__, channelNo );
|
||||
XP_LOGF( "%s: no rec for channelNo %X", __func__, channelNo );
|
||||
}
|
||||
|
||||
LOG_RETURNF( XP_P, rec );
|
||||
|
@ -1917,6 +1954,7 @@ XP_Bool
|
|||
comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
||||
const CommsAddrRec* retAddr )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_Bool messageValid = XP_FALSE;
|
||||
XWHostID senderID = 0; /* unset; default for non-relay cases */
|
||||
XP_Bool usingRelay = XP_FALSE;
|
||||
|
@ -1957,7 +1995,7 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream,
|
|||
channelNo = stream_getU16( stream );
|
||||
msgID = stream_getU32( stream );
|
||||
lastMsgRcd = stream_getU32( stream );
|
||||
XP_LOGF( "%s: rcd on channelNo %d(%x): msgID=%d,lastMsgRcd=%d ",
|
||||
XP_LOGF( "%s: rcd on channelNo %d(%X): msgID=%d,lastMsgRcd=%d ",
|
||||
__func__, channelNo & CHANNEL_MASK, channelNo,
|
||||
msgID, lastMsgRcd );
|
||||
|
||||
|
@ -2196,14 +2234,14 @@ comms_getStats( CommsCtxt* comms, XWStreamCtxt* stream )
|
|||
|
||||
for ( elem = comms->msgQueueHead; !!elem; elem = elem->next ) {
|
||||
XP_SNPRINTF( buf, sizeof(buf),
|
||||
" - channelNo=%x; msgID=" XP_LD "; len=%d\n",
|
||||
" - channelNo=%X; msgID=" XP_LD "; len=%d\n",
|
||||
elem->channelNo, elem->msgID, elem->len );
|
||||
stream_catString( stream, buf );
|
||||
}
|
||||
|
||||
for ( rec = comms->recs; !!rec; rec = rec->next ) {
|
||||
XP_SNPRINTF( (XP_UCHAR*)buf, sizeof(buf),
|
||||
(XP_UCHAR*)" Stats for channel: %x\n",
|
||||
(XP_UCHAR*)" Stats for channel: %X\n",
|
||||
rec->channelNo );
|
||||
stream_catString( stream, buf );
|
||||
|
||||
|
@ -2224,34 +2262,135 @@ static AddressRecord*
|
|||
rememberChannelAddress( CommsCtxt* comms, XP_PlayerAddr channelNo,
|
||||
XWHostID hostID, const CommsAddrRec* addr )
|
||||
{
|
||||
AddressRecord* recs = NULL;
|
||||
recs = getRecordFor( comms, NULL, channelNo, XP_FALSE );
|
||||
if ( !recs ) {
|
||||
XP_LOGF( "%s(%X)", __func__, channelNo );
|
||||
logAddr( comms, addr, __func__ );
|
||||
AddressRecord* rec = NULL;
|
||||
rec = getRecordFor( comms, NULL, channelNo, XP_FALSE );
|
||||
if ( !rec ) {
|
||||
/* not found; add a new entry */
|
||||
recs = (AddressRecord*)XP_MALLOC( comms->mpool, sizeof(*recs) );
|
||||
XP_MEMSET( recs, 0, sizeof(*recs) );
|
||||
rec = (AddressRecord*)XP_CALLOC( comms->mpool, sizeof(*rec) );
|
||||
|
||||
recs->channelNo = channelNo;
|
||||
recs->rr.hostID = hostID;
|
||||
recs->next = comms->recs;
|
||||
comms->recs = recs;
|
||||
rec->channelNo = channelNo;
|
||||
rec->rr.hostID = hostID;
|
||||
rec->next = comms->recs;
|
||||
comms->recs = rec;
|
||||
XP_LOGF( "%s() creating rec %p for channelNo=%X", __func__,
|
||||
rec, channelNo );
|
||||
}
|
||||
|
||||
/* overwrite existing address with new one. I assume that's the right
|
||||
move. */
|
||||
if ( !!recs ) {
|
||||
if ( !!rec ) {
|
||||
if ( !!addr ) {
|
||||
XP_MEMCPY( &recs->addr, addr, sizeof(recs->addr) );
|
||||
XP_ASSERT( recs->rr.hostID == hostID );
|
||||
XP_LOGF( "%s: replacing/adding addr with _conTypes %x with %x", __func__,
|
||||
rec->addr._conTypes, addr->_conTypes );
|
||||
XP_MEMCPY( &rec->addr, addr, sizeof(rec->addr) );
|
||||
XP_ASSERT( rec->rr.hostID == hostID );
|
||||
} else {
|
||||
XP_MEMSET( &recs->addr, 0, sizeof(recs->addr) );
|
||||
recs->addr._conTypes = comms->addr._conTypes;
|
||||
XP_LOGF( "%s: storing addr with _conTypes %x", __func__,
|
||||
addr->_conTypes );
|
||||
XP_MEMSET( &rec->addr, 0, sizeof(rec->addr) );
|
||||
rec->addr._conTypes = comms->addr._conTypes;
|
||||
// addr_setTypes( &recs->addr, addr_getTypes( &comms->addr ) );
|
||||
}
|
||||
}
|
||||
return recs;
|
||||
return rec;
|
||||
} /* rememberChannelAddress */
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
logAddr( CommsCtxt* comms, const CommsAddrRec* addr, const char* caller )
|
||||
{
|
||||
if ( !!addr ) {
|
||||
char buf[128];
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(comms->mpool)
|
||||
util_getVTManager(comms->util),
|
||||
NULL, 0,
|
||||
(MemStreamCloseCallback)NULL );
|
||||
snprintf( buf, sizeof(buf), "%s called on %p from %s:\n", __func__,
|
||||
addr, caller );
|
||||
stream_catString( stream, buf );
|
||||
|
||||
CommsConnType typ;
|
||||
XP_Bool first = XP_TRUE;
|
||||
for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) {
|
||||
if ( !first ) {
|
||||
stream_catString( stream, "\n" );
|
||||
}
|
||||
|
||||
snprintf( buf, sizeof(buf), "* %s: ", ConnType2Str(typ) );
|
||||
stream_catString( stream, buf );
|
||||
|
||||
switch( typ ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
stream_catString( stream, "room: " );
|
||||
stream_catString( stream, addr->u.ip_relay.invite );
|
||||
stream_catString( stream, "; host: " );
|
||||
stream_catString( stream, addr->u.ip_relay.hostName );
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
stream_catString( stream, "phone: " );
|
||||
stream_catString( stream, addr->u.sms.phone );
|
||||
stream_catString( stream, "; port: " );
|
||||
snprintf( buf, sizeof(buf), "%d", addr->u.sms.port );
|
||||
stream_catString( stream, buf );
|
||||
break;
|
||||
default:
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
first = XP_FALSE;
|
||||
}
|
||||
stream_putU8( stream, '\0' );
|
||||
XP_LOGF( "%s: %s", __func__, stream_getPtr( stream ) );
|
||||
stream_destroy( stream );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
augmentChannelAddr( CommsCtxt* comms, AddressRecord* rec, const CommsAddrRec* addr )
|
||||
{
|
||||
logAddr( comms, &rec->addr, __func__ );
|
||||
logAddr( comms, addr, __func__ );
|
||||
|
||||
if ( !!addr ) {
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) {
|
||||
addr_addType( &rec->addr, typ );
|
||||
|
||||
const void* src = NULL;
|
||||
void* dest = NULL;
|
||||
XP_U32 siz;
|
||||
|
||||
switch( typ ) {
|
||||
case COMMS_CONN_RELAY:
|
||||
dest = &rec->addr.u.ip_relay;
|
||||
siz = sizeof( rec->addr.u.ip_relay );
|
||||
/* Special case for relay: use comms' relay info if caller
|
||||
didn't bother to fill it in */
|
||||
if ( addr->u.ip_relay.invite[0] ) {
|
||||
src = &addr->u.ip_relay;
|
||||
} else {
|
||||
src = &comms->addr.u.ip_relay;
|
||||
}
|
||||
break;
|
||||
case COMMS_CONN_SMS:
|
||||
dest = &rec->addr.u.sms;
|
||||
src = &addr->u.sms;
|
||||
siz = sizeof(rec->addr.u.sms);
|
||||
break;
|
||||
default:
|
||||
XP_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if ( !!dest ) {
|
||||
XP_MEMCPY( dest, src, siz );
|
||||
}
|
||||
}
|
||||
}
|
||||
logAddr( comms, &rec->addr, __func__ );
|
||||
}
|
||||
|
||||
static void
|
||||
updateChannelAddress( AddressRecord* rec, const CommsAddrRec* addr )
|
||||
{
|
||||
|
@ -2298,15 +2437,20 @@ addr_iter( const CommsAddrRec* addr, CommsConnType* typp, XP_U32* state )
|
|||
if ( found ) {
|
||||
*typp = typ;
|
||||
}
|
||||
XP_LOGF( "%s(flag=%x)=>%d (typ=%s)", __func__, conTypes, found, ConnType2Str( typ ) );
|
||||
// XP_LOGF( "%s(flag=%x)=>%d (typ=%s)", __func__, conTypes, found, ConnType2Str( typ ) );
|
||||
return found;
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
addr_hasType( const CommsAddrRec* addr, CommsConnType type )
|
||||
addr_hasType( const CommsAddrRec* addr, CommsConnType typ )
|
||||
{
|
||||
XP_ASSERT( COMMS_CONN_NONE != type );
|
||||
return 0 != (addr->_conTypes & (1 << (type - 1)));
|
||||
/* Any address has NONE */
|
||||
XP_Bool hasType = COMMS_CONN_NONE == typ;
|
||||
if ( !hasType ) {
|
||||
hasType = 0 != (addr->_conTypes & (1 << (typ - 1)));
|
||||
}
|
||||
// XP_LOGF( "%s(%s) => %d", __func__, ConnType2Str(typ), hasType );
|
||||
return hasType;
|
||||
}
|
||||
|
||||
CommsConnType
|
||||
|
@ -2317,7 +2461,7 @@ addr_getType( const CommsAddrRec* addr )
|
|||
if ( !addr_iter( addr, &typ, &st ) ) {
|
||||
typ = COMMS_CONN_NONE;
|
||||
}
|
||||
XP_ASSERT( !addr_iter( addr, &typ, &st ) ); /* shouldn't be a second -- yet */
|
||||
XP_ASSERT( !addr_iter( addr, &typ, &st ) ); /* shouldn't be a second */
|
||||
XP_LOGF( "%s(%p) => %s", __func__, addr, ConnType2Str( typ ) );
|
||||
return typ;
|
||||
}
|
||||
|
@ -2369,7 +2513,7 @@ getDestID( CommsCtxt* comms, XP_PlayerAddr channelNo )
|
|||
}
|
||||
}
|
||||
}
|
||||
XP_LOGF( "%s(%x) => %x", __func__, channelNo, id );
|
||||
XP_LOGF( "%s(%X) => %x", __func__, channelNo, id );
|
||||
return id;
|
||||
} /* getDestID */
|
||||
|
||||
|
|
|
@ -972,7 +972,7 @@ SIGINTTERM_handler( int XP_UNUSED(signal) )
|
|||
}
|
||||
|
||||
static void
|
||||
cursesListenOnSocket( CursesAppGlobals* globals, int newSock
|
||||
cursesListenOnSocket( void* closure, int newSock
|
||||
#ifdef USE_GLIBLOOP
|
||||
, GIOFunc func
|
||||
#endif
|
||||
|
@ -982,15 +982,9 @@ cursesListenOnSocket( CursesAppGlobals* globals, int newSock
|
|||
GIOChannel* channel = g_io_channel_unix_new( newSock );
|
||||
XP_LOGF( "%s: created channel %p for socket %d", __func__, channel, newSock );
|
||||
XP_ASSERT( !!func );
|
||||
guint watch = g_io_add_watch( channel,
|
||||
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
|
||||
func, globals );
|
||||
|
||||
SourceData* data = g_malloc( sizeof(*data) );
|
||||
data->channel = channel;
|
||||
data->watch = watch;
|
||||
globals->sources = g_list_append( globals->sources, data );
|
||||
|
||||
(void)g_io_add_watch( channel,
|
||||
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
|
||||
func, closure );
|
||||
#else
|
||||
XP_ASSERT( globals->fdCount+1 < FD_MAX );
|
||||
|
||||
|
@ -1004,42 +998,6 @@ cursesListenOnSocket( CursesAppGlobals* globals, int newSock
|
|||
#endif
|
||||
} /* cursesListenOnSocket */
|
||||
|
||||
static void
|
||||
curses_stop_listening( CursesAppGlobals* globals, int sock )
|
||||
{
|
||||
#ifdef USE_GLIBLOOP
|
||||
GList* sources = globals->sources;
|
||||
while ( !!sources ) {
|
||||
SourceData* data = sources->data;
|
||||
gint fd = g_io_channel_unix_get_fd( data->channel );
|
||||
if ( fd == sock ) {
|
||||
g_io_channel_unref( data->channel );
|
||||
XP_LOGF( "%s: unreffing channel %p", __func__, data->channel );
|
||||
g_free( data );
|
||||
globals->sources = g_list_remove_link( globals->sources, sources );
|
||||
break;
|
||||
}
|
||||
sources = sources->next;
|
||||
}
|
||||
|
||||
#else
|
||||
int count = globals->fdCount;
|
||||
int i;
|
||||
bool found = false;
|
||||
|
||||
for ( i = 0; i < count; ++i ) {
|
||||
if ( globals->fdArray[i].fd == sock ) {
|
||||
found = true;
|
||||
} else if ( found ) {
|
||||
globals->fdArray[i-1].fd = globals->fdArray[i].fd;
|
||||
}
|
||||
}
|
||||
|
||||
assert( found );
|
||||
--globals->fdCount;
|
||||
#endif
|
||||
} /* curses_stop_listening */
|
||||
|
||||
#ifdef USE_GLIBLOOP
|
||||
#if 0
|
||||
static gboolean
|
||||
|
@ -1124,15 +1082,11 @@ data_socket_proc( GIOChannel* source, GIOCondition condition, gpointer data )
|
|||
#endif
|
||||
|
||||
static void
|
||||
curses_socket_changed( void* closure, int oldSock, int newSock,
|
||||
GIOFunc func, void** XP_UNUSED(storage) )
|
||||
curses_socket_added( void* closure, int newSock, GIOFunc func )
|
||||
{
|
||||
CursesAppGlobals* globals = (CursesAppGlobals*)closure;
|
||||
if ( oldSock != -1 ) {
|
||||
curses_stop_listening( globals, oldSock );
|
||||
}
|
||||
// CursesAppGlobals* globals = (CursesAppGlobals*)closure;
|
||||
if ( newSock != -1 ) {
|
||||
cursesListenOnSocket( globals, newSock
|
||||
cursesListenOnSocket( closure, newSock
|
||||
#ifdef USE_GLIBLOOP
|
||||
, func
|
||||
#endif
|
||||
|
@ -1140,7 +1094,8 @@ curses_socket_changed( void* closure, int oldSock, int newSock,
|
|||
}
|
||||
|
||||
#ifdef XWFEATURE_RELAY
|
||||
globals->cGlobals.relaySocket = newSock;
|
||||
/* XP_ASSERT( !globals->cGlobals.relaySocket ); */
|
||||
/* globals->cGlobals.relaySocket = newSock; */
|
||||
#endif
|
||||
} /* curses_socket_changed */
|
||||
|
||||
|
@ -1780,7 +1735,8 @@ curses_getFlags( void* XP_UNUSED(closure) )
|
|||
#endif
|
||||
|
||||
static void
|
||||
cursesGotBuf( void* closure, const XP_U8* buf, XP_U16 len )
|
||||
cursesGotBuf( void* closure, const CommsAddrRec* addr,
|
||||
const XP_U8* buf, XP_U16 len )
|
||||
{
|
||||
CursesAppGlobals* globals = (CursesAppGlobals*)closure;
|
||||
XP_U32 clientToken;
|
||||
|
@ -1794,7 +1750,7 @@ cursesGotBuf( void* closure, const XP_U8* buf, XP_U16 len )
|
|||
rowidFromToken( XP_NTOHL( clientToken ), &ignore, &seed );
|
||||
XP_ASSERT( seed == comms_getChannelSeed( globals->cGlobals.game.comms ) );
|
||||
if ( seed == comms_getChannelSeed( globals->cGlobals.game.comms ) ) {
|
||||
gameGotBuf( &globals->cGlobals, XP_TRUE, buf, len, NULL );
|
||||
gameGotBuf( &globals->cGlobals, XP_TRUE, buf, len, addr );
|
||||
} else {
|
||||
XP_LOGF( "%s: dropping packet; meant for a different device",
|
||||
__func__ );
|
||||
|
@ -1875,44 +1831,6 @@ cursesErrorMsgRcvd( void* closure, const XP_UCHAR* msg )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
curses_app_socket_proc( GIOChannel* source, GIOCondition condition,
|
||||
gpointer data )
|
||||
{
|
||||
if ( 0 != (G_IO_IN & condition) ) {
|
||||
CursesAppGlobals* globals = (CursesAppGlobals*)data;
|
||||
int socket = g_io_channel_unix_get_fd( source );
|
||||
GList* iter;
|
||||
for ( iter = globals->sources; !!iter; iter = iter->next ) {
|
||||
SourceData* sd = (SourceData*)iter->data;
|
||||
if ( sd->channel == source ) {
|
||||
(*sd->proc)( sd->procClosure, socket );
|
||||
break;
|
||||
}
|
||||
}
|
||||
XP_ASSERT( !!iter ); /* didn't fail to find it */
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
cursesUDPSocketChanged( void* closure, int newSock, int XP_UNUSED(oldSock),
|
||||
SockReceiver proc, void* procClosure )
|
||||
{
|
||||
CursesAppGlobals* globals = (CursesAppGlobals*)closure;
|
||||
|
||||
SourceData* sd = g_malloc( sizeof(*sd) );
|
||||
sd->channel = g_io_channel_unix_new( newSock );
|
||||
XP_LOGF( "%s: created channel %p for socket %d", __func__, sd->channel, newSock );
|
||||
sd->watch = g_io_add_watch( sd->channel,
|
||||
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
|
||||
curses_app_socket_proc, globals );
|
||||
sd->proc = proc;
|
||||
sd->procClosure = procClosure;
|
||||
globals->sources = g_list_append( globals->sources, sd );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
chatsTimerFired( gpointer data )
|
||||
{
|
||||
|
@ -1942,6 +1860,49 @@ chatsTimerFired( gpointer data )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* static XP_U16 */
|
||||
/* feedBufferCurses( CommonGlobals* cGlobals, sqlite3_int64 rowid, */
|
||||
/* const XP_U8* buf, XP_U16 len, const CommsAddrRec* from ) */
|
||||
/* { */
|
||||
/* gameGotBuf( cGlobals, XP_TRUE, buf, len, from ); */
|
||||
|
||||
/* /\* GtkGameGlobals* globals = findOpenGame( apg, rowid ); *\/ */
|
||||
|
||||
/* /\* if ( !!globals ) { *\/ */
|
||||
/* /\* gameGotBuf( &globals->cGlobals, XP_TRUE, buf, len, from ); *\/ */
|
||||
/* /\* seed = comms_getChannelSeed( globals->cGlobals.game.comms ); *\/ */
|
||||
/* /\* } else { *\/ */
|
||||
/* /\* GtkGameGlobals tmpGlobals; *\/ */
|
||||
/* /\* if ( loadGameNoDraw( &tmpGlobals, apg->params, rowid ) ) { *\/ */
|
||||
/* /\* gameGotBuf( &tmpGlobals.cGlobals, XP_FALSE, buf, len, from ); *\/ */
|
||||
/* /\* seed = comms_getChannelSeed( tmpGlobals.cGlobals.game.comms ); *\/ */
|
||||
/* /\* saveGame( &tmpGlobals.cGlobals ); *\/ */
|
||||
/* /\* } *\/ */
|
||||
/* /\* freeGlobals( &tmpGlobals ); *\/ */
|
||||
/* /\* } *\/ */
|
||||
/* /\* return seed; *\/ */
|
||||
/* } */
|
||||
|
||||
static void
|
||||
smsMsgReceivedCurses( void* closure, const CommsAddrRec* from,
|
||||
XP_U32 XP_UNUSED(gameID),
|
||||
const XP_U8* buf, XP_U16 len )
|
||||
{
|
||||
LOG_FUNC();
|
||||
CommonGlobals* cGlobals = (CommonGlobals*)closure;
|
||||
gameGotBuf( cGlobals, XP_TRUE, buf, len, from );
|
||||
LOG_RETURN_VOID();
|
||||
/* LaunchParams* params = cGlobals->params; */
|
||||
|
||||
/* sqlite3_int64 rowids[4]; */
|
||||
/* int nRowIDs = VSIZE(rowids); */
|
||||
/* getRowsForGameID( params->pDb, gameID, rowids, &nRowIDs ); */
|
||||
/* for ( int ii = 0; ii < nRowIDs; ++ii ) { */
|
||||
/* gameGotBuf( cGlobals, XP_TRUE, buf, len, from ); */
|
||||
/* // feedBufferCurses( cGlobals, rowids[ii], buf, len, from ); */
|
||||
/* } */
|
||||
}
|
||||
|
||||
void
|
||||
cursesmain( XP_Bool isServer, LaunchParams* params )
|
||||
{
|
||||
|
@ -1960,8 +1921,8 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
|||
g_globals.cGlobals.relaySocket = -1;
|
||||
#endif
|
||||
|
||||
g_globals.cGlobals.socketChanged = curses_socket_changed;
|
||||
g_globals.cGlobals.socketChangedClosure = &g_globals;
|
||||
g_globals.cGlobals.socketAdded = curses_socket_added;
|
||||
g_globals.cGlobals.socketAddedClosure = &g_globals;
|
||||
g_globals.cGlobals.onSave = curses_onGameSaved;
|
||||
g_globals.cGlobals.onSaveClosure = &g_globals;
|
||||
|
||||
|
@ -2071,7 +2032,7 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
|||
.msgNoticeReceived = cursesNoticeRcvd,
|
||||
.devIDReceived = cursesDevIDReceived,
|
||||
.msgErrorMsg = cursesErrorMsgRcvd,
|
||||
.socketChanged = cursesUDPSocketChanged,
|
||||
.socketAdded = curses_socket_added,
|
||||
};
|
||||
|
||||
relaycon_init( params, &procs, &g_globals,
|
||||
|
@ -2081,6 +2042,33 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
|||
linux_doInitialReg( params, idIsNew );
|
||||
}
|
||||
|
||||
#ifdef XWFEATURE_SMS
|
||||
gchar buf[32];
|
||||
const gchar* myPhone = params->connInfo.sms.phone;
|
||||
if ( !!myPhone ) {
|
||||
db_store( params->pDb, KEY_SMSPHONE, myPhone );
|
||||
} else if ( !myPhone && db_fetch( params->pDb, KEY_SMSPHONE, buf, VSIZE(buf) ) ) {
|
||||
params->connInfo.sms.phone = myPhone = buf;
|
||||
}
|
||||
XP_U16 myPort = params->connInfo.sms.port;
|
||||
gchar portbuf[8];
|
||||
if ( 0 < myPort ) {
|
||||
sprintf( portbuf, "%d", myPort );
|
||||
db_store( params->pDb, KEY_SMSPORT, portbuf );
|
||||
} else if ( db_fetch( params->pDb, KEY_SMSPORT, portbuf, VSIZE(portbuf) ) ) {
|
||||
params->connInfo.sms.port = myPort = atoi( portbuf );
|
||||
}
|
||||
|
||||
if ( !!myPhone && myPhone[0] && myPort ) {
|
||||
SMSProcs smsProcs = {
|
||||
.socketAdded = curses_socket_added,
|
||||
.inviteReceived = NULL,
|
||||
.msgReceived = smsMsgReceivedCurses,
|
||||
};
|
||||
linux_sms_init( params, myPhone, myPort, &smsProcs, &g_globals.cGlobals );
|
||||
}
|
||||
#endif
|
||||
|
||||
XWStreamCtxt* stream = NULL;
|
||||
if ( !!params->dbName ) {
|
||||
GSList* games = listGames( params->pDb );
|
||||
|
@ -2264,6 +2252,8 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
|
|||
}
|
||||
relaycon_cleanup( params );
|
||||
|
||||
linux_sms_cleanup( params );
|
||||
|
||||
linux_util_vt_destroy( g_globals.cGlobals.util );
|
||||
} /* cursesmain */
|
||||
#endif /* PLATFORM_NCURSES */
|
||||
|
|
|
@ -1475,43 +1475,31 @@ handle_commit_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
|||
static void
|
||||
handle_invite_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals )
|
||||
{
|
||||
CommsAddrRec addr;
|
||||
CommsCtxt* comms = globals->cGlobals.game.comms;
|
||||
XP_ASSERT( comms );
|
||||
comms_getAddr( comms, &addr );
|
||||
gchar* phone = NULL;
|
||||
gchar* portstr = NULL;
|
||||
AskMInfo infos[] = {
|
||||
{ "Remote phone#", &phone },
|
||||
{ "Remote port", &portstr },
|
||||
};
|
||||
if ( gtkaskm( "Invite whom?", infos, VSIZE(infos) ) ) {
|
||||
int port = atoi( portstr );
|
||||
XP_LOGF( "need to invite using number %s and port %d", phone, port );
|
||||
XP_ASSERT( 0 != port );
|
||||
const CurGameInfo* gi = globals->cGlobals.gi;
|
||||
gchar gameName[64];
|
||||
snprintf( gameName, VSIZE(gameName), "Game %d", gi->gameID );
|
||||
|
||||
CommsConnType typ;
|
||||
for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) {
|
||||
switch ( typ ) {
|
||||
#ifdef XWFEATURE_SMS
|
||||
case COMMS_CONN_SMS: {
|
||||
gchar* phone = NULL;
|
||||
gchar* portstr = NULL;
|
||||
AskMInfo infos[] = {
|
||||
{ "Remote phone#", &phone },
|
||||
{ "Remote port", &portstr },
|
||||
};
|
||||
if ( gtkaskm( "Invite whom?", infos, VSIZE(infos) ) ) {
|
||||
int port = atoi( portstr );
|
||||
XP_LOGF( "need to invite using number %s and port %d", phone, port );
|
||||
XP_ASSERT( 0 != port );
|
||||
const CurGameInfo* gi = globals->cGlobals.gi;
|
||||
gchar gameName[64];
|
||||
snprintf( gameName, VSIZE(gameName), "Game %d", gi->gameID );
|
||||
linux_sms_invite( globals->cGlobals.params, gi, gameName, 1,
|
||||
phone, port );
|
||||
}
|
||||
g_free( phone );
|
||||
g_free( portstr );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
XP_ASSERT( 0 );
|
||||
break;
|
||||
}
|
||||
CommsAddrRec addr;
|
||||
CommsCtxt* comms = globals->cGlobals.game.comms;
|
||||
XP_ASSERT( comms );
|
||||
comms_getAddr( comms, &addr );
|
||||
|
||||
linux_sms_invite( globals->cGlobals.params, gi, &addr, gameName,
|
||||
1, phone, port );
|
||||
}
|
||||
} /* handle_commit_button */
|
||||
g_free( phone );
|
||||
g_free( portstr );
|
||||
} /* handle_invite_button */
|
||||
|
||||
static void
|
||||
gtkUserError( GtkGameGlobals* globals, const char* format, ... )
|
||||
|
@ -2291,117 +2279,6 @@ setupGtkUtilCallbacks( GtkGameGlobals* globals, XW_UtilCtxt* util )
|
|||
} /* setupGtkUtilCallbacks */
|
||||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
#if 0
|
||||
static gboolean
|
||||
newConnectionInput( GIOChannel *source,
|
||||
GIOCondition condition,
|
||||
gpointer data )
|
||||
{
|
||||
gboolean keepSource = TRUE;
|
||||
int sock = g_io_channel_unix_get_fd( source );
|
||||
GtkGameGlobals* globals = (GtkGameGlobals*)data;
|
||||
|
||||
XP_LOGF( "%s(%p):condition = 0x%x", __func__, source, (int)condition );
|
||||
|
||||
/* XP_ASSERT( sock == globals->cGlobals.socket ); */
|
||||
|
||||
if ( (condition & G_IO_IN) != 0 ) {
|
||||
ssize_t nRead;
|
||||
unsigned char buf[1024];
|
||||
CommsAddrRec* addrp = NULL;
|
||||
#if defined XWFEATURE_IP_DIRECT
|
||||
CommsAddrRec addr;
|
||||
#endif
|
||||
|
||||
switch ( comms_getConType( globals->cGlobals.game.comms ) ) {
|
||||
#ifdef XWFEATURE_RELAY
|
||||
case COMMS_CONN_RELAY:
|
||||
XP_ASSERT( globals->cGlobals.relaySocket == sock );
|
||||
nRead = linux_relay_receive( &globals->cGlobals, buf, sizeof(buf) );
|
||||
break;
|
||||
#endif
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
case COMMS_CONN_BT:
|
||||
nRead = linux_bt_receive( sock, buf, sizeof(buf) );
|
||||
break;
|
||||
#endif
|
||||
#ifdef XWFEATURE_SMS
|
||||
case COMMS_CONN_SMS:
|
||||
XP_ASSERT(0);
|
||||
/* addrp = &addr; */
|
||||
/* nRead = linux_sms_receive( &globals->cGlobals, sock, */
|
||||
/* buf, sizeof(buf), addrp ); */
|
||||
break;
|
||||
#endif
|
||||
#ifdef XWFEATURE_IP_DIRECT
|
||||
case COMMS_CONN_IP_DIRECT:
|
||||
addrp = &addr;
|
||||
nRead = linux_udp_receive( sock, buf, sizeof(buf), addrp, &globals->cGlobals );
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
|
||||
if ( !globals->dropIncommingMsgs && nRead > 0 ) {
|
||||
XWStreamCtxt* inboundS;
|
||||
XP_Bool redraw = XP_FALSE;
|
||||
|
||||
inboundS = stream_from_msgbuf( &globals->cGlobals, buf, nRead );
|
||||
if ( !!inboundS ) {
|
||||
XP_LOGF( "%s: got %zd bytes", __func__, nRead );
|
||||
if ( comms_checkIncomingStream( globals->cGlobals.game.comms,
|
||||
inboundS, addrp ) ) {
|
||||
redraw =
|
||||
server_receiveMessage(globals->cGlobals.game.server,
|
||||
inboundS );
|
||||
if ( redraw ) {
|
||||
saveGame( &globals->cGlobals );
|
||||
}
|
||||
}
|
||||
stream_destroy( inboundS );
|
||||
}
|
||||
|
||||
/* if there's something to draw resulting from the message, we
|
||||
need to give the main loop time to reflect that on the screen
|
||||
before giving the server another shot. So just call the idle
|
||||
proc. */
|
||||
if ( redraw ) {
|
||||
gtk_util_requestTime( globals->cGlobals.util );
|
||||
} else {
|
||||
redraw = server_do( globals->cGlobals.game.server );
|
||||
}
|
||||
if ( redraw ) {
|
||||
board_draw( globals->cGlobals.game.board );
|
||||
}
|
||||
} else {
|
||||
XP_LOGF( "errno from read: %d/%s", errno, strerror(errno) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( (condition & (G_IO_HUP | G_IO_ERR)) != 0 ) {
|
||||
XP_LOGF( "dropping socket %d", sock );
|
||||
close( sock );
|
||||
#ifdef XWFEATURE_RELAY
|
||||
globals->cGlobals.relaySocket = -1;
|
||||
#endif
|
||||
if ( 0 ) {
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
} else if ( COMMS_CONN_BT == addr_getType( &globals->cGlobals.params->addr ) ) {
|
||||
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 */
|
||||
}
|
||||
|
||||
return keepSource; /* FALSE means to remove event source */
|
||||
} /* newConnectionInput */
|
||||
#endif
|
||||
|
||||
typedef struct _SockInfo {
|
||||
GIOChannel* channel;
|
||||
guint watch;
|
||||
|
@ -2409,39 +2286,19 @@ typedef struct _SockInfo {
|
|||
} SockInfo;
|
||||
|
||||
static void
|
||||
gtk_socket_changed( void* closure, int oldSock, int newSock, GIOFunc proc,
|
||||
void** storage )
|
||||
gtk_socket_added( void* closure, int newSock, GIOFunc proc )
|
||||
{
|
||||
GtkGameGlobals* globals = (GtkGameGlobals*)closure;
|
||||
SockInfo* info = (SockInfo*)*storage;
|
||||
XP_LOGF( "%s(old:%d; new:%d)", __func__, oldSock, newSock );
|
||||
|
||||
if ( oldSock != -1 ) {
|
||||
XP_ASSERT( info != NULL );
|
||||
g_source_remove( info->watch );
|
||||
g_io_channel_unref( info->channel );
|
||||
XP_FREE( globals->cGlobals.util->mpool, info );
|
||||
*storage = NULL;
|
||||
XP_LOGF( "Removed socket %d from gtk's list of listened-to sockets",
|
||||
oldSock );
|
||||
}
|
||||
if ( newSock != -1 ) {
|
||||
XP_ASSERT( !!proc );
|
||||
info = (SockInfo*)XP_MALLOC( globals->cGlobals.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,
|
||||
proc, globals );
|
||||
info->channel = channel;
|
||||
info->watch = result;
|
||||
*storage = info;
|
||||
XP_LOGF( "g_io_add_watch(%d) => %d", newSock, result );
|
||||
}
|
||||
#ifdef XWFEATURE_RELAY
|
||||
globals->cGlobals.relaySocket = newSock;
|
||||
#endif
|
||||
/* A hack for the bluetooth case. */
|
||||
CommsCtxt* comms = globals->cGlobals.game.comms;
|
||||
|
||||
|
@ -2520,7 +2377,7 @@ drop_msg_toggle( GtkWidget* toggle, GtkGameGlobals* globals )
|
|||
globals->dropIncommingMsgs = gtk_toggle_button_get_active(
|
||||
GTK_TOGGLE_BUTTON(toggle) );
|
||||
} /* drop_msg_toggle */
|
||||
#endif
|
||||
#endif /* #ifndef XWFEATURE_STANDALONE_ONLY */
|
||||
|
||||
/* int */
|
||||
/* board_main( LaunchParams* params ) */
|
||||
|
@ -2561,8 +2418,8 @@ initGlobalsNoDraw( GtkGameGlobals* globals, LaunchParams* params,
|
|||
globals->cGlobals.relaySocket = -1;
|
||||
# endif
|
||||
|
||||
globals->cGlobals.socketChanged = gtk_socket_changed;
|
||||
globals->cGlobals.socketChangedClosure = globals;
|
||||
globals->cGlobals.socketAdded = gtk_socket_added;
|
||||
globals->cGlobals.socketAddedClosure = globals;
|
||||
globals->cGlobals.onSave = onGameSaved;
|
||||
globals->cGlobals.onSaveClosure = globals;
|
||||
globals->cGlobals.addAcceptor = gtk_socket_acceptor;
|
||||
|
|
|
@ -307,7 +307,7 @@ makeSMSPage( GtkConnsState* state, PageData* data )
|
|||
XP_Bool hasSMS = addr_hasType( state->addr, data->pageType );
|
||||
const gchar* phone = hasSMS ?
|
||||
state->addr->u.sms.phone : state->globals->cGlobals.params->connInfo.sms.phone;
|
||||
GtkWidget* hbox = makeLabeledField( "Host phone", &state->smsphone, phone );
|
||||
GtkWidget* hbox = makeLabeledField( "My phone", &state->smsphone, phone );
|
||||
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
|
||||
gtk_widget_set_sensitive( state->smsphone, !state->readOnly );
|
||||
|
||||
|
@ -315,7 +315,7 @@ makeSMSPage( GtkConnsState* state, PageData* data )
|
|||
: state->globals->cGlobals.params->connInfo.sms.port;
|
||||
gchar port[32];
|
||||
snprintf( port, sizeof(port), "%d", portVal );
|
||||
hbox = makeLabeledField( "Host port", &state->smsport, port );
|
||||
hbox = makeLabeledField( "My port", &state->smsport, port );
|
||||
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
|
||||
gtk_widget_set_sensitive( state->smsport, !state->readOnly );
|
||||
|
||||
|
|
|
@ -352,7 +352,8 @@ makeGamesWindow( GtkAppGlobals* apg )
|
|||
}
|
||||
#ifdef XWFEATURE_SMS
|
||||
int len = strlen( title );
|
||||
snprintf( &title[len], VSIZE(title) - len, " (phone: %s)", params->connInfo.sms.phone );
|
||||
snprintf( &title[len], VSIZE(title) - len, " (phone: %s, port: %d)",
|
||||
params->connInfo.sms.phone, params->connInfo.sms.port );
|
||||
#endif
|
||||
gtk_window_set_title( GTK_WINDOW(window), title );
|
||||
|
||||
|
@ -416,8 +417,8 @@ onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid, XP_Bool isNew )
|
|||
}
|
||||
|
||||
static XP_U16
|
||||
feedBuffer( GtkAppGlobals* apg, sqlite3_int64 rowid,
|
||||
const XP_U8* buf, XP_U16 len, const CommsAddrRec* from )
|
||||
feedBufferGTK( GtkAppGlobals* apg, sqlite3_int64 rowid,
|
||||
const XP_U8* buf, XP_U16 len, const CommsAddrRec* from )
|
||||
{
|
||||
XP_U16 seed = 0;
|
||||
GtkGameGlobals* globals = findOpenGame( apg, rowid );
|
||||
|
@ -437,38 +438,31 @@ feedBuffer( GtkAppGlobals* apg, sqlite3_int64 rowid,
|
|||
return seed;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_app_socket_proc( GIOChannel* source, GIOCondition condition, gpointer data )
|
||||
{
|
||||
if ( 0 != (G_IO_IN & condition) ) {
|
||||
GtkAppGlobals* apg = (GtkAppGlobals*)data;
|
||||
int socket = g_io_channel_unix_get_fd( source );
|
||||
GList* iter;
|
||||
for ( iter = apg->sources; !!iter; iter = iter->next ) {
|
||||
SourceData* sd = (SourceData*)iter->data;
|
||||
if ( sd->channel == source ) {
|
||||
(*sd->proc)( sd->procClosure, socket );
|
||||
break;
|
||||
}
|
||||
}
|
||||
XP_ASSERT( !!iter ); /* didn't fail to find it */
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
/* static gboolean */
|
||||
/* gtk_app_socket_proc( GIOChannel* source, GIOCondition condition, gpointer data ) */
|
||||
/* { */
|
||||
/* if ( 0 != (G_IO_IN & condition) ) { */
|
||||
/* GtkAppGlobals* apg = (GtkAppGlobals*)data; */
|
||||
/* int socket = g_io_channel_unix_get_fd( source ); */
|
||||
/* GList* iter; */
|
||||
/* for ( iter = apg->sources; !!iter; iter = iter->next ) { */
|
||||
/* SourceData* sd = (SourceData*)iter->data; */
|
||||
/* if ( sd->channel == source ) { */
|
||||
/* (*sd->proc)( sd->procClosure, socket ); */
|
||||
/* break; */
|
||||
/* } */
|
||||
/* } */
|
||||
/* XP_ASSERT( !!iter ); /\* didn't fail to find it *\/ */
|
||||
/* } */
|
||||
/* return TRUE; */
|
||||
/* } */
|
||||
|
||||
static void
|
||||
gtkSocketChanged( void* closure, int newSock, int XP_UNUSED(oldSock),
|
||||
SockReceiver proc, void* procClosure )
|
||||
gtkSocketAdded( void* closure, int newSock, GIOFunc proc )
|
||||
{
|
||||
#if 1
|
||||
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
||||
SourceData* sd = g_malloc( sizeof(*sd) );
|
||||
sd->channel = g_io_channel_unix_new( newSock );
|
||||
sd->watch = g_io_add_watch( sd->channel, G_IO_IN | G_IO_ERR,
|
||||
gtk_app_socket_proc, apg );
|
||||
sd->proc = proc;
|
||||
sd->procClosure = procClosure;
|
||||
apg->sources = g_list_append( apg->sources, sd );
|
||||
GIOChannel* channel = g_io_channel_unix_new( newSock );
|
||||
(void)g_io_add_watch( channel, G_IO_IN | G_IO_ERR, proc, closure );
|
||||
#else
|
||||
GtkAppGlobals* globals = (GtkAppGlobals*)closure;
|
||||
SockInfo* info = (SockInfo*)*storage;
|
||||
|
@ -513,7 +507,8 @@ gtkSocketChanged( void* closure, int newSock, int XP_UNUSED(oldSock),
|
|||
} /* gtk_socket_changed */
|
||||
|
||||
static void
|
||||
gtkGotBuf( void* closure, const XP_U8* buf, XP_U16 len )
|
||||
gtkGotBuf( void* closure, const CommsAddrRec* from,
|
||||
const XP_U8* buf, XP_U16 len )
|
||||
{
|
||||
LOG_FUNC();
|
||||
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
||||
|
@ -527,7 +522,7 @@ gtkGotBuf( void* closure, const XP_U8* buf, XP_U16 len )
|
|||
XP_U16 gotSeed;
|
||||
rowidFromToken( ntohl( clientToken ), &rowid, &gotSeed );
|
||||
|
||||
XP_U16 seed = feedBuffer( apg, rowid, buf, len, NULL );
|
||||
XP_U16 seed = feedBufferGTK( apg, rowid, buf, len, from );
|
||||
XP_ASSERT( seed == 0 || gotSeed == seed );
|
||||
XP_USE( seed );
|
||||
}
|
||||
|
@ -587,8 +582,8 @@ smsInviteReceived( void* closure, const XP_UCHAR* XP_UNUSED_DBG(gameName),
|
|||
}
|
||||
|
||||
static void
|
||||
smsMsgReceived( void* closure, XP_U32 gameID, const XP_U8* buf, XP_U16 len,
|
||||
const CommsAddrRec* from )
|
||||
smsMsgReceivedGTK( void* closure, const CommsAddrRec* from, XP_U32 gameID,
|
||||
const XP_U8* buf, XP_U16 len )
|
||||
{
|
||||
LOG_FUNC();
|
||||
GtkAppGlobals* apg = (GtkAppGlobals*)closure;
|
||||
|
@ -597,9 +592,9 @@ smsMsgReceived( void* closure, XP_U32 gameID, const XP_U8* buf, XP_U16 len,
|
|||
sqlite3_int64 rowids[4];
|
||||
int nRowIDs = VSIZE(rowids);
|
||||
getRowsForGameID( params->pDb, gameID, rowids, &nRowIDs );
|
||||
int ii;
|
||||
for ( ii = 0; ii < nRowIDs; ++ii ) {
|
||||
feedBuffer( apg, rowids[ii], buf, len, from );
|
||||
XP_LOGF( "%s: found %d rows for gameID %d", __func__, nRowIDs, gameID );
|
||||
for ( int ii = 0; ii < nRowIDs; ++ii ) {
|
||||
feedBufferGTK( apg, rowids[ii], buf, len, from );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -695,7 +690,7 @@ gtkmain( LaunchParams* params )
|
|||
.msgNoticeReceived = gtkNoticeRcvd,
|
||||
.devIDReceived = gtkDevIDReceived,
|
||||
.msgErrorMsg = gtkErrorMsgRcvd,
|
||||
.socketChanged = gtkSocketChanged,
|
||||
.socketAdded = gtkSocketAdded,
|
||||
};
|
||||
|
||||
relaycon_init( params, &procs, &apg,
|
||||
|
@ -707,27 +702,27 @@ gtkmain( LaunchParams* params )
|
|||
|
||||
#ifdef XWFEATURE_SMS
|
||||
gchar buf[32];
|
||||
const gchar* phone = params->connInfo.sms.phone;
|
||||
if ( !!phone ) {
|
||||
db_store( params->pDb, KEY_SMSPHONE, phone );
|
||||
} else if ( !phone && db_fetch( params->pDb, KEY_SMSPHONE, buf, VSIZE(buf) ) ) {
|
||||
params->connInfo.sms.phone = phone = buf;
|
||||
const gchar* myPhone = params->connInfo.sms.phone;
|
||||
if ( !!myPhone ) {
|
||||
db_store( params->pDb, KEY_SMSPHONE, myPhone );
|
||||
} else if ( !myPhone && db_fetch( params->pDb, KEY_SMSPHONE, buf, VSIZE(buf) ) ) {
|
||||
params->connInfo.sms.phone = myPhone = buf;
|
||||
}
|
||||
XP_U16 port = params->connInfo.sms.port;
|
||||
XP_U16 myPort = params->connInfo.sms.port;
|
||||
gchar portbuf[8];
|
||||
if ( 0 < port ) {
|
||||
sprintf( portbuf, "%d", port );
|
||||
if ( 0 < myPort ) {
|
||||
sprintf( portbuf, "%d", myPort );
|
||||
db_store( params->pDb, KEY_SMSPORT, portbuf );
|
||||
} else if ( db_fetch( params->pDb, KEY_SMSPORT, portbuf, VSIZE(portbuf) ) ) {
|
||||
params->connInfo.sms.port = port = atoi( portbuf );
|
||||
params->connInfo.sms.port = myPort = atoi( portbuf );
|
||||
}
|
||||
if ( !!phone && 0 < port ) {
|
||||
if ( !!myPhone && 0 < myPort ) {
|
||||
SMSProcs smsProcs = {
|
||||
.socketChanged = gtkSocketChanged,
|
||||
.socketAdded = gtkSocketAdded,
|
||||
.inviteReceived = smsInviteReceived,
|
||||
.msgReceived = smsMsgReceived,
|
||||
.msgReceived = smsMsgReceivedGTK,
|
||||
};
|
||||
linux_sms_init( params, phone, port, &smsProcs, &apg );
|
||||
linux_sms_init( params, myPhone, myPort, &smsProcs, &apg );
|
||||
} else {
|
||||
XP_LOGF( "not activating SMS: I don't have a phone" );
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
|
||||
typedef struct LinBtStuff {
|
||||
CommonGlobals* globals;
|
||||
void* sockStorage;
|
||||
union {
|
||||
struct {
|
||||
int listener; /* socket */
|
||||
|
@ -187,8 +186,7 @@ lbt_connectSocket( LinBtStuff* btStuff, const CommsAddrRec* addrP )
|
|||
// connect to server
|
||||
&& (0 == connect( sock, (struct sockaddr *)&saddr, sizeof(saddr) )) ) {
|
||||
CommonGlobals* globals = btStuff->globals;
|
||||
(*globals->socketChanged)( globals->socketChangedClosure, -1, sock,
|
||||
bt_socket_proc, &btStuff->sockStorage );
|
||||
(*globals->socketAdded)( globals->socketAddedClosure, sock, bt_socket_proc );
|
||||
btStuff->socket = sock;
|
||||
} else {
|
||||
XP_LOGF( "%s: connect->%s; closing socket %d", __func__, strerror(errno), sock );
|
||||
|
@ -217,8 +215,7 @@ lbt_accept( int listener, void* ctxt )
|
|||
|
||||
success = sock >= 0;
|
||||
if ( success ) {
|
||||
(*globals->socketChanged)( globals->socketChangedClosure, -1, sock,
|
||||
bt_socket_proc, &btStuff->sockStorage );
|
||||
(*globals->socketAdded)( globals->socketAddedClosure, sock, bt_socket_proc );
|
||||
XP_ASSERT( btStuff->socket == -1 );
|
||||
btStuff->socket = sock;
|
||||
} else {
|
||||
|
@ -412,13 +409,6 @@ linux_bt_close( CommonGlobals* globals )
|
|||
sleep( 2 ); /* see if this gives palm a chance to not hang */
|
||||
}
|
||||
|
||||
if ( btStuff->socket != -1 ) {
|
||||
(*globals->socketChanged)( globals->socketChangedClosure,
|
||||
btStuff->socket, -1, NULL,
|
||||
&btStuff->sockStorage );
|
||||
(void)close( btStuff->socket );
|
||||
}
|
||||
|
||||
XP_FREE( globals->util->mpool, btStuff );
|
||||
globals->btStuff = NULL;
|
||||
}
|
||||
|
|
|
@ -645,6 +645,7 @@ typedef enum {
|
|||
#endif
|
||||
#ifdef XWFEATURE_SMS
|
||||
,CMD_SMSNUMBER /* SMS phone number */
|
||||
,CMD_SMSPORT
|
||||
#endif
|
||||
#ifdef XWFEATURE_RELAY
|
||||
,CMD_ROOMNAME
|
||||
|
@ -756,7 +757,8 @@ static CmdInfoRec CmdInfoRecs[] = {
|
|||
,{ CMD_HINTRECT, false, "hintrect", "enable draggable hint-limits rect" }
|
||||
#endif
|
||||
#ifdef XWFEATURE_SMS
|
||||
,{ CMD_SMSNUMBER, true, "sms-number", "phone number of host for sms game" }
|
||||
,{ CMD_SMSNUMBER, true, "sms-number", "this devices's sms phone number" }
|
||||
,{ CMD_SMSPORT, true, "sms-port", "this devices's sms port" }
|
||||
#endif
|
||||
#ifdef XWFEATURE_RELAY
|
||||
,{ CMD_ROOMNAME, true, "room", "name of room on relay" }
|
||||
|
@ -1006,9 +1008,6 @@ send_or_close( CommonGlobals* cGlobals, const XP_U8* buf, size_t len )
|
|||
bool success = len == nSent;
|
||||
if ( !success ) {
|
||||
close( cGlobals->relaySocket );
|
||||
(*cGlobals->socketChanged)( cGlobals->socketChangedClosure,
|
||||
cGlobals->relaySocket, -1,
|
||||
NULL, &cGlobals->storage );
|
||||
cGlobals->relaySocket = -1;
|
||||
|
||||
/* delete all pending packets since the socket's bad */
|
||||
|
@ -1137,12 +1136,7 @@ linux_relay_send( CommonGlobals* cGlobals, const XP_U8* buf, XP_U16 buflen,
|
|||
if ( sock == -1 ) {
|
||||
XP_LOGF( "%s: socket uninitialized", __func__ );
|
||||
sock = linux_init_relay_socket( cGlobals, addrRec );
|
||||
if ( sock != -1 ) {
|
||||
assert( cGlobals->relaySocket == sock );
|
||||
(*cGlobals->socketChanged)( cGlobals->socketChangedClosure,
|
||||
-1, sock, linux_relay_ioproc,
|
||||
(void*)cGlobals );
|
||||
}
|
||||
(*cGlobals->socketAdded)( cGlobals, sock, linux_relay_ioproc );
|
||||
}
|
||||
|
||||
if ( sock != -1 ) {
|
||||
|
@ -1267,14 +1261,8 @@ void
|
|||
linux_close_socket( CommonGlobals* cGlobals )
|
||||
{
|
||||
LOG_FUNC();
|
||||
int socket = cGlobals->relaySocket;
|
||||
|
||||
(*cGlobals->socketChanged)( cGlobals->socketChangedClosure,
|
||||
socket, -1, NULL, &cGlobals->storage );
|
||||
|
||||
XP_ASSERT( -1 == cGlobals->relaySocket );
|
||||
|
||||
close( socket );
|
||||
close( cGlobals->relaySocket );
|
||||
cGlobals->relaySocket = -1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2227,6 +2215,10 @@ main( int argc, char** argv )
|
|||
mainParams.connInfo.sms.phone = optarg;
|
||||
addr_addType( &mainParams.addr, COMMS_CONN_SMS );
|
||||
break;
|
||||
case CMD_SMSPORT:
|
||||
mainParams.connInfo.sms.port = atoi(optarg);
|
||||
addr_addType( &mainParams.addr, COMMS_CONN_SMS );
|
||||
break;
|
||||
#endif
|
||||
case CMD_DUPPACKETS:
|
||||
mainParams.duplicatePackets = XP_TRUE;
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
* checked.
|
||||
*/
|
||||
|
||||
#define ADDR_FMT "from: %s %d\n"
|
||||
|
||||
static void
|
||||
makeQueuePath( const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_UCHAR* path, XP_U16 pathlen )
|
||||
|
@ -63,7 +65,7 @@ makeQueuePath( const XP_UCHAR* phone, XP_U16 port,
|
|||
typedef struct _LinSMSData {
|
||||
int fd, wd;
|
||||
XP_UCHAR myQueue[256];
|
||||
XP_U16 port;
|
||||
XP_U16 myPort;
|
||||
FILE* lock;
|
||||
XP_U16 count;
|
||||
|
||||
|
@ -86,6 +88,7 @@ lock_queue( LinSMSData* storage )
|
|||
char lock[256];
|
||||
snprintf( lock, sizeof(lock), "%s/%s", storage->myQueue, LOCK_FILE );
|
||||
FILE* fp = fopen( lock, "w" );
|
||||
XP_ASSERT( !!fp );
|
||||
XP_ASSERT( NULL == storage->lock );
|
||||
storage->lock = fp;
|
||||
}
|
||||
|
@ -94,11 +97,11 @@ static void
|
|||
unlock_queue( LinSMSData* storage )
|
||||
{
|
||||
XP_ASSERT( NULL != storage->lock );
|
||||
fclose( storage->lock );
|
||||
FILE* lock = storage->lock;
|
||||
storage->lock = NULL;
|
||||
fclose( lock );
|
||||
}
|
||||
|
||||
|
||||
static XP_S16
|
||||
send_sms( LinSMSData* storage, XWStreamCtxt* stream,
|
||||
const XP_UCHAR* phone, XP_U16 port )
|
||||
|
@ -141,7 +144,7 @@ send_sms( LinSMSData* storage, XWStreamCtxt* stream,
|
|||
|
||||
FILE* fp = fopen( path, "w" );
|
||||
XP_ASSERT( !!fp );
|
||||
(void)fprintf( fp, "from: %s\n", storage->myPhone );
|
||||
(void)fprintf( fp, ADDR_FMT, storage->myPhone, storage->myPort );
|
||||
(void)fprintf( fp, "%s\n", sms );
|
||||
fclose( fp );
|
||||
sync();
|
||||
|
@ -171,11 +174,12 @@ decodeAndDelete( LinSMSData* storage, const gchar* name,
|
|||
XP_ASSERT( success );
|
||||
unlink( path );
|
||||
|
||||
if ( 0 == strncmp( "from: ", contents, 6 ) ) {
|
||||
char phone[32];
|
||||
char phone[32];
|
||||
int port;
|
||||
int matched = sscanf( contents, ADDR_FMT, phone, &port );
|
||||
if ( 2 == matched ) {
|
||||
gchar* eol = strstr( contents, "\n" );
|
||||
*eol = '\0';
|
||||
XP_STRNCPY( phone, &contents[6], sizeof(phone) );
|
||||
XP_ASSERT( !*eol );
|
||||
++eol; /* skip NULL */
|
||||
*strstr(eol, "\n" ) = '\0';
|
||||
|
@ -190,9 +194,11 @@ decodeAndDelete( LinSMSData* storage, const gchar* name,
|
|||
nRead = outlen;
|
||||
addr_setType( addr, COMMS_CONN_SMS );
|
||||
XP_STRNCPY( addr->u.sms.phone, phone, sizeof(addr->u.sms.phone) );
|
||||
XP_LOGF( "%s: message came from phone: %s", __func__, phone );
|
||||
addr->u.sms.port = 1; /* for now */
|
||||
XP_LOGF( "%s: message came from phone: %s, port: %d", __func__, phone, port );
|
||||
addr->u.sms.port = port;
|
||||
}
|
||||
} else {
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
|
||||
g_free( contents );
|
||||
|
@ -203,7 +209,7 @@ decodeAndDelete( LinSMSData* storage, const gchar* name,
|
|||
|
||||
static void
|
||||
dispatch_invite( LinSMSData* storage, XP_U16 XP_UNUSED(proto),
|
||||
XWStreamCtxt* stream, const CommsAddrRec* addr )
|
||||
XWStreamCtxt* stream, CommsAddrRec* addr )
|
||||
{
|
||||
XP_UCHAR gameName[256];
|
||||
XP_UCHAR dictName[256];
|
||||
|
@ -216,33 +222,35 @@ dispatch_invite( LinSMSData* storage, XP_U16 XP_UNUSED(proto),
|
|||
XP_U8 nMissing = stream_getU8( stream );
|
||||
XP_U8 nPlayers = stream_getU8( stream );
|
||||
|
||||
(*storage->procs->inviteReceived)( storage->procClosure, gameName, gameID,
|
||||
dictLang, dictName, nPlayers, nMissing,
|
||||
addr );
|
||||
addrFromStream( addr, stream );
|
||||
|
||||
(*storage->procs->inviteReceived)( storage->procClosure, gameName,
|
||||
gameID, dictLang, dictName, nPlayers,
|
||||
nMissing, addr );
|
||||
}
|
||||
|
||||
static void
|
||||
dispatch_data( LinSMSData* storage, XP_U16 XP_UNUSED(proto),
|
||||
XWStreamCtxt* stream, const CommsAddrRec* addr )
|
||||
{
|
||||
XP_USE( addr );
|
||||
XP_U32 gameID = stream_getU32( stream );
|
||||
XP_U16 len = stream_getSize( stream );
|
||||
XP_U8 data[len];
|
||||
stream_getBytes( stream, data, len );
|
||||
|
||||
(*storage->procs->msgReceived)( storage->procClosure, gameID,
|
||||
data, len, addr );
|
||||
(*storage->procs->msgReceived)( storage->procClosure, addr, gameID,
|
||||
data, len );
|
||||
}
|
||||
|
||||
static void
|
||||
parseAndDispatch( LaunchParams* params, uint8_t* buf, int len,
|
||||
const CommsAddrRec* addr )
|
||||
CommsAddrRec* addr )
|
||||
{
|
||||
LinSMSData* storage = getStorage( params );
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(params->mpool)
|
||||
params->vtMgr,
|
||||
NULL, CHANNEL_NONE, NULL );
|
||||
stream_setVersion( stream, CUR_STREAM_VERS );
|
||||
stream_putBytes( stream, buf, len );
|
||||
|
||||
XP_U8 proto = stream_getU8( stream );
|
||||
|
@ -265,14 +273,16 @@ parseAndDispatch( LaunchParams* params, uint8_t* buf, int len,
|
|||
stream_destroy( stream );
|
||||
}
|
||||
|
||||
static void
|
||||
sms_receive( void* closure, int socket )
|
||||
static gboolean
|
||||
sms_receive( GIOChannel *source, GIOCondition condition, gpointer data )
|
||||
{
|
||||
LOG_FUNC();
|
||||
LaunchParams* params = (LaunchParams*)closure;
|
||||
XP_ASSERT( 0 != (G_IO_IN & condition) );
|
||||
LaunchParams* params = (LaunchParams*)data;
|
||||
XP_ASSERT( !!params->smsStorage );
|
||||
LinSMSData* storage = getStorage( params );
|
||||
|
||||
int socket = g_io_channel_unix_get_fd( source );
|
||||
XP_ASSERT( socket == storage->fd );
|
||||
|
||||
lock_queue( storage );
|
||||
|
@ -281,6 +291,7 @@ sms_receive( void* closure, int socket )
|
|||
about the result or the buffer contents. */
|
||||
XP_U8 buffer[sizeof(struct inotify_event) + 16];
|
||||
if ( 0 > read( socket, buffer, sizeof(buffer) ) ) {
|
||||
XP_LOGF( "%s: discarding inotify buffer", __func__ );
|
||||
}
|
||||
for ( ; ; ) {
|
||||
XP_S16 nRead = -1;
|
||||
|
@ -306,6 +317,8 @@ sms_receive( void* closure, int socket )
|
|||
XP_LOGF( "%s: decoding message %s", __func__, shortest );
|
||||
nRead = decodeAndDelete( storage, shortest, buf,
|
||||
sizeof(buf), &fromAddr );
|
||||
} else {
|
||||
XP_LOGF( "%s: never found shortest", __func__ );
|
||||
}
|
||||
|
||||
unlock_queue( storage );
|
||||
|
@ -317,22 +330,25 @@ sms_receive( void* closure, int socket )
|
|||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
} /* sms_receive */
|
||||
|
||||
void
|
||||
linux_sms_init( LaunchParams* params, const gchar* phone, XP_U16 port,
|
||||
linux_sms_init( LaunchParams* params, const gchar* myPhone, XP_U16 myPort,
|
||||
const SMSProcs* procs, void* procClosure )
|
||||
{
|
||||
XP_ASSERT( !!phone );
|
||||
LOG_FUNC();
|
||||
XP_ASSERT( !!myPhone );
|
||||
LinSMSData* storage = getStorage( params );
|
||||
XP_ASSERT( !!storage );
|
||||
storage->myPhone = phone;
|
||||
storage->myPhone = myPhone;
|
||||
storage->myPort = myPort;
|
||||
storage->procs = procs;
|
||||
storage->procClosure = procClosure;
|
||||
|
||||
makeQueuePath( phone, port, storage->myQueue, sizeof(storage->myQueue) );
|
||||
makeQueuePath( myPhone, myPort, storage->myQueue, sizeof(storage->myQueue) );
|
||||
XP_LOGF( "%s: my queue: %s", __func__, storage->myQueue );
|
||||
storage->port = params->connInfo.sms.port;
|
||||
storage->myPort = params->connInfo.sms.port;
|
||||
|
||||
(void)g_mkdir_with_parents( storage->myQueue, 0777 );
|
||||
|
||||
|
@ -340,13 +356,13 @@ linux_sms_init( LaunchParams* params, const gchar* phone, XP_U16 port,
|
|||
storage->fd = fd;
|
||||
storage->wd = inotify_add_watch( fd, storage->myQueue, IN_MODIFY );
|
||||
|
||||
(*procs->socketChanged)( procClosure, fd, -1, sms_receive, params );
|
||||
(*procs->socketAdded)( params, fd, sms_receive );
|
||||
} /* linux_sms_init */
|
||||
|
||||
void
|
||||
linux_sms_invite( LaunchParams* params, const CurGameInfo* gi,
|
||||
const gchar* gameName, XP_U16 nMissing, const gchar* phone,
|
||||
int port )
|
||||
const CommsAddrRec* addr, const gchar* gameName,
|
||||
XP_U16 nMissing, const gchar* toPhone, int toPort )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XWStreamCtxt* stream;
|
||||
|
@ -360,18 +376,20 @@ linux_sms_invite( LaunchParams* params, const CurGameInfo* gi,
|
|||
stream_putU8( stream, nMissing );
|
||||
stream_putU8( stream, gi->nPlayers );
|
||||
|
||||
addrToStream( stream, addr );
|
||||
|
||||
LinSMSData* storage = getStorage( params );
|
||||
send_sms( storage, stream, phone, port );
|
||||
send_sms( storage, stream, toPhone, toPort );
|
||||
|
||||
stream_destroy( stream );
|
||||
}
|
||||
|
||||
XP_S16
|
||||
linux_sms_send( LaunchParams* params, const XP_U8* buf,
|
||||
XP_U16 buflen, const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_U32 gameID )
|
||||
XP_U16 buflen, const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_U32 gameID )
|
||||
{
|
||||
LOG_FUNC();
|
||||
XP_LOGF( "%s(len=%d)", __func__, buflen );
|
||||
XWStreamCtxt* stream = mem_stream_make( MPPARM(params->mpool) params->vtMgr,
|
||||
NULL, CHANNEL_NONE, NULL );
|
||||
writeHeader( stream, DATA );
|
||||
|
|
|
@ -29,15 +29,13 @@ typedef struct _SMSProcs {
|
|||
XP_U32 gameID, XP_U16 dictLang,
|
||||
const XP_UCHAR* dictName, XP_U16 nPlayers,
|
||||
XP_U16 nHere, const CommsAddrRec* returnAddr );
|
||||
void (*msgReceived)( void* closure, XP_U32 gameID, const XP_U8* buf,
|
||||
XP_U16 len, const CommsAddrRec* from );
|
||||
void (*msgReceived)( void* closure, const CommsAddrRec* from, XP_U32 gameID,
|
||||
const XP_U8* buf, XP_U16 len );
|
||||
void (*msgNoticeReceived)( void* closure );
|
||||
void (*devIDReceived)( void* closure, const XP_UCHAR* devID,
|
||||
XP_U16 maxInterval );
|
||||
void (*msgErrorMsg)( void* closure, const XP_UCHAR* msg );
|
||||
void (*socketChanged)( void* closure, int newSock, int oldSock,
|
||||
SockReceiver proc, void* procClosure );
|
||||
|
||||
SocketAddedFunc socketAdded;
|
||||
} SMSProcs;
|
||||
|
||||
|
||||
|
@ -47,6 +45,7 @@ XP_S16 linux_sms_send( LaunchParams* params, const XP_U8* buf,
|
|||
XP_U16 buflen, const XP_UCHAR* phone, XP_U16 port,
|
||||
XP_U32 gameID );
|
||||
void linux_sms_invite( LaunchParams* params, const CurGameInfo* info,
|
||||
const CommsAddrRec* addr,
|
||||
const gchar* gameName, XP_U16 nMissing,
|
||||
const gchar* phone, int port );
|
||||
void linux_sms_cleanup( LaunchParams* params );
|
||||
|
|
|
@ -161,8 +161,7 @@ typedef struct LaunchParams {
|
|||
|
||||
typedef struct CommonGlobals CommonGlobals;
|
||||
|
||||
typedef void (*SocketChangedFunc)(void* closure, int oldsock, int newsock,
|
||||
GIOFunc func, void** storage );
|
||||
typedef void (*SocketAddedFunc)( void* closure, int newsock, GIOFunc func );
|
||||
typedef XP_Bool (*Acceptor)( int sock, void* ctxt );
|
||||
typedef void (*AddAcceptorFunc)(int listener, Acceptor func,
|
||||
CommonGlobals* globals, void** storage );
|
||||
|
@ -197,8 +196,8 @@ struct CommonGlobals {
|
|||
sqlite3* pDb;
|
||||
sqlite3_int64 selRow;
|
||||
|
||||
SocketChangedFunc socketChanged;
|
||||
void* socketChangedClosure;
|
||||
SocketAddedFunc socketAdded;
|
||||
void* socketAddedClosure;
|
||||
OnSaveFunc onSave;
|
||||
void* onSaveClosure;
|
||||
GSList* packetQueue;
|
||||
|
|
|
@ -40,7 +40,8 @@ typedef struct _MsgHeader {
|
|||
|
||||
static RelayConStorage* getStorage( LaunchParams* params );
|
||||
static XP_U32 hostNameToIP( const XP_UCHAR* name );
|
||||
static void relaycon_receive( void* closure, int socket );
|
||||
static gboolean relaycon_receive( GIOChannel *source, GIOCondition condition,
|
||||
gpointer data );
|
||||
static ssize_t sendIt( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len );
|
||||
static size_t addVLIStr( XP_U8* buf, size_t len, const XP_UCHAR* str );
|
||||
static void getNetString( const XP_U8** ptr, XP_U16 len, XP_UCHAR* buf );
|
||||
|
@ -67,8 +68,7 @@ relaycon_init( LaunchParams* params, const RelayConnProcs* procs,
|
|||
storage->procsClosure = procsClosure;
|
||||
|
||||
storage->socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
||||
(*procs->socketChanged)( procsClosure, storage->socket, -1,
|
||||
relaycon_receive, params );
|
||||
(*procs->socketAdded)( storage, storage->socket, relaycon_receive );
|
||||
|
||||
XP_MEMSET( &storage->saddr, 0, sizeof(storage->saddr) );
|
||||
storage->saddr.sin_family = PF_INET;
|
||||
|
@ -203,16 +203,16 @@ sendAckIf( RelayConStorage* storage, const MsgHeader* header )
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
relaycon_receive( void* closure, int socket )
|
||||
static gboolean
|
||||
relaycon_receive( GIOChannel* source, GIOCondition condition, gpointer data )
|
||||
{
|
||||
LaunchParams* params = (LaunchParams*)closure;
|
||||
XP_ASSERT( !!params->relayConStorage );
|
||||
RelayConStorage* storage = getStorage( params );
|
||||
XP_ASSERT( 0 != (G_IO_IN & condition) ); /* FIX ME */
|
||||
RelayConStorage* storage = (RelayConStorage*)data;
|
||||
XP_U8 buf[512];
|
||||
struct sockaddr_in from;
|
||||
socklen_t fromlen = sizeof(from);
|
||||
|
||||
int socket = g_io_channel_unix_get_fd( source );
|
||||
XP_LOGF( "%s: calling recvfrom on socket %d", __func__, socket );
|
||||
|
||||
ssize_t nRead = recvfrom( socket, buf, sizeof(buf), 0, /* flags */
|
||||
|
@ -242,9 +242,12 @@ relaycon_receive( void* closure, int socket )
|
|||
maxInterval );
|
||||
}
|
||||
break;
|
||||
case XWPDEV_MSG:
|
||||
(*storage->procs.msgReceived)( storage->procsClosure,
|
||||
case XWPDEV_MSG: {
|
||||
CommsAddrRec addr = {0};
|
||||
addr_addType( &addr, COMMS_CONN_RELAY );
|
||||
(*storage->procs.msgReceived)( storage->procsClosure, &addr,
|
||||
ptr, end - ptr );
|
||||
}
|
||||
break;
|
||||
case XWPDEV_BADREG:
|
||||
(*storage->procs.devIDReceived)( storage->procsClosure, NULL, 0 );
|
||||
|
@ -296,6 +299,7 @@ relaycon_receive( void* closure, int socket )
|
|||
XP_LOGF( "%s: error reading udp socket: %d (%s)", __func__,
|
||||
errno, strerror(errno) );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -23,14 +23,13 @@
|
|||
#include "main.h"
|
||||
|
||||
typedef struct _Procs {
|
||||
void (*msgReceived)( void* closure, const XP_U8* buf, XP_U16 len );
|
||||
void (*msgReceived)( void* closure, const CommsAddrRec* from,
|
||||
const XP_U8* buf, XP_U16 len );
|
||||
void (*msgNoticeReceived)( void* closure );
|
||||
void (*devIDReceived)( void* closure, const XP_UCHAR* devID,
|
||||
XP_U16 maxInterval );
|
||||
void (*msgErrorMsg)( void* closure, const XP_UCHAR* msg );
|
||||
void (*socketChanged)( void* closure, int newSock, int oldSock,
|
||||
SockReceiver proc, void* procClosure );
|
||||
|
||||
SocketAddedFunc socketAdded;
|
||||
} RelayConnProcs;
|
||||
|
||||
void relaycon_init( LaunchParams* params, const RelayConnProcs* procs,
|
||||
|
|
Loading…
Reference in a new issue