From 4996d3fe89857e2f05e0ea8d35fbde3077d5f6c1 Mon Sep 17 00:00:00 2001 From: Eric House Date: Sat, 3 Sep 2022 18:47:04 -0700 Subject: [PATCH] improve comms address tracking (breaks android for now) Remove legacy relay-inspired logic around comms addressing. Now when a device creates a game it's required to provide its "self address," and if it's a client, the address of the host (which it presumably got through the invitation in response to which the game is being created.) Then as registration messages come in from clients, the host gathers their addresses as always. --- xwords4/common/comms.c | 332 +++++++++++++++------------- xwords4/common/comms.h | 19 +- xwords4/common/game.c | 43 ++-- xwords4/common/game.h | 10 +- xwords4/common/knownplyr.c | 1 - xwords4/common/nli.c | 21 +- xwords4/common/server.c | 12 +- xwords4/linux/cursesboard.c | 53 +---- xwords4/linux/gtkboard.c | 55 +---- xwords4/linux/gtkmain.c | 71 +----- xwords4/linux/linuxmain.c | 232 +++++-------------- xwords4/linux/linuxmain.h | 5 +- xwords4/linux/main.h | 6 +- xwords4/linux/scripts/discon_ok2.py | 2 + 14 files changed, 311 insertions(+), 551 deletions(-) diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index 25f11cd92..a60a0f5ab 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 - 2021 by Eric House (xwords@eehouse.org). All rights + * Copyright 2001 - 2022 by Eric House (xwords@eehouse.org). All rights * reserved. * * This program is free software; you can redistribute it and/or @@ -251,6 +251,9 @@ static void putDevID( const CommsCtxt* comms, XWEnv xwe, XWStreamCtxt* stream ); #endif #ifdef DEBUG +static void assertAddrOk( const CommsAddrRec* addr ); +#define ASSERT_ADDR_OK(addr) assertAddrOk( addr ) + # ifdef XWFEATURE_RELAY static const char* relayCmdToStr( XWRELAY_Cmd cmd ); # endif @@ -261,6 +264,7 @@ static void logAddrs( const CommsCtxt* comms, XWEnv xwe, const char* caller ); #else +#define ASSERT_ADDR_OK(addr) #define printQueue( comms ) #define logAddr( comms, xwe, addr, caller) #define logAddrs( comms, caller ) @@ -380,6 +384,7 @@ init_relay( CommsCtxt* comms, XWEnv xwe, XP_U16 nPlayersHere, XP_U16 nPlayersTot CommsCtxt* comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer, + const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr, #ifdef XWFEATURE_RELAY XP_U16 nPlayersHere, XP_U16 nPlayersTotal, #endif @@ -422,6 +427,22 @@ comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer, comms->channelSeed = gameSeed; # endif #endif + + if ( !!selfAddr ) { + logAddr( comms, xwe, selfAddr, __func__ ); + comms_augmentHostAddr( comms, xwe, selfAddr ); + } + if ( !!hostAddr ) { + XP_ASSERT( !isServer ); + logAddr( comms, xwe, hostAddr, __func__ ); + XP_PlayerAddr channelNo = comms_getChannelSeed( comms ); +#ifdef DEBUG + AddressRecord* rec = +#endif + rememberChannelAddress( comms, xwe, channelNo, 0, hostAddr,0 ); + XP_ASSERT( rec == getRecordFor( comms, xwe, hostAddr, channelNo, XP_TRUE ) ); + } + return comms; } /* comms_make */ @@ -697,6 +718,7 @@ addrFromStream( CommsAddrRec* addrP, XWStreamCtxt* stream ) for ( XP_U32 st = 0; addr_iter( addrP, &typ, &st ); ) { addrFromStreamOne( addrP, stream, typ ); } + ASSERT_ADDR_OK( addrP ); } /* Return TRUE if there are no addresses left that include relay */ @@ -756,7 +778,7 @@ comms_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream, nPlayersHere = 0; nPlayersTotal = 0; } - CommsCtxt* comms = comms_make( MPPARM(mpool) xwe, util, isServer, + CommsCtxt* comms = comms_make( MPPARM(mpool) xwe, util, isServer, NULL, NULL, #ifdef XWFEATURE_RELAY nPlayersHere, nPlayersTotal, #endif @@ -961,7 +983,8 @@ sendConnect( CommsCtxt* comms, XWEnv xwe } /* sendConnect */ static void -addrToStreamOne( XWStreamCtxt* stream, CommsConnType typ, const CommsAddrRec* addrP ) +addrToStreamOne( XWStreamCtxt* stream, CommsConnType typ, + const CommsAddrRec* addrP ) { switch( typ ) { case COMMS_CONN_NONE: @@ -998,6 +1021,7 @@ addrToStreamOne( XWStreamCtxt* stream, CommsConnType typ, const CommsAddrRec* ad case COMMS_CONN_NFC: break; case COMMS_CONN_MQTT: + XP_ASSERT( 0 != addrP->u.mqtt.devID ); stream_putBytes( stream, &addrP->u.mqtt.devID, sizeof(addrP->u.mqtt.devID) ); break; default: @@ -1057,9 +1081,9 @@ comms_writeToStream( CommsCtxt* comms, XWEnv XP_UNUSED_DBG(xwe), #endif for ( rec = comms->recs; !!rec; rec = rec->next ) { - CommsAddrRec* addr = &rec->addr; - addrToStream( stream, addr ); + const CommsAddrRec* addr = &rec->addr; logAddr( comms, xwe, addr, __func__ ); + addrToStream( stream, addr ); stream_putU32VL( stream, rec->nextMsgID ); stream_putU32VL( stream, rec->lastMsgRcd ); @@ -1069,7 +1093,7 @@ comms_writeToStream( CommsCtxt* comms, XWEnv XP_UNUSED_DBG(xwe), #endif stream_putU16( stream, (XP_U16)rec->lastMsgAckd ); stream_putU16( stream, rec->channelNo ); - if ( addr_hasType( &rec->addr, COMMS_CONN_RELAY ) ) { + if ( addr_hasType( addr, COMMS_CONN_RELAY ) ) { stream_putU8( stream, rec->rr.hostID ); /* unneeded unless RELAY */ } } @@ -1174,15 +1198,20 @@ comms_addMQTTDevID( CommsCtxt* comms, XP_PlayerAddr channelNo, if ( found ) { if ( addr_hasType( &rec->addr, COMMS_CONN_MQTT ) ) { XP_ASSERT( *devID == rec->addr.u.mqtt.devID ); + } else { + CommsAddrRec tmp = {0}; + addr_setType( &tmp, COMMS_CONN_MQTT ); + tmp.u.mqtt.devID = *devID; + ASSERT_ADDR_OK( &tmp ); + + augmentAddrIntrnl( comms, &rec->addr, &tmp, XP_TRUE ); + ASSERT_ADDR_OK( &rec->addr ); } - CommsAddrRec addr = {0}; - addr_setType( &addr, COMMS_CONN_MQTT ); - addr.u.mqtt.devID = *devID; - augmentAddrIntrnl( comms, &rec->addr, &addr, XP_TRUE ); } } if ( !found ) { XP_LOGFF( "unable to augment address!!" ); + XP_ASSERT(0); } #endif } @@ -1260,55 +1289,6 @@ formatMsgNo( const CommsCtxt* comms, const MsgQueueElem* elem, XP_SNPRINTF( buf, len, "%d:%d", comms->rr.myHostID, elem->msgID ); } -void -comms_getInitialAddr( CommsAddrRec* addr -#ifdef XWFEATURE_RELAY - , const XP_UCHAR* relayName - , XP_U16 relayPort -#endif - ) -{ - XP_MEMSET( addr, 0, sizeof(*addr) ); -#if defined XWFEATURE_RELAY - addr_setType( addr, COMMS_CONN_RELAY ); /* for temporary ease in debugging */ - addr->u.ip_relay.ipAddr = 0L; /* force 'em to set it */ - addr->u.ip_relay.port = relayPort; - { - const char* name = relayName; - char* room = RELAY_ROOM_DEFAULT; - XP_MEMCPY( addr->u.ip_relay.hostName, name, XP_STRLEN(name)+1 ); - XP_MEMCPY( addr->u.ip_relay.invite, room, XP_STRLEN(room)+1 ); - } - addr->u.ip_relay.seeksPublicRoom = XP_FALSE; - addr->u.ip_relay.advertiseRoom = XP_FALSE; -#elif defined PLATFORM_PALM - /* default values; default is still IR where there's a choice, at least on - Palm... */ - addr->conType = COMMS_CONN_IR; -#endif - addr_setType( addr, COMMS_CONN_MQTT ); -} /* comms_getInitialAddr */ - -XP_Bool -comms_checkAddr( XWEnv xwe, DeviceRole role, const CommsAddrRec* addr, - XW_UtilCtxt* util ) -{ - XP_Bool ok = XP_TRUE; - /* make sure the user's given us enough information to make a connection */ - if ( role == SERVER_ISCLIENT ) { - if ( addr_hasType( addr, COMMS_CONN_BT ) ) { - XP_U32 empty = 0L; /* check four bytes to save some code */ - if ( !XP_MEMCMP( &empty, &addr->u.bt.btAddr, sizeof(empty) ) ) { - ok = XP_FALSE; - if ( !!util ) { - util_userError( util, xwe, STR_NEED_BT_HOST_ADDR ); - } - } - } - } - return ok; -} /* comms_checkAddr */ - CommsConnTypes comms_getConTypes( const CommsCtxt* comms ) { @@ -1326,6 +1306,7 @@ void comms_dropHostAddr( CommsCtxt* comms, CommsConnType typ ) { addr_rmType( &comms->addr, typ ); + ASSERT_ADDR_OK( &comms->addr ); } XP_Bool @@ -1540,6 +1521,25 @@ assertQueueOk( const CommsCtxt* comms ) XP_LOGFF( "queueLen unexpectedly high: %d", count ); } } + +static void +assertAddrOk( const CommsAddrRec* addr ) +{ + CommsConnType typ; + for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) { + switch ( typ ) { + case COMMS_CONN_MQTT: + XP_ASSERT( 0 != addr->u.mqtt.devID ); + break; + case COMMS_CONN_SMS: + XP_ASSERT( 0 != addr->u.sms.phone[0] ); + break; + default: + XP_ASSERT(0); + break; + } + } +} #endif static XP_Bool @@ -1654,105 +1654,112 @@ sendMsg( CommsCtxt* comms, XWEnv xwe, MsgQueueElem* elem, const CommsConnType fi cbuf, elem->msgID, elem->len, elem->checksum ); #endif - CommsAddrRec addr; const CommsAddrRec* addrP; - (void)channelToAddress( comms, xwe, channelNo, &addrP ); - if ( NULL == addrP ) { - XP_LOGFF( TAGFMT() "no addr for channel so using comms'", TAGPRMS ); - comms_getAddr( comms, &addr ); - logAddr( comms, xwe, &addr, "default case" ); + if ( comms->isServer ) { + (void)channelToAddress( comms, xwe, channelNo, &addrP ); } else { - addr = *addrP; + /* guest has only one peer, but old code might save several */ + XP_ASSERT( !!comms->recs && !comms->recs->next ); + if ( !!comms->recs ) { + addrP = &comms->recs->addr; + } + } + if ( NULL == addrP ) { + XP_LOGFF( TAGFMT() "no addr for channel %x; dropping!'", TAGPRMS, channelNo ); + XP_ASSERT(0); + } else { + CommsAddrRec addr = *addrP; if ( addr_hasType( &comms->addr, COMMS_CONN_NFC ) ) { addr_addType( &addr, COMMS_CONN_NFC ); } - } - CommsConnType typ; - for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) { - XP_S16 nSent = -1; - if ( comms_getAddrDisabled( comms, typ, XP_TRUE ) ) { - XP_LOGFF( "dropping message because %s disabled", - ConnType2Str( typ ) ); - } else if ( COMMS_CONN_NONE != filter && filter != typ ) { - XP_LOGFF( "dropping message because not of type %s", - ConnType2Str( filter ) ); - } else { + CommsConnType typ; + for ( XP_U32 st = 0; addr_iter( &addr, &typ, &st ); ) { + XP_S16 nSent = -1; + if ( comms_getAddrDisabled( comms, typ, XP_TRUE ) ) { + XP_LOGFF( "dropping message because %s disabled", + ConnType2Str( typ ) ); + } else if ( COMMS_CONN_NONE != filter && filter != typ ) { + XP_LOGFF( "dropping message because not of type %s", + ConnType2Str( filter ) ); + } else { #ifdef COMMS_CHECKSUM - XP_LOGFF( TAGFMT() "sending msg with sum %s using typ %s", TAGPRMS, - elem->checksum, ConnType2Str(typ) ); + XP_LOGFF( TAGFMT() "sending msg with sum %s using typ %s", TAGPRMS, + elem->checksum, ConnType2Str(typ) ); #endif - switch ( typ ) { + switch ( typ ) { #ifdef XWFEATURE_RELAY - case COMMS_CONN_RELAY: { - XWHostID destID = getDestID( comms, xwe, channelNo ); - if ( HOST_ID_NONE == destID ) { - XP_LOGFF( TAGFMT() "skipping message via relay: no destID yet", TAGPRMS ); - } else if ( haveRelayID( comms ) && sendNoConn( comms, xwe, elem, destID ) ) { - /* do nothing */ - nSent = elem->len; - } else if ( comms->rr.relayState >= COMMS_RELAYSTATE_CONNECTED ) { - XP_UCHAR msgNo[16]; - formatMsgNo( comms, elem, msgNo, sizeof(msgNo) ); - if ( send_via_relay( comms, xwe, XWRELAY_MSG_TORELAY, destID, - elem->msg, elem->len, msgNo ) ) { + case COMMS_CONN_RELAY: { + XWHostID destID = getDestID( comms, xwe, channelNo ); + if ( HOST_ID_NONE == destID ) { + XP_LOGFF( TAGFMT() "skipping message via relay: no destID yet", TAGPRMS ); + } else if ( haveRelayID( comms ) && sendNoConn( comms, xwe, elem, destID ) ) { + /* do nothing */ nSent = elem->len; + } else if ( comms->rr.relayState >= COMMS_RELAYSTATE_CONNECTED ) { + XP_UCHAR msgNo[16]; + formatMsgNo( comms, elem, msgNo, sizeof(msgNo) ); + if ( send_via_relay( comms, xwe, XWRELAY_MSG_TORELAY, destID, + elem->msg, elem->len, msgNo ) ) { + nSent = elem->len; + } + } else { + XP_LOGFF( "skipping message: not connected to relay" ); } - } else { - XP_LOGFF( "skipping message: not connected to relay" ); - } - break; - } -#endif -#if defined XWFEATURE_IP_DIRECT - case COMMS_CONN_BT: - case COMMS_CONN_IP_DIRECT: - nSent = send_via_ip( comms, BTIPMSG_DATA, channelNo, - elem->msg, elem->len ); -#ifdef COMMS_HEARTBEAT - setHeartbeatTimer( comms ); -#endif - break; -#endif - default: { - XP_ASSERT( addr_hasType( &addr, typ ) ); - - /* A more general check that the address type has the settings - it needs would be better here.... */ - if ( typ == COMMS_CONN_MQTT && 0 == addr.u.mqtt.devID ) { - XP_LOGFF( "not sending: MQTT address NULL" ); break; } - - XP_ASSERT( !!comms->procs.send ); - XP_U32 gameid = gameID( comms ); - logAddr( comms, xwe, &addr, __func__ ); - XP_UCHAR msgNo[16]; - formatMsgNo( comms, elem, msgNo, sizeof(msgNo) ); - nSent = (*comms->procs.send)( xwe, elem->msg, elem->len, msgNo, - elem->createdStamp, &addr, - typ, gameid, comms->procs.closure ); - break; - } - } /* switch */ - } - XP_LOGFF( TAGFMT() "sent %d bytes using typ %s", TAGPRMS, nSent, - ConnType2Str(typ) ); - if ( nSent > result ) { - result = nSent; - } - } - - if ( result == elem->len ) { -#ifdef DEBUG - ++elem->sendCount; #endif - XP_LOGFF( "elem's sendCount since load: %d", - elem->sendCount ); +#if defined XWFEATURE_IP_DIRECT + case COMMS_CONN_BT: + case COMMS_CONN_IP_DIRECT: + nSent = send_via_ip( comms, BTIPMSG_DATA, channelNo, + elem->msg, elem->len ); +#ifdef COMMS_HEARTBEAT + setHeartbeatTimer( comms ); +#endif + break; +#endif + default: { + XP_ASSERT( addr_hasType( &addr, typ ) ); + + /* A more general check that the address type has the settings + it needs would be better here.... */ + if ( typ == COMMS_CONN_MQTT && 0 == addr.u.mqtt.devID ) { + XP_LOGFF( "not sending: MQTT address NULL" ); + XP_ASSERT(0); + break; + } + + XP_ASSERT( !!comms->procs.send ); + XP_U32 gameid = gameID( comms ); + logAddr( comms, xwe, &addr, __func__ ); + XP_UCHAR msgNo[16]; + formatMsgNo( comms, elem, msgNo, sizeof(msgNo) ); + nSent = (*comms->procs.send)( xwe, elem->msg, elem->len, msgNo, + elem->createdStamp, &addr, + typ, gameid, comms->procs.closure ); + break; + } + } /* switch */ + } + XP_LOGFF( TAGFMT() "sent %d bytes using typ %s", TAGPRMS, nSent, + ConnType2Str(typ) ); + if ( nSent > result ) { + result = nSent; + } + } + + if ( result == elem->len ) { +#ifdef DEBUG + ++elem->sendCount; +#endif + XP_LOGFF( "elem's sendCount since load: %d", + elem->sendCount ); + } + CNO_FMT( cbuf1, elem->channelNo ); + XP_LOGFF( "(%s; msgID=" XP_LD ", len=%d)=>%d", cbuf1, elem->msgID, + elem->len, result ); } - CNO_FMT( cbuf1, elem->channelNo ); - XP_LOGFF( "(%s; msgID=" XP_LD ", len=%d)=>%d", cbuf1, elem->msgID, - elem->len, result ); XP_ASSERT( result < 0 || elem->len == result ); return result; } /* sendMsg */ @@ -2318,8 +2325,7 @@ getRecordFor( CommsCtxt* comms, XWEnv xwe, const CommsAddrRec* addr, } } - XP_LOGFF( "(%s, maskChannel=%s) => %p", cbuf, - maskChannel? "true":"false", rec ); + XP_LOGFF( "(%s, maskChannel=%s) => %p", cbuf, boolToStr(maskChannel), rec ); return rec; } /* getRecordFor */ @@ -2402,7 +2408,8 @@ validateInitialMessage( CommsCtxt* comms, XWEnv xwe, XP_LOGFF( TAGFMT() "ORd channel onto channelNo: now %s", TAGPRMS, cbuf1 ); XP_ASSERT( comms->nextChannelNo <= CHANNEL_MASK ); } - rec = rememberChannelAddress( comms, xwe, *channelNo, senderID, addr, flags ); + rec = rememberChannelAddress( comms, xwe, *channelNo, senderID, addr, + flags ); if ( hasPayload ) { rec->initialSeen = XP_TRUE; } else { @@ -2416,9 +2423,18 @@ validateInitialMessage( CommsCtxt* comms, XWEnv xwe, rec = getRecordFor( comms, xwe, addr, *channelNo, XP_TRUE ); if ( !!rec ) { augmentChannelAddr( comms, rec, addr, senderID ); + + /* Used to be that the initial message was where the channel + record got created, but now the client creates an address for + the host on startup (comms_make()) */ + if ( comms->isServer ) { + XP_LOGFF( TAGFMT() "rejecting duplicate INIT message", TAGPRMS ); + rec = NULL; + } else { + XP_LOGFF( "accepting duplicate (?) msg" ); + } /* reject: we've already seen init message on channel */ - XP_LOGFF( TAGFMT() "rejecting duplicate INIT message", TAGPRMS ); - rec = NULL; + // XP_ASSERT(0); } else { if ( comms->isServer ) { if ( checkChannelNo( comms, channelNo ) ) { @@ -3172,7 +3188,6 @@ augmentChannelAddr( CommsCtxt* comms, AddressRecord* const rec, for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) { if ( !addr_hasType( &comms->addr, typ ) ) { XP_LOGFF( "main addr missing type %s", ConnType2Str(typ) ); - XP_ASSERT(0); /* firing */ } } #endif @@ -3182,6 +3197,7 @@ static XP_Bool augmentAddrIntrnl( CommsCtxt* comms, CommsAddrRec* destAddr, const CommsAddrRec* srcAddr, XP_Bool isNewer ) { + ASSERT_ADDR_OK( srcAddr ); XP_Bool changed = XP_FALSE; const CommsAddrRec empty = {0}; if ( !!srcAddr ) { @@ -3194,12 +3210,14 @@ augmentAddrIntrnl( CommsCtxt* comms, CommsAddrRec* destAddr, /* If an address is getting added to a channel, the top-level address should also include the type. The specifics of the - address don't make sense to copy, however. */ + address don't make sense to copy, however. + NO -- not any more. I have the addresses my user gives me + */ if ( !!comms && ! addr_hasType( &comms->addr, typ ) ) { /* we just added it, so can't be comms->addr */ XP_ASSERT( destAddr != &comms->addr ); - XP_LOGFF( "adding %s to comms->addr", ConnType2Str(typ) ); - addr_addType( &comms->addr, typ ); + XP_LOGFF( "NOT adding %s to comms->addr", ConnType2Str(typ) ); + // addr_addType( &comms->addr, typ ); } } @@ -3236,6 +3254,7 @@ augmentAddrIntrnl( CommsCtxt* comms, CommsAddrRec* destAddr, case COMMS_CONN_NFC: break; case COMMS_CONN_MQTT: + XP_ASSERT( 0 != srcAddr->u.mqtt.devID ); dest = &destAddr->u.mqtt; src = &srcAddr->u.mqtt; siz = sizeof(destAddr->u.mqtt); @@ -3360,6 +3379,13 @@ types_addType( XP_U16* conTypes, CommsConnType type ) *conTypes |= 1 << (type - 1); } +void +types_rmType( XP_U16* conTypes, CommsConnType type ) +{ + XP_ASSERT( COMMS_CONN_NONE != type ); + *conTypes &= ~(1 << (type - 1)); +} + void addr_addType( CommsAddrRec* addr, CommsConnType type ) { @@ -3371,7 +3397,7 @@ addr_rmType( CommsAddrRec* addr, CommsConnType type ) { XP_ASSERT( COMMS_CONN_NONE != type ); // XP_LOGF( "%s(%s)", __func__, ConnType2Str(type) ); - addr->_conTypes &= ~(1 << (type - 1)); + types_rmType( &addr->_conTypes, type ); } /* Overwrites anything that might already be there. Use addr_addType() to add diff --git a/xwords4/common/comms.h b/xwords4/common/comms.h index 38f798882..21a8a7caa 100644 --- a/xwords4/common/comms.h +++ b/xwords4/common/comms.h @@ -1,6 +1,6 @@ /* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */ /* - * Copyright 2001 - 2014 by Eric House (xwords@eehouse.org). All rights + * Copyright 2001 - 2022 by Eric House (xwords@eehouse.org). All rights * reserved. * * This program is free software; you can redistribute it and/or @@ -138,6 +138,8 @@ typedef struct _TransportProcs { CommsCtxt* comms_make( MPFORMAL XWEnv xwe, XW_UtilCtxt* util, XP_Bool isServer, + const CommsAddrRec* selfAddr, + const CommsAddrRec* hostAddr, #ifdef XWFEATURE_RELAY XP_U16 nPlayersHere, XP_U16 nPlayersTotal, #endif @@ -165,16 +167,6 @@ void comms_destroy( CommsCtxt* comms, XWEnv xwe ); void comms_setConnID( CommsCtxt* comms, XP_U32 connID ); -/* "static" methods work when no comms present */ -void comms_getInitialAddr( CommsAddrRec* addr -#ifdef XWFEATURE_RELAY - , const XP_UCHAR* relayName - , XP_U16 relayPort -#endif - ); -XP_Bool comms_checkAddr( XWEnv xwe, DeviceRole role, const CommsAddrRec* addr, - XW_UtilCtxt* util ); - void comms_getAddr( const CommsCtxt* comms, CommsAddrRec* addr ); void comms_augmentHostAddr( CommsCtxt* comms, XWEnv xwe, const CommsAddrRec* addr ); void comms_addMQTTDevID( CommsCtxt* comms, XP_PlayerAddr channelNo, @@ -261,12 +253,13 @@ XP_Bool augmentAddr( CommsAddrRec* addr, const CommsAddrRec* newer, CommsConnType addr_getType( const CommsAddrRec* addr ); void addr_setType( CommsAddrRec* addr, CommsConnType type ); void addr_addType( CommsAddrRec* addr, CommsConnType type ); -void types_addType( XP_U16* conTypes, CommsConnType type ); void addr_rmType( CommsAddrRec* addr, CommsConnType type ); XP_Bool addr_hasType( const CommsAddrRec* addr, CommsConnType type ); -XP_Bool types_hasType( XP_U16 conTypes, CommsConnType type ); XP_Bool addr_iter( const CommsAddrRec* addr, CommsConnType* typp, XP_U32* state ); +void types_addType( XP_U16* conTypes, CommsConnType type ); +void types_rmType( XP_U16* conTypes, CommsConnType type ); +XP_Bool types_hasType( XP_U16 conTypes, CommsConnType type ); XP_Bool types_iter( XP_U32 conTypes, CommsConnType* typp, XP_U32* state ); #ifdef XWFEATURE_KNOWNPLAYERS diff --git a/xwords4/common/game.c b/xwords4/common/game.c index 128c40d63..fa7e234e7 100644 --- a/xwords4/common/game.c +++ b/xwords4/common/game.c @@ -155,8 +155,10 @@ unrefDicts( XWEnv xwe, const DictionaryCtxt* dict, PlayerDicts* playerDicts ) XP_Bool game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi, - XW_UtilCtxt* util, DrawCtx* draw, - const CommonPrefs* cp, const TransportProcs* procs + const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr, + XW_UtilCtxt* util, + DrawCtx* draw, const CommonPrefs* cp, + const TransportProcs* procs #ifdef SET_GAMESEED ,XP_U16 gameSeed #endif @@ -192,6 +194,7 @@ game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi, if ( gi->serverRole != SERVER_STANDALONE ) { game->comms = comms_make( MPPARM(mpool) xwe, util, gi->serverRole != SERVER_ISCLIENT, + selfAddr, hostAddr, #ifdef XWFEATURE_RELAY nPlayersHere, nPlayersTotal, #endif @@ -228,7 +231,9 @@ game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi, } /* game_makeNewGame */ XP_Bool -game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi, XW_UtilCtxt* util, +game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi, + const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr, + XW_UtilCtxt* util, CommonPrefs* cp, const TransportProcs* procs ) { XP_ASSERT( util == game->util ); @@ -262,6 +267,7 @@ game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi, XW_UtilCtxt* util } else if ( gi->serverRole != SERVER_STANDALONE ) { game->comms = comms_make( MPPARM(mpool) xwe, util, gi->serverRole != SERVER_ISCLIENT, + selfAddr, hostAddr, #ifdef XWFEATURE_RELAY nPlayersHere, nPlayersTotal, #endif @@ -409,8 +415,8 @@ game_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream, XP_Bool game_makeFromInvite( MPFORMAL XWEnv xwe, const NetLaunchInfo* nli, - XWGame* game, CurGameInfo* gi, const XP_UCHAR* plyrName, - XW_UtilCtxt* util, DrawCtx* draw, + XWGame* game, CurGameInfo* gi, const CommsAddrRec* selfAddr, + const XP_UCHAR* plyrName, XW_UtilCtxt* util, DrawCtx* draw, CommonPrefs* cp, const TransportProcs* procs ) { gi_setNPlayers( gi, nli->nPlayersT, nli->nPlayersH ); @@ -425,7 +431,10 @@ game_makeFromInvite( MPFORMAL XWEnv xwe, const NetLaunchInfo* nli, replaceStringIfDifferent( mpool, &gi->players[0].name, plyrName ); replaceStringIfDifferent( mpool, &gi->dictName, nli->dict ); - XP_Bool success = game_makeNewGame( MPPARM(mpool) xwe, game, gi, util, draw, cp, procs ); + CommsAddrRec hostAddr; + nli_makeAddrRec( nli, &hostAddr ); + XP_Bool success = game_makeNewGame( MPPARM(mpool) xwe, game, gi, selfAddr, + &hostAddr, util, draw, cp, procs ); if ( success ) { CommsAddrRec returnAddr; nli_makeAddrRec( nli, &returnAddr ); @@ -434,28 +443,6 @@ game_makeFromInvite( MPFORMAL XWEnv xwe, const NetLaunchInfo* nli, return success; } -void -game_saveNewGame( MPFORMAL XWEnv xwe, const CurGameInfo* gi, XW_UtilCtxt* util, - const CommonPrefs* cp, XWStreamCtxt* out ) -{ - XWGame newGame = {0}; - CurGameInfo newGI = {0}; - gi_copy( MPPARM(mpool) &newGI, gi ); - - game_makeNewGame( MPPARM(mpool) xwe, &newGame, &newGI, util, - NULL, /* DrawCtx*, */ - cp, NULL /* TransportProcs* procs */ -#ifdef SET_GAMESEED - ,0 -#endif - ); - - game_saveToStream( &newGame, xwe, &newGI, out, 1 ); - game_saveSucceeded( &newGame, xwe, 1 ); - game_dispose( &newGame, xwe ); - gi_disposePlayerInfo( MPPARM(mpool) &newGI ); -} - void game_saveToStream( const XWGame* game, XWEnv xwe, const CurGameInfo* gi, XWStreamCtxt* stream, XP_U16 saveToken ) diff --git a/xwords4/common/game.h b/xwords4/common/game.h index d80630202..213290da0 100644 --- a/xwords4/common/game.h +++ b/xwords4/common/game.h @@ -76,13 +76,15 @@ typedef struct _XWGame { } XWGame; XP_Bool game_makeNewGame( MPFORMAL XWEnv xwe, XWGame* game, CurGameInfo* gi, - XW_UtilCtxt* util, DrawCtx* draw, - const CommonPrefs* cp, const TransportProcs* procs + const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr, + XW_UtilCtxt* util, DrawCtx* draw, const CommonPrefs* cp, + const TransportProcs* procs #ifdef SET_GAMESEED ,XP_U16 gameSeed #endif ); XP_Bool game_reset( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi, + const CommsAddrRec* selfAddr, const CommsAddrRec* hostAddr, XW_UtilCtxt* util, CommonPrefs* cp, const TransportProcs* procs ); void game_changeDict( MPFORMAL XWGame* game, XWEnv xwe, CurGameInfo* gi, @@ -94,8 +96,8 @@ XP_Bool game_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream, CommonPrefs* cp, const TransportProcs* procs ); XP_Bool game_makeFromInvite( MPFORMAL XWEnv xwe, const NetLaunchInfo* nli, - XWGame* game, CurGameInfo* gi, const XP_UCHAR* plyrName, - XW_UtilCtxt* util, DrawCtx* draw, + XWGame* game, CurGameInfo* gi, const CommsAddrRec* selfAddr, + const XP_UCHAR* plyrName, XW_UtilCtxt* util, DrawCtx* draw, CommonPrefs* cp, const TransportProcs* procs ); void game_saveNewGame( MPFORMAL XWEnv xwe, const CurGameInfo* gi, XW_UtilCtxt* util, diff --git a/xwords4/common/knownplyr.c b/xwords4/common/knownplyr.c index 89dc92ac1..d44623b72 100644 --- a/xwords4/common/knownplyr.c +++ b/xwords4/common/knownplyr.c @@ -47,7 +47,6 @@ static void getPlayersImpl( const KPState* state, const XP_UCHAR** players, static void loadFromStream( XW_DUtilCtxt* dutil, KPState* state, XWStreamCtxt* stream ) { - LOG_FUNC(); while ( 0 < stream_getSize( stream ) ) { XP_U32 newestMod = stream_getU32( stream ); XP_UCHAR buf[64]; diff --git a/xwords4/common/nli.c b/xwords4/common/nli.c index 7b09afeb2..f674bfb1c 100644 --- a/xwords4/common/nli.c +++ b/xwords4/common/nli.c @@ -50,6 +50,7 @@ nli_init( NetLaunchInfo* nli, const CurGameInfo* gi, const CommsAddrRec* addr, break; case COMMS_CONN_SMS: XP_STRCAT( nli->phone, addr->u.sms.phone ); + XP_ASSERT( 1 == addr->u.sms.port ); // nli->port = addr->u.sms.port; <-- I wish break; case COMMS_CONN_MQTT: @@ -278,11 +279,23 @@ logNLI( const NetLaunchInfo* nli, const char* callerFunc, const int callerLine ) offset += XP_SNPRINTF( &conTypes[offset], sizeof(conTypes)-offset, "%s,", asstr ); } - XP_UCHAR buf[256+128]; + XP_UCHAR buf[1024]; XP_SNPRINTF( buf, VSIZE(buf), "{ctyps: [%s], nPlayersT: %d, nPlayersH: %d, " - "isoCode: '%s', gameID: %d, inviteID: %s, mqttid: %s}", conTypes, - nli->nPlayersT, nli->nPlayersH, nli->isoCodeStr, nli->gameID, - nli->inviteID, nli->mqttDevID ); + "isoCode: '%s', gameID: %d", + conTypes, nli->nPlayersT, nli->nPlayersH, nli->isoCodeStr, + nli->gameID ); + if ( types_hasType( nli->_conTypes, COMMS_CONN_MQTT ) ) { + XP_UCHAR smallBuf[128]; + XP_SNPRINTF( smallBuf, VSIZE(smallBuf), ", mqttid: %s", nli->mqttDevID ); + XP_STRCAT( buf, smallBuf ); + } + if ( types_hasType( nli->_conTypes, COMMS_CONN_SMS ) ) { + XP_UCHAR smallBuf[128]; + XP_SNPRINTF( smallBuf, VSIZE(smallBuf), ", phone: %s", + nli->phone ); + XP_STRCAT( buf, smallBuf ); + } + XP_STRCAT( buf, "}" ); XP_LOGF( "%s", buf ); } # endif diff --git a/xwords4/common/server.c b/xwords4/common/server.c index c20e0dd08..1ae6e7e04 100644 --- a/xwords4/common/server.c +++ b/xwords4/common/server.c @@ -287,7 +287,7 @@ static XP_Bool inDuplicateMode( const ServerCtxt* server ) { XP_Bool result = server->vol.gi->inDuplicateMode; - // LOG_RETURNF( "%d", result ); + // LOG_RETURNF( "%s", boolToStr(result) ); return result; } @@ -423,7 +423,7 @@ getNV( XWStreamCtxt* stream, ServerNonvolatiles* nv, XP_U16 nPlayers ) if ( version >= STREAM_VERS_DUPLICATE ) { for ( ii = 0; ii < nPlayers; ++ii ) { nv->dupTurnsMade[ii] = stream_getBits( stream, 1 ); - XP_LOGFF( "dupTurnsMade[%d]: %d", ii, nv->dupTurnsMade[ii] ); + // XP_LOGFF( "dupTurnsMade[%d]: %d", ii, nv->dupTurnsMade[ii] ); nv->dupTurnsForced[ii] = stream_getBits( stream, 1 ); } nv->dupTurnsSent = stream_getBits( stream, 1 ); @@ -2413,14 +2413,14 @@ server_askPickTiles( ServerCtxt* server, XWEnv xwe, XP_U16 turn, return asked; } -/* dupe_trayAllowsMoves() +/* trayAllowsMoves() * * Assuming a model with a turn loaded (but maybe not committed), build the * tile set containing the current model tray tiles PLUS the new set we're * considering, and see if the engine can find moves. */ static XP_Bool -dupe_trayAllowsMoves( ServerCtxt* server, XWEnv xwe, XP_U16 turn, +trayAllowsMoves( ServerCtxt* server, XWEnv xwe, XP_U16 turn, const Tile* tiles, XP_U16 nTiles ) { ModelCtxt* model = server->vol.model; @@ -2552,8 +2552,8 @@ fetchTiles( ServerCtxt* server, XWEnv xwe, XP_U16 playerNum, XP_U16 nToFetch, if ( !inDuplicateMode( server ) && !forceCanPlay ) { break; - } else if ( dupe_trayAllowsMoves( server, xwe, playerNum, &resultTiles->tiles[0], - nSoFar + nLeft ) + } else if ( trayAllowsMoves( server, xwe, playerNum, &resultTiles->tiles[0], + nSoFar + nLeft ) || ++nBadTrays >= 5 ) { break; } diff --git a/xwords4/linux/cursesboard.c b/xwords4/linux/cursesboard.c index 803930f46..45595fcf7 100644 --- a/xwords4/linux/cursesboard.c +++ b/xwords4/linux/cursesboard.c @@ -357,51 +357,6 @@ curses_socket_acceptor( int listener, Acceptor func, CommonGlobals* cGlobals, } } -static void -copyParmsAddr( CommonGlobals* cGlobals ) -{ - LaunchParams* params = cGlobals->params; - CommsAddrRec* addr = &cGlobals->addr; - - CommsConnType typ; - for ( XP_U32 st = 0; addr_iter( ¶ms->addr, &typ, &st ); ) { - addr_addType( addr, typ ); - switch( typ ) { -#ifdef XWFEATURE_RELAY - case COMMS_CONN_RELAY: - addr->u.ip_relay.ipAddr = 0; /* ??? */ - addr->u.ip_relay.port = params->connInfo.relay.defaultSendPort; - addr->u.ip_relay.seeksPublicRoom = - params->connInfo.relay.seeksPublicRoom; - addr->u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom; - XP_STRNCPY( addr->u.ip_relay.hostName, - params->connInfo.relay.relayName, - sizeof(addr->u.ip_relay.hostName) - 1 ); - XP_STRNCPY( addr->u.ip_relay.invite, params->connInfo.relay.invite, - sizeof(addr->u.ip_relay.invite) - 1 ); - break; -#endif -#ifdef XWFEATURE_SMS - case COMMS_CONN_SMS: - XP_STRNCPY( addr->u.sms.phone, params->connInfo.sms.myPhone, - sizeof(addr->u.sms.phone) - 1 ); - addr->u.sms.port = params->connInfo.sms.port; - break; -#endif -#ifdef XWFEATURE_BLUETOOTH - case COMMS_CONN_BT: - XP_ASSERT( sizeof(addr->u.bt.btAddr) - >= sizeof(params->connInfo.bt.hostAddr)); - XP_MEMCPY( &addr->u.bt.btAddr, ¶ms->connInfo.bt.hostAddr, - sizeof(params->connInfo.bt.hostAddr) ); - break; -#endif - default: - break; - } - } -} - static CursesBoardGlobals* commonInit( CursesBoardState* cbState, sqlite3_int64 rowid, const CurGameInfo* gip ) @@ -442,7 +397,7 @@ commonInit( CursesBoardState* cbState, sqlite3_int64 rowid, bGlobals->procs.requestJoin = relay_requestJoin_curses; #endif - copyParmsAddr( cGlobals ); + makeSelfAddress( &cGlobals->selfAddr, params ); setOneSecondTimer( cGlobals ); return bGlobals; @@ -575,6 +530,10 @@ initNoDraw( CursesBoardState* cbState, sqlite3_int64 rowid, CommonGlobals* cGlobals = &result->cGlobals; LaunchParams* params = cGlobals->params; + if ( !!returnAddr ) { + cGlobals->hostAddr = *returnAddr; + } + cGlobals->cp.showBoardArrow = XP_TRUE; cGlobals->cp.showRobotScores = params->showRobotScores; cGlobals->cp.hideTileValues = params->hideValues; @@ -592,7 +551,7 @@ initNoDraw( CursesBoardState* cbState, sqlite3_int64 rowid, cGlobals->cp.makePhonyPct = params->makePhonyPct; #endif - if ( linuxOpenGame( cGlobals, &result->procs, returnAddr ) ) { + if ( linuxOpenGame( cGlobals, &result->procs ) ) { result = ref( result ); } else { disposeBoard( result ); diff --git a/xwords4/linux/gtkboard.c b/xwords4/linux/gtkboard.c index f687e575e..c29016946 100644 --- a/xwords4/linux/gtkboard.c +++ b/xwords4/linux/gtkboard.c @@ -618,8 +618,7 @@ createOrLoadObjects( GtkGameGlobals* globals ) TransportProcs procs; setTransportProcs( &procs, globals ); - if ( linuxOpenGame( cGlobals, &procs, &cGlobals->addr ) ) { - + if ( linuxOpenGame( cGlobals, &procs ) ) { if ( !params->fileName && !!params->dbName ) { XP_UCHAR buf[64]; snprintf( buf, sizeof(buf), "%s / %lld", params->dbName, @@ -861,23 +860,14 @@ new_game_impl( GtkGameGlobals* globals, XP_Bool fireConnDlg ) { XP_Bool success = XP_FALSE; CommonGlobals* cGlobals = &globals->cGlobals; - CommsAddrRec addr; - - if ( !!cGlobals->game.comms ) { - comms_getAddr( cGlobals->game.comms, &addr ); - } else { - comms_getInitialAddr( &addr -#ifdef XWFEATURE_RELAY - , RELAY_NAME_DEFAULT, RELAY_PORT_DEFAULT -#endif - ); - } CurGameInfo* gi = cGlobals->gi; + CommsAddrRec addr; success = gtkNewGameDialog( globals, gi, &addr, XP_TRUE, fireConnDlg ); if ( success ) { #ifndef XWFEATURE_STANDALONE_ONLY XP_Bool isClient = gi->serverRole == SERVER_ISCLIENT; + XP_ASSERT( !isClient ); /* Doesn't make sense! Send invitation. */ #endif TransportProcs procs = { .closure = globals, @@ -887,20 +877,10 @@ new_game_impl( GtkGameGlobals* globals, XP_Bool fireConnDlg ) #endif }; - (void)game_reset( MEMPOOL &cGlobals->game, NULL_XWE, gi, cGlobals->util, + (void)game_reset( MEMPOOL &cGlobals->game, NULL_XWE, gi, + &cGlobals->selfAddr, NULL, cGlobals->util, &cGlobals->cp, &procs ); -#ifndef XWFEATURE_STANDALONE_ONLY - if ( !!cGlobals->game.comms ) { - comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &addr ); - } else if ( gi->serverRole != SERVER_STANDALONE ) { - XP_ASSERT(0); - } - - if ( isClient ) { - tryConnectToServer( cGlobals ); - } -#endif (void)server_do( cGlobals->game.server, NULL_XWE ); /* assign tiles, etc. */ board_invalAll( cGlobals->game.board ); board_draw( cGlobals->game.board, NULL_XWE ); @@ -2507,6 +2487,8 @@ initGlobalsNoDraw( GtkGameGlobals* globals, LaunchParams* params, setupUtil( cGlobals ); setupGtkUtilCallbacks( globals, cGlobals->util ); + + makeSelfAddress( &cGlobals->selfAddr, params ); } /* This gets called all the time, e.g. when the mouse moves across @@ -2736,27 +2718,8 @@ XP_Bool makeNewGame( GtkGameGlobals* globals ) { CommonGlobals* cGlobals = &globals->cGlobals; - if ( !!cGlobals->game.comms ) { - comms_getAddr( cGlobals->game.comms, &cGlobals->addr ); - } else { -#ifdef XWFEATURE_RELAY - LaunchParams* params = cGlobals->params; - const XP_UCHAR* relayName = params->connInfo.relay.relayName; - if ( !relayName ) { - relayName = RELAY_NAME_DEFAULT; - } - XP_U16 relayPort = params->connInfo.relay.defaultSendPort; - if ( 0 == relayPort ) { - relayPort = RELAY_PORT_DEFAULT; - } - comms_getInitialAddr( &cGlobals->addr , relayName, relayPort ); -#else - comms_getInitialAddr( &cGlobals->addr ); -#endif - } - - CurGameInfo* gi = cGlobals->gi; - XP_Bool success = gtkNewGameDialog( globals, gi, &cGlobals->addr, + XP_Bool success = gtkNewGameDialog( globals, cGlobals->gi, + &cGlobals->selfAddr, XP_TRUE, XP_FALSE ); LOG_RETURNF( "%s", boolToStr(success) ); return success; diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index 31a846eb6..c58d7a884 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -351,63 +351,10 @@ handle_open_button( GtkWidget* XP_UNUSED(widget), void* closure ) } void -make_rematch( GtkAppGlobals* apg, const CommonGlobals* cGlobals ) +make_rematch( GtkAppGlobals* XP_UNUSED(apg), + const CommonGlobals* XP_UNUSED(cGlobals) ) { - LaunchParams* params = apg->cag.params; - XP_ASSERT( params == cGlobals->params ); - XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool) - params->vtMgr ); - - /* Create new game. But has no addressing info, so need to set that - aside for later. */ - const CommsCtxt* comms = cGlobals->game.comms; - CurGameInfo gi = {0}; - gi_copy( MPPARM(cGlobals->util->mpool) &gi, cGlobals->gi ); - gi.gameID = 0; /* clear so will get generated */ - if ( !!comms ) { - gi.serverRole = SERVER_ISSERVER; - gi.forceChannel = 0; - } - game_saveNewGame( MPPARM(cGlobals->util->mpool) NULL_XWE, &gi, - cGlobals->util, &cGlobals->cp, stream ); - - sqlite3_int64 rowID = gdb_writeNewGame( stream, params->pDb ); - stream_destroy( stream, NULL_XWE ); - gi_disposePlayerInfo( MPPARM(cGlobals->util->mpool) &gi ); - - /* If it's a multi-device game, save enough information with it than when - opened it can invite the other device[s] join the rematch. */ - if ( !!comms ) { - XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool) - params->vtMgr ); - CommsAddrRec addr; - comms_getAddr( comms, &addr ); - addrToStream( stream, &addr ); - - CommsAddrRec addrs[4]; - XP_U16 nRecs = VSIZE(addrs); - comms_getAddrs( comms, NULL_XWE, addrs, &nRecs ); - - stream_putU8( stream, nRecs ); - for ( int ii = 0; ii < nRecs; ++ii ) { - XP_LOGFF( "MQTT rematch not implemented" ); - XP_ASSERT(0); /* REWRITE TO USE MQTT */ - /* XP_UCHAR relayID[32]; */ - /* XP_U16 len = sizeof(relayID); */ - /* comms_formatRelayID( comms, ii, relayID, &len ); */ - /* XP_LOGF( "%s: adding relayID: %s", __func__, relayID ); */ - /* stringToStream( stream, relayID ); */ - /* if ( addr_hasType( &addrs[ii], COMMS_CONN_RELAY ) ) { */ - /* /\* copy over room name *\/ */ - /* XP_STRCAT( addrs[ii].u.ip_relay.invite, addr.u.ip_relay.invite ); */ - /* } */ - /* addrToStream( stream, &addrs[ii] ); */ - } - gdb_saveInviteAddrs( stream, params->pDb, rowID ); - stream_destroy( stream, NULL_XWE ); - } - - open_row( apg, rowID, XP_TRUE ); + XP_ASSERT(0); } /* make_rematch */ static void @@ -740,7 +687,7 @@ feedBufferGTK( GtkAppGlobals* apg, sqlite3_int64 rowid, /* Stuff common to receiving invitations */ static void gameFromInvite( GtkAppGlobals* apg, const NetLaunchInfo* invite, - const CommsAddrRec* returnAddr ) + const CommsAddrRec* XP_UNUSED(returnAddr) ) { LaunchParams* params = apg->cag.params; CurGameInfo gi = {0}; @@ -757,17 +704,13 @@ gameFromInvite( GtkAppGlobals* apg, const NetLaunchInfo* invite, replaceStringIfDifferent( params->mpool, &gi.dictName, invite->dict ); GtkGameGlobals* globals = malloc( sizeof(*globals) ); + CommonGlobals* cGlobals = &globals->cGlobals; params->needsNewGame = XP_FALSE; initBoardGlobalsGtk( globals, params, &gi ); - - if ( !!returnAddr ) { - globals->cGlobals.addr = *returnAddr; - } else { - nli_makeAddrRec( invite, &globals->cGlobals.addr ); - } + nli_makeAddrRec( invite, &cGlobals->hostAddr ); GtkWidget* gameWindow = globals->window; - globals->cGlobals.rowid = -1; + cGlobals->rowid = -1; recordOpened( apg, globals ); gtk_widget_show( gameWindow ); diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index b92f8329c..c29a0cf45 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -61,6 +61,7 @@ #include "relaycon.h" #include "mqttcon.h" #include "smsproto.h" +#include "device.h" #ifdef PLATFORM_NCURSES # include "cursesmain.h" #endif @@ -147,10 +148,8 @@ ensureLocalPlayerNames( LaunchParams* XP_UNUSED_DBG(params), CurGameInfo* gi ) } bool -linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs, - const CommsAddrRec* returnAddrP ) +linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs ) { - LOG_FUNC(); XWStreamCtxt* stream = NULL; XP_Bool opened = XP_FALSE; @@ -163,6 +162,7 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs, XP_SNPRINTF( buf, sizeof(buf), "%d", params->dbFileID ); mpool_setTag( MEMPOOL buf ); stream = streamFromDB( cGlobals ); + XP_ASSERT(0); #endif } else if ( !!params->pDb && 0 <= cGlobals->rowid ) { stream = mem_stream_make_raw( MPPARM(cGlobals->util->mpool) @@ -184,10 +184,13 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs, if ( !opened /* && canMakeFromGI( cGlobals->gi )*/ ) { opened = XP_TRUE; - + CommsAddrRec* hostAddr = NULL; + if ( cGlobals->gi->serverRole == SERVER_ISCLIENT ) { + hostAddr = &cGlobals->hostAddr; + } game_makeNewGame( MEMPOOL NULL_XWE, &cGlobals->game, cGlobals->gi, - cGlobals->util, cGlobals->draw, - &cGlobals->cp, procs + &cGlobals->selfAddr, hostAddr, cGlobals->util, + cGlobals->draw, &cGlobals->cp, procs #ifdef SET_GAMESEED , params->gameSeed #endif @@ -195,60 +198,6 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs, #ifdef XWFEATURE_RELAY bool savedGame = false; #endif - CommsAddrRec returnAddr = {0}; - if ( !!returnAddrP ) { - returnAddr = *returnAddrP; - CommsConnType typ; - for ( XP_U32 st = 0; addr_iter( &returnAddr, &typ, &st ); ) { - if ( params->commsDisableds[typ][0] ) { - comms_setAddrDisabled( cGlobals->game.comms, typ, XP_FALSE, XP_TRUE ); - } - if ( params->commsDisableds[typ][1] ) { - comms_setAddrDisabled( cGlobals->game.comms, typ, XP_TRUE, XP_TRUE ); - } - switch( typ ) { -#ifdef XWFEATURE_RELAY - case COMMS_CONN_RELAY: - /* addr.u.ip_relay.ipAddr = 0; */ - /* addr.u.ip_relay.port = params->connInfo.relay.defaultSendPort; */ - /* addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom; */ - /* addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom; */ - /* XP_STRNCPY( addr.u.ip_relay.hostName, params->connInfo.relay.relayName, */ - /* sizeof(addr.u.ip_relay.hostName) - 1 ); */ - /* XP_STRNCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite, */ - /* sizeof(addr.u.ip_relay.invite) - 1 ); */ - break; -#endif -#ifdef XWFEATURE_BLUETOOTH - case COMMS_CONN_BT: - XP_ASSERT( sizeof(returnAddr.u.bt.btAddr) - >= sizeof(params->connInfo.bt.hostAddr)); - XP_MEMCPY( &returnAddr.u.bt.btAddr, ¶ms->connInfo.bt.hostAddr, - sizeof(params->connInfo.bt.hostAddr) ); - break; -#endif -#ifdef XWFEATURE_IP_DIRECT - case COMMS_CONN_IP_DIRECT: - XP_STRNCPY( returnAddr.u.ip.hostName_ip, params->connInfo.ip.hostName, - sizeof(addr.u.ip.hostName_ip) - 1 ); - returnAddr.u.ip.port_ip = params->connInfo.ip.port; - break; -#endif -#ifdef XWFEATURE_SMS - case COMMS_CONN_SMS: - XP_LOGF( "%s(): SMS is on at least", __func__ ); - /* No! Don't overwrite what may be a return address with local - stuff */ - /* XP_STRNCPY( addr.u.sms.phone, params->connInfo.sms.phone, */ - /* sizeof(addr.u.sms.phone) - 1 ); */ - /* addr.u.sms.port = params->connInfo.sms.port; */ - break; -#endif - default: - break; - } - } - } /* Need to save in order to have a valid selRow for the first send */ linuxSaveGame( cGlobals ); @@ -256,57 +205,9 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs, savedGame = true; #endif -#ifndef XWFEATURE_STANDALONE_ONLY - /* If this is to be a relay connected game, tell it so. Otherwise - let the invitation process and receipt of messages populate - comms' addressbook */ - if ( cGlobals->gi->serverRole != SERVER_STANDALONE ) { -#ifdef XWFEATURE_RELAY - if ( addr_hasType( ¶ms->addr, COMMS_CONN_RELAY ) ) { - - if ( ! savedGame ) { - linuxSaveGame( cGlobals ); - savedGame = true; - } - CommsAddrRec addr = {0}; - comms_getInitialAddr( &addr, params->connInfo.relay.relayName, - params->connInfo.relay.defaultSendPort ); - XP_MEMCPY( addr.u.ip_relay.invite, params->connInfo.relay.invite, - 1 + XP_STRLEN(params->connInfo.relay.invite) ); - addr.u.ip_relay.seeksPublicRoom = params->connInfo.relay.seeksPublicRoom; - addr.u.ip_relay.advertiseRoom = params->connInfo.relay.advertiseRoom; - comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &addr ); /* sends stuff */ - } -#endif - if ( addr_hasType( ¶ms->addr, COMMS_CONN_SMS ) ) { - CommsAddrRec addr = {0}; - addr_addType( &addr, COMMS_CONN_SMS ); - XP_STRCAT( addr.u.sms.phone, params->connInfo.sms.myPhone ); - addr.u.sms.port = params->connInfo.sms.port; - comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &addr ); - } - - if ( addr_hasType( ¶ms->addr, COMMS_CONN_MQTT ) ) { - CommsAddrRec addr = {0}; - addr_addType( &addr, COMMS_CONN_MQTT ); - addr.u.mqtt.devID = *mqttc_getDevID( params ); - comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &addr ); - } - } - - if ( !!returnAddrP ) { - /* This may trigger network activity */ - CommsCtxt* comms = cGlobals->game.comms; - if ( !!comms ) { - comms_augmentHostAddr( cGlobals->game.comms, NULL_XWE, &returnAddr ); - } - } -#endif - #ifdef XWFEATURE_SEARCHLIMIT cGlobals->gi->allowHintRect = params->allowHintRect; #endif - if ( params->needsNewGame && !opened ) { XP_ASSERT(0); // new_game_impl( globals, XP_FALSE ); @@ -330,6 +231,7 @@ linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs, server_do( cGlobals->game.server, NULL_XWE ); linuxSaveGame( cGlobals ); /* again, to include address etc. */ } + LOG_RETURNF( "%s", boolToStr(opened) ); return opened; } /* linuxOpenGame */ @@ -849,7 +751,7 @@ typedef enum { ,CMD_INVITEE_SMSNUMBER ,CMD_SMSPORT #endif - ,CMD_WITHMQTT + ,CMD_WITHOUT_MQTT ,CMD_MQTTHOST ,CMD_MQTTPORT @@ -1002,7 +904,7 @@ static CmdInfoRec CmdInfoRecs[] = { ,{ CMD_INVITEE_SMSNUMBER, true, "invitee-sms-number", "number to send any invitation to" } ,{ CMD_SMSPORT, true, "sms-port", "this devices's sms port" } #endif - ,{ CMD_WITHMQTT, false, "with-mqtt", "enable connecting via mqtt" } + ,{ CMD_WITHOUT_MQTT, false, "without-mqtt", "disable connecting via mqtt (which is on by default)" } ,{ CMD_MQTTHOST, true, "mqtt-host", "server mosquitto is running on" } ,{ CMD_MQTTPORT, true, "mqtt-port", "port mosquitto is listening on" } ,{ CMD_INVITEE_MQTTDEVID, true, "invitee-mqtt-devid", "upper-case hex devID to send any invitation to" } @@ -2626,6 +2528,32 @@ testOneString( const LaunchParams* params, GSList* testDicts ) } #endif +void +makeSelfAddress( CommsAddrRec* selfAddr, const LaunchParams* params ) +{ + XP_MEMSET( selfAddr, 0, sizeof(*selfAddr) ); + + CommsConnType typ; + for ( XP_U32 state = 0; types_iter( params->conTypes, &typ, &state ); ) { + XP_LOGFF( "got type: %s", ConnType2Str(typ) ); + addr_addType( selfAddr, typ ); + switch ( typ ) { + case COMMS_CONN_MQTT: + dvc_getMQTTDevID( params->dutil, NULL_XWE, &selfAddr->u.mqtt.devID ); + XP_ASSERT( 0 != selfAddr->u.mqtt.devID ); + break; + case COMMS_CONN_SMS: + XP_ASSERT( !!params->connInfo.sms.myPhone[0] ); + XP_STRCAT( selfAddr->u.sms.phone, params->connInfo.sms.myPhone ); + XP_ASSERT( 1 == params->connInfo.sms.port ); /* It's ignored, but keep it 1 */ + selfAddr->u.sms.port = params->connInfo.sms.port; + break; + default: + XP_ASSERT(0); + } + } +} + int main( int argc, char** argv ) { @@ -2660,9 +2588,6 @@ main( int argc, char** argv ) #ifdef XWFEATURE_SMS // char* phone = NULL; #endif -#ifdef XWFEATURE_BLUETOOTH - const char* btaddr = NULL; -#endif setlocale(LC_ALL, ""); @@ -2724,6 +2649,7 @@ main( int argc, char** argv ) mainParams.useUdp = true; mainParams.dbName = "xwgames.sqldb"; mainParams.cursesListWinHt = 5; + types_addType( &mainParams.conTypes, COMMS_CONN_MQTT ); if ( file_exists( "./dict.xwd" ) ) { trimDictPath( "./dict.xwd", dictbuf, VSIZE(dictbuf), &path, &dict ); @@ -2780,15 +2706,15 @@ main( int argc, char** argv ) #endif case CMD_HOSTIP: mainParams.connInfo.ip.hostName = optarg; - addr_addType( &mainParams.addr, COMMS_CONN_IP_DIRECT ); + types_addType( &mainParams.conTypes, COMMS_CONN_IP_DIRECT ); break; case CMD_HOSTPORT: mainParams.connInfo.ip.hostPort = atoi(optarg); - addr_addType( &mainParams.addr, COMMS_CONN_IP_DIRECT ); + types_addType( &mainParams.conTypes, COMMS_CONN_IP_DIRECT ); break; case CMD_MYPORT: mainParams.connInfo.ip.myPort = atoi(optarg); - addr_addType( &mainParams.addr, COMMS_CONN_IP_DIRECT ); + types_addType( &mainParams.conTypes, COMMS_CONN_IP_DIRECT ); break; case CMD_DICT: trimDictPath( optarg, dictbuf, VSIZE(dictbuf), &path, &dict ); @@ -2909,12 +2835,12 @@ main( int argc, char** argv ) #ifdef XWFEATURE_SMS case CMD_SMSNUMBER: /* SMS phone number */ mainParams.connInfo.sms.myPhone = optarg; - addr_addType( &mainParams.addr, COMMS_CONN_SMS ); + types_addType( &mainParams.conTypes, COMMS_CONN_SMS ); break; case CMD_INVITEE_SMSNUMBER: mainParams.connInfo.sms.inviteePhones = g_slist_append( mainParams.connInfo.sms.inviteePhones, optarg ); - addr_addType( &mainParams.addr, COMMS_CONN_SMS ); + types_addType( &mainParams.conTypes, COMMS_CONN_SMS ); break; case CMD_INVITEE_COUNTS: { gchar** strs = g_strsplit( optarg, ":", -1 ); @@ -2928,11 +2854,11 @@ main( int argc, char** argv ) break; case CMD_SMSPORT: mainParams.connInfo.sms.port = atoi(optarg); - addr_addType( &mainParams.addr, COMMS_CONN_SMS ); + types_addType( &mainParams.conTypes, COMMS_CONN_SMS ); break; #endif - case CMD_WITHMQTT: - addr_addType( &mainParams.addr, COMMS_CONN_MQTT ); + case CMD_WITHOUT_MQTT: + types_rmType( &mainParams.conTypes, COMMS_CONN_MQTT ); break; case CMD_MQTTHOST: mainParams.connInfo.mqtt.hostName = optarg; @@ -2943,7 +2869,7 @@ main( int argc, char** argv ) case CMD_INVITEE_MQTTDEVID: mainParams.connInfo.mqtt.inviteeDevIDs = g_slist_append( mainParams.connInfo.mqtt.inviteeDevIDs, optarg ); - addr_addType( &mainParams.addr, COMMS_CONN_MQTT ); + types_addType( &mainParams.conTypes, COMMS_CONN_MQTT ); break; case CMD_DUPPACKETS: mainParams.duplicatePackets = XP_TRUE; @@ -3072,8 +2998,8 @@ main( int argc, char** argv ) break; #ifdef XWFEATURE_BLUETOOTH case CMD_BTADDR: - addr_addType( &mainParams.addr, COMMS_CONN_BT ); - btaddr = optarg; + types_addType( &mainParams.conTypes, COMMS_CONN_BT ); + mainParams.connInfo.bt.btaddr = optarg; break; #endif case CMD_HIDEVALUES: @@ -3286,6 +3212,7 @@ main( int argc, char** argv ) given. It's an error to give too many, or not to give enough if there's no game-dict */ if ( 0 < nPlayerDicts ) { + XP_ASSERT(0); /* fix me */ /* XP_U16 nextDict = 0; */ /* for ( ii = 0; ii < mainParams.gi.nPlayers; ++ii ) { */ /* if ( mainParams.gi.players[ii].isLocal ) { */ @@ -3302,71 +3229,14 @@ main( int argc, char** argv ) /* } */ } - /* if ( !isServer ) { */ - /* if ( mainParams.info.serverInfo.nRemotePlayers > 0 ) { */ - /* mainParams.needsNewGame = XP_TRUE; */ - /* } */ - /* } */ #ifdef XWFEATURE_WALKDICT if ( !!testDicts ) { walk_dict_test_all( MPPARM(mainParams.mpool) &mainParams, testDicts, testPrefixes ); exit( 0 ); } #endif - CommsConnType typ; - for ( XP_U32 st = 0; addr_iter( &mainParams.addr, &typ, &st ); ) { - switch ( typ ) { -#ifdef XWFEATURE_BLUETOOTH - case COMMS_CONN_BT: { - bdaddr_t ba; - XP_Bool success; - XP_ASSERT( btaddr ); - if ( isServer ) { - success = XP_TRUE; - /* any format is ok */ - } else if ( btaddr[1] == ':' ) { - success = XP_FALSE; - if ( btaddr[0] == 'n' ) { - if ( !nameToBtAddr( btaddr+2, &ba ) ) { - fprintf( stderr, "fatal error: unable to find device %s\n", - btaddr + 2 ); - exit(0); - } - success = XP_TRUE; - } else if ( btaddr[0] == 'a' ) { - success = 0 == str2ba( &btaddr[2], &ba ); - XP_ASSERT( success ); - } - } - if ( !success ) { - usage( argv[0], "bad format for -B param" ); - } - XP_MEMCPY( &mainParams.connInfo.bt.hostAddr, &ba, - sizeof(mainParams.connInfo.bt.hostAddr) ); - } - break; -#endif -/* #ifdef XWFEATURE_SMS */ -/* case COMMS_CONN_SMS: */ -/* XP_MEMCPY( &mainParams.connInfo.sms.myPhone, sms-phone */ -/* const char* serverPhone; */ -/* int port; */ -/* break; */ -/* #endif */ - default: - break; - } - } - // addr_setType( &mainParams.addr, conType ); - - /* mainParams.pipe = linuxCommPipeCtxtMake( isServer ); */ - - /* mainParams.util->vtable->m_util_makeStreamFromAddr = */ - /* linux_util_makeStreamFromAddr; */ - - // mainParams.util->gameInfo = &mainParams.pgi; srandom( seed ); /* init linux random number generator */ XP_LOGFF( "seeded srandom with %d", seed ); diff --git a/xwords4/linux/linuxmain.h b/xwords4/linux/linuxmain.h index ac893d4d3..6ee12360e 100644 --- a/xwords4/linux/linuxmain.h +++ b/xwords4/linux/linuxmain.h @@ -112,9 +112,10 @@ void linux_doInitialReg( LaunchParams* params, XP_Bool idIsNew ); XP_Bool linux_setupDevidParams( LaunchParams* params ); XP_Bool parseSMSParams( LaunchParams* params, gchar** myPhone, XP_U16* myPort ); +void makeSelfAddress( CommsAddrRec* selfAddr, const LaunchParams* params ); + unsigned int makeRandomInt(); -bool linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs, - const CommsAddrRec* addrP ); +bool linuxOpenGame( CommonGlobals* cGlobals, const TransportProcs* procs ); void tryConnectToServer( CommonGlobals* cGlobals ); void ensureLocalPlayerNames( LaunchParams* params, CurGameInfo* gi ); void cancelTimers( CommonGlobals* cGlobals ); diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index 1dd0fef36..42f08e906 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -153,7 +153,7 @@ typedef struct _LaunchParams { const XP_UCHAR* iterTestPatStr; #endif - CommsAddrRec addr; + XP_U16 conTypes; struct { XP_U16 inviteeCounts[MAX_NUM_PLAYERS]; #ifdef XWFEATURE_RELAY @@ -169,6 +169,7 @@ typedef struct _LaunchParams { #ifdef XWFEATURE_BLUETOOTH struct { bdaddr_t hostAddr; /* unused if a host */ + const char* btaddr; } bt; #endif #if defined XWFEATURE_IP_DIRECT || defined XWFEATURE_DIRECTIP @@ -229,7 +230,8 @@ struct CommonGlobals { XWGame game; DrawCtx* draw; CurGameInfo* gi; - CommsAddrRec addr; + CommsAddrRec selfAddr; /* set e.g. by new game dialog */ + CommsAddrRec hostAddr; /* used by client only: addr of invite sender */ XP_U16 lastNTilesToUse; XP_U16 lastStreamSize; XP_U16 nMissing; diff --git a/xwords4/linux/scripts/discon_ok2.py b/xwords4/linux/scripts/discon_ok2.py index b3f23951b..6a1ceb1a9 100755 --- a/xwords4/linux/scripts/discon_ok2.py +++ b/xwords4/linux/scripts/discon_ok2.py @@ -476,6 +476,8 @@ def build_cmds(args): PARAMS += [ '--with-mqtt' ] if DEV == 1: PARAMS += [ '--force-invite' ] + else: + PARAMS += [ '--without-mqtt' ] if args.UNDO_PCT > 0: PARAMS += ['--undo-pct', args.UNDO_PCT]