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,