From 17bc0ab47cda82349bf5dfeece2c080d6e1303db Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 5 Nov 2014 07:41:20 -0800 Subject: [PATCH] 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. --- xwords4/common/comms.c | 320 ++++++++++++++++++++++++++---------- xwords4/linux/cursesmain.c | 184 ++++++++++----------- xwords4/linux/gtkboard.c | 197 +++------------------- xwords4/linux/gtkconnsdlg.c | 4 +- xwords4/linux/gtkmain.c | 99 ++++++----- xwords4/linux/linuxbt.c | 14 +- xwords4/linux/linuxmain.c | 28 ++-- xwords4/linux/linuxsms.c | 82 +++++---- xwords4/linux/linuxsms.h | 9 +- xwords4/linux/main.h | 7 +- xwords4/linux/relaycon.c | 24 +-- xwords4/linux/relaycon.h | 7 +- 12 files changed, 481 insertions(+), 494 deletions(-) diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index a41eecca6..69a816ae9 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -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 */ diff --git a/xwords4/linux/cursesmain.c b/xwords4/linux/cursesmain.c index 87cca79ec..33efd395c 100644 --- a/xwords4/linux/cursesmain.c +++ b/xwords4/linux/cursesmain.c @@ -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 */ diff --git a/xwords4/linux/gtkboard.c b/xwords4/linux/gtkboard.c index 1af9ff957..fa91dc23d 100644 --- a/xwords4/linux/gtkboard.c +++ b/xwords4/linux/gtkboard.c @@ -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; diff --git a/xwords4/linux/gtkconnsdlg.c b/xwords4/linux/gtkconnsdlg.c index c758383bc..b77542c58 100644 --- a/xwords4/linux/gtkconnsdlg.c +++ b/xwords4/linux/gtkconnsdlg.c @@ -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 ); diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index fc215b6bf..92952f299 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -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" ); } diff --git a/xwords4/linux/linuxbt.c b/xwords4/linux/linuxbt.c index 059040ec4..283eb2bcc 100644 --- a/xwords4/linux/linuxbt.c +++ b/xwords4/linux/linuxbt.c @@ -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; } diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index 24e59d057..42b97210d 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -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; diff --git a/xwords4/linux/linuxsms.c b/xwords4/linux/linuxsms.c index 766d15a0a..21fd25cd1 100644 --- a/xwords4/linux/linuxsms.c +++ b/xwords4/linux/linuxsms.c @@ -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 ); diff --git a/xwords4/linux/linuxsms.h b/xwords4/linux/linuxsms.h index 7bbdb283a..3d04011e4 100644 --- a/xwords4/linux/linuxsms.h +++ b/xwords4/linux/linuxsms.h @@ -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 ); diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index 6ab37508d..0e27c1edf 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -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; diff --git a/xwords4/linux/relaycon.c b/xwords4/linux/relaycon.c index 379f8365b..7a5727181 100644 --- a/xwords4/linux/relaycon.c +++ b/xwords4/linux/relaycon.c @@ -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 diff --git a/xwords4/linux/relaycon.h b/xwords4/linux/relaycon.h index 66ad5cf36..30ebb1bc3 100644 --- a/xwords4/linux/relaycon.h +++ b/xwords4/linux/relaycon.h @@ -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,