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:
Eric House 2014-11-05 07:41:20 -08:00
parent fc6ccf217f
commit 17bc0ab47c
12 changed files with 481 additions and 494 deletions

View file

@ -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 */

View file

@ -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 */

View file

@ -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;

View file

@ -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 );

View file

@ -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" );
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 );

View file

@ -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 );

View file

@ -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;

View file

@ -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

View file

@ -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,