diff --git a/xwords4/android/app/build.gradle b/xwords4/android/app/build.gradle index 00aecdfef..f0b1862ae 100644 --- a/xwords4/android/app/build.gradle +++ b/xwords4/android/app/build.gradle @@ -1,6 +1,6 @@ def INITIAL_CLIENT_VERS = 9 -def VERSION_CODE_BASE = 148 -def VERSION_NAME = '4.4.152' +def VERSION_CODE_BASE = 149 +def VERSION_NAME = '4.4.153' def FABRIC_API_KEY = System.getenv("FABRIC_API_KEY") def BUILD_INFO_NAME = "build-info.txt" diff --git a/xwords4/android/app/src/main/assets/changes.html b/xwords4/android/app/src/main/assets/changes.html index 28a3ab1f7..f6ca79a17 100644 --- a/xwords4/android/app/src/main/assets/changes.html +++ b/xwords4/android/app/src/main/assets/changes.html @@ -13,9 +13,9 @@ -

CrossWords 4.4.152 release

+

CrossWords 4.4.153 release

-

This release fixes a nasty crash in some non-English versions.

+

This release fixes a crash sending invitations via SMS/Text.

Please take @@ -23,17 +23,13 @@ CrossWords.

-

New with this (and previous) release

+

New with this release

(The full changelog diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java index 025567323..8ddbaaf49 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/BoardDelegate.java @@ -755,9 +755,10 @@ public class BoardDelegate extends DelegateBase // straight to asking for the permission. private void callInviteChoices( final SentInvitesInfo info ) { - Perms23.tryGetPerms( this, Perm.READ_PHONE_STATE, - R.string.phone_state_rationale, - Action.ASKED_PHONE_STATE, info ); + Perms23.tryGetPermsNA( this, Perm.READ_PHONE_STATE, + R.string.phone_state_rationale, + R.string.key_na_perms_phonestate, + Action.ASKED_PHONE_STATE, info ); } private void showInviteChoicesThen( Object[] params ) @@ -1260,7 +1261,8 @@ public class BoardDelegate extends DelegateBase break; default: - handled = false; + handled = super.onDismissed( action, params ); + break; } return handled; } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java index b739af7ca..093a5f296 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DelegateBase.java @@ -792,9 +792,20 @@ public class DelegateBase implements DlgClickNotify, public boolean onDismissed( Action action, Object[] params ) { - Log.d( TAG, "%s.dlgDismissed(%s)", getClass().getSimpleName(), + boolean handled = false; + Log.d( TAG, "%s.onDismissed(%s)", getClass().getSimpleName(), action.toString() ); - return false; + + switch( action ) { + case PERMS_QUERY: + handled = true; + Perms23.onGotPermsAction( this, false, params ); + break; + default: + Log.e( TAG, "onDismissed(): not handling action %s", action ); + } + + return handled; } public void inviteChoiceMade( Action action, DlgClickNotify.InviteMeans means, Object... params ) diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameConfigDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameConfigDelegate.java index 33be78a13..dd545ec7b 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameConfigDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameConfigDelegate.java @@ -783,9 +783,10 @@ public class GameConfigDelegate extends DelegateBase private void showConnAfterCheck() { if ( null == SMSPhoneInfo.get( m_activity ) ) { - Perms23.tryGetPerms( this, Perms23.Perm.READ_PHONE_STATE, - R.string.phone_state_rationale, - Action.ASKED_PHONE_STATE ); + Perms23.tryGetPermsNA( this, Perms23.Perm.READ_PHONE_STATE, + R.string.phone_state_rationale, + R.string.key_na_perms_phonestate, + Action.ASKED_PHONE_STATE ); } else { showDialogFragment( DlgID.CHANGE_CONN, m_conTypes ); } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/NetLaunchInfo.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/NetLaunchInfo.java index 183d9edce..aff0be752 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/NetLaunchInfo.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/NetLaunchInfo.java @@ -217,9 +217,13 @@ public class NetLaunchInfo implements Serializable { p2pMacAddress = data.getQueryParameter( P2P_MAC_KEY ); doAdd = !hasAddrs && null != p2pMacAddress; break; + case COMMS_CONN_NFC: + doAdd = true; + break; default: doAdd = false; - Assert.fail(); + Log.d( TAG, "unexpected type: %s", typ ); + Assert.assertFalse( BuildConfig.DEBUG ); } if ( doAdd ) { m_addrs.add( typ ); @@ -691,7 +695,7 @@ public class NetLaunchInfo implements Serializable { private void calcValid() { boolean valid = hasCommon() && null != m_addrs; - // DbgUtils.logf( "calcValid(%s)", toString() ); + // Log.d( TAG, "calcValid(%s); valid (so far): %b", this, valid ); if ( valid ) { for ( Iterator iter = m_addrs.iterator(); valid && iter.hasNext(); ) { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Perms23.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Perms23.java index f8efdf580..ebc106c6b 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Perms23.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/Perms23.java @@ -203,23 +203,26 @@ public class Perms23 { private static class QueryInfo { private Action m_action; private Perm[] m_perms; + private int mNAKey; private DelegateBase m_delegate; private String m_rationaleMsg; private Object[] m_params; private QueryInfo( DelegateBase delegate, Action action, - Perm[] perms, String msg, Object[] params ) { + Perm[] perms, String msg, int naKey, + Object[] params ) { m_delegate = delegate; m_action = action; m_perms = perms; m_rationaleMsg = msg; + mNAKey = naKey; m_params = params; } private QueryInfo( DelegateBase delegate, Object[] params ) { this( delegate, (Action)params[0], (Perm[])params[1], (String)params[2], - (Object[])params[3] ); + 0, (Object[])params[3] ); } private Object[] getParams() @@ -260,6 +263,7 @@ public class Perms23 { .setPosButton( R.string.button_ask_again ) .setNegButton( R.string.button_skip ) .setParams( QueryInfo.this.getParams() ) + .setNAKey( mNAKey ) .show(); } } ); @@ -319,30 +323,36 @@ public class Perms23 { * Request permissions, giving rationale once, then call with action and * either positive or negative, the former if permission granted. */ + private static void tryGetPermsImpl( DelegateBase delegate, Perm[] perms, + String rationaleMsg, int naKey, + final Action action, Object... params ) + { + // Log.d( TAG, "tryGetPerms(%s)", perm.toString() ); + new QueryInfo( delegate, action, perms, rationaleMsg, naKey, params ) + .doIt( true ); + } + public static void tryGetPerms( DelegateBase delegate, Perm[] perms, int rationaleId, final Action action, Object... params ) { // Log.d( TAG, "tryGetPerms(%s)", perm.toString() ); - Context context = XWApp.getContext(); - String msg = rationaleId == 0 - ? null : LocUtils.getString( context, rationaleId ); - tryGetPerms( delegate, perms, msg, action, params ); + String msg = LocUtils.getStringOrNull( rationaleId ); + tryGetPermsImpl( delegate, perms, msg, 0, action, params ); } public static void tryGetPerms( DelegateBase delegate, Perm[] perms, String rationaleMsg, final Action action, Object... params ) { - // Log.d( TAG, "tryGetPerms(%s)", perm.toString() ); - new QueryInfo( delegate, action, perms, rationaleMsg, params ) - .doIt( true ); + tryGetPermsImpl( delegate, perms, rationaleMsg, 0, action, params ); } public static void tryGetPerms( DelegateBase delegate, Perm perm, String rationaleMsg, final Action action, Object... params ) { - tryGetPerms( delegate, new Perm[]{ perm }, rationaleMsg, action, params ); + tryGetPermsImpl( delegate, new Perm[]{ perm }, rationaleMsg, 0, + action, params ); } public static void tryGetPerms( DelegateBase delegate, Perm perm, int rationaleId, @@ -351,6 +361,15 @@ public class Perms23 { tryGetPerms( delegate, new Perm[]{perm}, rationaleId, action, params ); } + public static void tryGetPermsNA( DelegateBase delegate, Perm perm, + int rationaleId, int naKey, + Action action, Object... params ) + { + tryGetPermsImpl( delegate, new Perm[] {perm}, + LocUtils.getStringOrNull( rationaleId ), naKey, + action, params ); + } + public static void onGotPermsAction( DelegateBase delegate, boolean positive, Object[] params ) { diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/loc/LocUtils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/loc/LocUtils.java index 3e65f491c..a2e74fcee 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/loc/LocUtils.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/loc/LocUtils.java @@ -265,6 +265,16 @@ public class LocUtils { return getString( context, true, id ); } + public static String getStringOrNull( int id ) + { + String result = null; + if ( 0 != id ) { + Context context = XWApp.getContext(); + result = getString( context, true, id ); + } + return result; + } + public static String getString( Context context, boolean canUseDB, int id ) { String result = null; diff --git a/xwords4/android/app/src/main/res/values/common_rsrc.xml b/xwords4/android/app/src/main/res/values/common_rsrc.xml index 56e50c8bc..f213c014e 100644 --- a/xwords4/android/app/src/main/res/values/common_rsrc.xml +++ b/xwords4/android/app/src/main/res/values/common_rsrc.xml @@ -145,6 +145,7 @@ key_na_bt_badproto key_na_sms_banned key_na_longtap_lookup + key_na_perms_phonestate xwords@eehouse.org diff --git a/xwords4/common/config.mk b/xwords4/common/config.mk index ac15f4e62..c85f602fe 100644 --- a/xwords4/common/config.mk +++ b/xwords4/common/config.mk @@ -49,6 +49,7 @@ COMMONSRC = \ $(COMMONDIR)/dictmgr.c \ $(COMMONDIR)/dbgutil.c \ $(COMMONDIR)/smsproto.c \ + $(COMMONDIR)/device.c \ # PENDING: define this in terms of above!!! @@ -87,5 +88,6 @@ COMMON5 = \ $(COMMONOBJDIR)/dictmgr.o \ $(COMMONOBJDIR)/dbgutil.o \ $(COMMONOBJDIR)/smsproto.o \ + $(COMMONOBJDIR)/device.o \ COMMONOBJ = $(COMMON1) $(COMMON2) $(COMMON3) $(COMMON4) $(COMMON5) diff --git a/xwords4/common/device.c b/xwords4/common/device.c new file mode 100644 index 000000000..7eedaf462 --- /dev/null +++ b/xwords4/common/device.c @@ -0,0 +1,79 @@ +/* -*- compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */ +/* + * Copyright 2020 by Eric House (xwords@eehouse.org). All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "device.h" +#include "comtypes.h" +#include "memstream.h" +#include "xwstream.h" + +#ifdef XWFEATURE_DEVICE + +# define KEY_DEVSTATE PERSIST_KEY("devState") + +typedef struct _DevCtxt { + XP_U16 devCount; +} DevCtxt; + +static XWStreamCtxt* +mkStream( XW_DUtilCtxt* dutil ) +{ + XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(dutil->mpool) + dutil_getVTManager(dutil) ); + return stream; +} + +static DevCtxt* +load( XW_DUtilCtxt* dutil ) +{ + LOG_FUNC(); + DevCtxt* state = (DevCtxt*)dutil->devCtxt; + if ( NULL == state ) { + XWStreamCtxt* stream = mkStream( dutil ); + dutil_loadStream( dutil, KEY_DEVSTATE, stream ); + + state = XP_CALLOC( dutil->mpool, sizeof(*state) ); + dutil->devCtxt = state; + + if ( 0 < stream_getSize( stream ) ) { + state->devCount = stream_getU16( stream ); + ++state->devCount; /* for testing until something's there */ + XP_LOGF( "%s(): read devCount: %d", __func__, state->devCount ); + } else { + XP_LOGF( "%s(): empty stream!!", __func__ ); + } + stream_destroy( stream ); + } + + return state; +} + +void +device_store( XW_DUtilCtxt* dutil ) +{ + LOG_FUNC(); + DevCtxt* state = load( dutil ); + XWStreamCtxt* stream = mkStream( dutil ); + stream_putU16( stream, state->devCount ); + dutil_storeStream( dutil, KEY_DEVSTATE, stream ); + stream_destroy( stream ); + + XP_FREEP( dutil->mpool, &dutil->devCtxt ); +} + +#endif diff --git a/xwords4/common/device.h b/xwords4/common/device.h new file mode 100644 index 000000000..6868cb5ba --- /dev/null +++ b/xwords4/common/device.h @@ -0,0 +1,33 @@ +/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */ +/* + * Copyright 2020 by Eric House (xwords@eehouse.org). All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef _DEVICE_H_ +#define _DEVICE_H_ + +#include "dutil.h" + +// void device_load( XW_DUtilCtxt dctxt ); +# ifdef XWFEATURE_DEVICE +void device_store( XW_DUtilCtxt* dctxt ); +# else +# define device_store(dctxt) +# endif + +#endif diff --git a/xwords4/common/dutil.h b/xwords4/common/dutil.h index 70aa8c70c..9771e8a09 100644 --- a/xwords4/common/dutil.h +++ b/xwords4/common/dutil.h @@ -60,8 +60,8 @@ typedef struct _DUtilVtable { struct XW_DUtilCtxt { DUtilVtable vtable; - void* closure; + void* devCtxt; /* owned by device.c */ VTableMgr* vtMgr; MPSLOT }; diff --git a/xwords4/common/nli.c b/xwords4/common/nli.c index a49802443..c65d708b9 100644 --- a/xwords4/common/nli.c +++ b/xwords4/common/nli.c @@ -42,9 +42,21 @@ nli_init( NetLaunchInfo* nli, const CurGameInfo* gi, const CommsAddrRec* addr, nli->nPlayersH = nPlayers; nli->forceChannel = forceChannel; - if ( addr_hasType( addr, COMMS_CONN_RELAY ) ) { - types_addType( &nli->_conTypes, COMMS_CONN_RELAY ); - XP_STRCAT( nli->room, addr->u.ip_relay.invite ); + CommsConnType typ; + for ( XP_U32 st = 0; addr_iter( addr, &typ, &st ); ) { + types_addType( &nli->_conTypes, typ ); + switch ( typ ) { + case COMMS_CONN_RELAY: + XP_STRCAT( nli->room, addr->u.ip_relay.invite ); + break; + case COMMS_CONN_SMS: + XP_STRCAT( nli->phone, addr->u.sms.phone ); + // nli->port = addr->u.sms.port; <-- I wish + break; + default: + XP_ASSERT(0); + break; + } } } @@ -159,9 +171,8 @@ nli_makeFromStream( NetLaunchInfo* nli, XWStreamCtxt* stream ) void nli_makeAddrRec( const NetLaunchInfo* nli, CommsAddrRec* addr ) { - XP_U32 state = 0; CommsConnType type; - while ( types_iter( nli->_conTypes, &type, &state ) ) { + for ( XP_U32 state = 0; types_iter( nli->_conTypes, &type, &state ); ) { addr_addType( addr, type ); switch( type ) { case COMMS_CONN_RELAY: @@ -176,6 +187,7 @@ nli_makeAddrRec( const NetLaunchInfo* nli, CommsAddrRec* addr ) break; case COMMS_CONN_SMS: XP_STRCAT( addr->u.sms.phone, nli->phone ); + addr->u.sms.port = 1; /* BAD, but 0 is worse */ break; default: XP_ASSERT(0); diff --git a/xwords4/linux/Makefile b/xwords4/linux/Makefile index 6e927ab16..dc52a8abf 100644 --- a/xwords4/linux/Makefile +++ b/xwords4/linux/Makefile @@ -163,6 +163,8 @@ DEFINES += -DXWFEATURE_DIRECTIP # Robot can be made to think, to simulate for relay mostly DEFINES += -DXWFEATURE_SLOW_ROBOT +DEFINES += -DXWFEATURE_DEVICE + # Support device-to-device connection via UDP, e.g. using wifi on a # LAN or where the host/server isn't behind a firewall. # DEFINES += -DXWFEATURE_IP_DIRECT diff --git a/xwords4/linux/cursesmain.c b/xwords4/linux/cursesmain.c index bed4a4838..c6807c391 100644 --- a/xwords4/linux/cursesmain.c +++ b/xwords4/linux/cursesmain.c @@ -65,6 +65,7 @@ #include "gamesdb.h" #include "relaycon.h" #include "smsproto.h" +#include "device.h" #ifdef CURSES_SMALL_SCREEN # define MENU_WINDOW_HEIGHT 1 @@ -2239,8 +2240,11 @@ cursesmain( XP_Bool isServer, LaunchParams* params ) endwin(); + device_store( params->dutil ); + if ( !!params->dbName ) { closeGamesDB( params->pDb ); + params->pDb = NULL; } relaycon_cleanup( params ); diff --git a/xwords4/linux/gamesdb.c b/xwords4/linux/gamesdb.c index e80a4de8d..efe30f397 100644 --- a/xwords4/linux/gamesdb.c +++ b/xwords4/linux/gamesdb.c @@ -533,8 +533,9 @@ db_fetch( sqlite3* pDb, const gchar* key, gchar* buf, gint* buflen ) XP_ASSERT( !!pDb ); FetchResult result = NOT_THERE; char query[256]; - snprintf( query, sizeof(query), - "SELECT value from pairs where key = '%s'", key ); + int len = snprintf( query, sizeof(query), + "SELECT value from pairs where key = '%s'", key ); + XP_ASSERT( len < sizeof(query) ); sqlite3_stmt *ppStmt; int sqlResult = sqlite3_prepare_v2( pDb, query, -1, &ppStmt, NULL ); XP_Bool found = SQLITE_OK == sqlResult; diff --git a/xwords4/linux/gtkboard.c b/xwords4/linux/gtkboard.c index 17e62780f..0393bf9f5 100644 --- a/xwords4/linux/gtkboard.c +++ b/xwords4/linux/gtkboard.c @@ -85,7 +85,7 @@ static void handle_invite_button( GtkWidget* widget, GtkGameGlobals* globals ); static void gtkShowFinalScores( const GtkGameGlobals* globals, XP_Bool ignoreTimeout ); static void send_invites( CommonGlobals* cGlobals, XP_U16 nPlayers, - XP_U32 devID, const XP_UCHAR* relayID, + XP_U32 relayDevID, const XP_UCHAR* relayID, const CommsAddrRec* addrs ); @@ -1556,18 +1556,19 @@ handle_invite_button( GtkWidget* XP_UNUSED(widget), GtkGameGlobals* globals ) CommsAddrRec inviteAddr = {0}; gint nPlayers = nMissing; - XP_U32 devID; - XP_Bool confirmed = gtkInviteDlg( globals, &inviteAddr, &nPlayers, &devID ); + XP_U32 relayDevID = 0; + XP_Bool confirmed = gtkInviteDlg( globals, &inviteAddr, &nPlayers, + &relayDevID ); XP_LOGF( "%s: inviteDlg => %d", __func__, confirmed ); if ( confirmed ) { - send_invites( cGlobals, nPlayers, devID, NULL, &inviteAddr ); + send_invites( cGlobals, nPlayers, relayDevID, NULL, &inviteAddr ); } } /* handle_invite_button */ static void send_invites( CommonGlobals* cGlobals, XP_U16 nPlayers, - XP_U32 devID, const XP_UCHAR* relayID, + XP_U32 relayDevID, const XP_UCHAR* relayID, const CommsAddrRec* addrs ) { CommsAddrRec addr = {0}; @@ -1579,10 +1580,12 @@ send_invites( CommonGlobals* cGlobals, XP_U16 nPlayers, NetLaunchInfo nli = {0}; nli_init( &nli, cGlobals->gi, &addr, nPlayers, forceChannel ); - XP_UCHAR buf[32]; - snprintf( buf, sizeof(buf), "%X", makeRandomInt() ); - nli_setInviteID( &nli, buf ); - nli_setDevID( &nli, linux_getDevIDRelay( cGlobals->params ) ); + if ( addr_hasType( &addr, COMMS_CONN_RELAY ) ) { + XP_UCHAR buf[32]; + snprintf( buf, sizeof(buf), "%X", makeRandomInt() ); + nli_setInviteID( &nli, buf ); /* should not be relay only!!! */ + } + // nli_setDevID( &nli, linux_getDevIDRelay( cGlobals->params ) ); #ifdef DEBUG { @@ -1603,9 +1606,9 @@ send_invites( CommonGlobals* cGlobals, XP_U16 nPlayers, linux_sms_invite( cGlobals->params, &nli, addrs->u.sms.phone, addrs->u.sms.port ); } - if ( 0 != devID || !!relayID ) { - XP_ASSERT( 0 != devID || (!!relayID && !!relayID[0]) ); - relaycon_invite( cGlobals->params, devID, relayID, &nli ); + if ( 0 != relayDevID || !!relayID ) { + XP_ASSERT( 0 != relayDevID || (!!relayID && !!relayID[0]) ); + relaycon_invite( cGlobals->params, relayDevID, relayID, &nli ); } /* while ( gtkaskm( "Invite how many and how?", infos, VSIZE(infos) ) ) { */ diff --git a/xwords4/linux/gtkinvit.c b/xwords4/linux/gtkinvit.c index d2ca40fc1..c85a85f48 100644 --- a/xwords4/linux/gtkinvit.c +++ b/xwords4/linux/gtkinvit.c @@ -38,7 +38,7 @@ typedef struct _GtkInviteState { GtkGameGlobals* globals; CommsAddrRec* addr; gint* nPlayersP; - XP_U32* devIDp; + XP_U32* relayDevIDp; gint maxPlayers; GtkWidget* nPlayersCombo; @@ -96,7 +96,7 @@ handle_ok( GtkWidget* XP_UNUSED(widget), gpointer closure ) case COMMS_CONN_RELAY: txt = gtk_entry_get_text( GTK_ENTRY(state->devID) ); snprintf( s_devIDBuf, sizeof(s_devIDBuf), "%s", txt ); - *state->devIDp = atoi( txt ); + *state->relayDevIDp = atoi( txt ); break; #endif #ifdef XWFEATURE_BLUETOOTH @@ -275,18 +275,15 @@ onPageChanged( GtkNotebook* XP_UNUSED(notebook), gpointer XP_UNUSED(arg1), XP_Bool gtkInviteDlg( GtkGameGlobals* globals, CommsAddrRec* addr, - gint* nPlayersP, XP_U32* devIDp ) - - + gint* nPlayersP, XP_U32* relayDevIDp ) { - GtkInviteState state; - XP_MEMSET( &state, 0, sizeof(state) ); - - state.globals = globals; - state.addr = addr; - state.nPlayersP = nPlayersP; - state.devIDp = devIDp; - state.maxPlayers = *nPlayersP; + GtkInviteState state = { + .globals = globals, + .addr = addr, + .nPlayersP = nPlayersP, + .relayDevIDp = relayDevIDp, + .maxPlayers = *nPlayersP, + }; GtkWidget* dialog; GtkWidget* hbox; diff --git a/xwords4/linux/gtkinvit.h b/xwords4/linux/gtkinvit.h index 5bb1b02f2..3f5cb960d 100644 --- a/xwords4/linux/gtkinvit.h +++ b/xwords4/linux/gtkinvit.h @@ -24,7 +24,7 @@ /* return true if not cancelled */ XP_Bool gtkInviteDlg( GtkGameGlobals* globals, CommsAddrRec* addr, - /*inout*/ gint* nPlayers, /* out */ XP_U32* devID ); + /*inout*/ gint* nPlayers, /* out */ XP_U32* relayDevID ); #endif diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index f44912bd7..ee7451f91 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -31,6 +31,7 @@ #include "relaycon.h" #include "linuxsms.h" #include "gtkask.h" +#include "device.h" static void onNewData( GtkAppGlobals* apg, sqlite3_int64 rowid, XP_Bool isNew ); @@ -941,8 +942,9 @@ gtkmain( LaunchParams* params ) } gtk_main(); - + device_store( params->dutil ); closeGamesDB( params->pDb ); + params->pDb = NULL; relaycon_cleanup( params ); #ifdef XWFEATURE_SMS linux_sms_cleanup( params ); diff --git a/xwords4/linux/lindutil.c b/xwords4/linux/lindutil.c index 3be0a333d..1ea819945 100644 --- a/xwords4/linux/lindutil.c +++ b/xwords4/linux/lindutil.c @@ -205,12 +205,8 @@ linux_dutil_loadStream( XW_DUtilCtxt* duc, const XP_UCHAR* key, if ( 0 < len ) { XP_U8 buf[len]; linux_dutil_loadPtr( duc, key, buf, &len ); - XP_ASSERT( buf[len-1] == '\0' ); - gsize out_len; - guchar* txt = g_base64_decode( (const gchar*)buf, &out_len ); /* BAD */ - stream_putBytes( stream, txt, out_len ); - g_free( txt ); + stream_putBytes( stream, buf, len ); } XP_LOGF( "%s(key=%s) => len: %d", __func__, key, stream_getSize(stream) ); @@ -218,7 +214,7 @@ linux_dutil_loadStream( XW_DUtilCtxt* duc, const XP_UCHAR* key, static void linux_dutil_storePtr( XW_DUtilCtxt* duc, const XP_UCHAR* key, - const void* data, XP_U16 len ) + const void* data, const XP_U16 len ) { LaunchParams* params = (LaunchParams*)duc->closure; sqlite3* pDb = params->pDb; @@ -238,18 +234,23 @@ linux_dutil_loadPtr( XW_DUtilCtxt* duc, const XP_UCHAR* key, gint buflen = 0; FetchResult res = db_fetch( pDb, key, NULL, &buflen ); if ( res == BUFFER_TOO_SMALL ) { /* expected: I passed 0 */ - void* tmp = XP_MALLOC( duc->mpool, buflen ); - res = db_fetch( pDb, key, tmp, &buflen ); - XP_ASSERT( res == SUCCESS ); + if ( 0 == *lenp ) { + *lenp = buflen; + } else { + gchar* tmp = XP_MALLOC( duc->mpool, buflen ); + res = db_fetch( pDb, key, tmp, &buflen ); + XP_ASSERT( res == SUCCESS ); + XP_ASSERT( tmp[buflen-1] == '\0' ); - gsize out_len; - guchar* txt = g_base64_decode( (const gchar*)tmp, &out_len ); - if ( out_len <= *lenp ) { - XP_MEMCPY( data, txt, out_len ); - *lenp = out_len; + gsize out_len; + guchar* txt = g_base64_decode( (const gchar*)tmp, &out_len ); + if ( out_len <= *lenp ) { + XP_MEMCPY( data, txt, out_len ); + *lenp = out_len; + } + XP_FREEP( duc->mpool, &tmp ); + g_free( txt ); } - XP_FREEP( duc->mpool, &tmp ); - g_free( txt ); } else { *lenp = 0; /* doesn't exist */ } diff --git a/xwords4/linux/relaycon.c b/xwords4/linux/relaycon.c index 03b2e69b5..7ffbeab9f 100644 --- a/xwords4/linux/relaycon.c +++ b/xwords4/linux/relaycon.c @@ -313,7 +313,7 @@ relaycon_reg( LaunchParams* params, const XP_UCHAR* rDevID, } void -relaycon_invite( LaunchParams* params, XP_U32 destDevID, +relaycon_invite( LaunchParams* params, XP_U32 destRelayDevID, const XP_UCHAR* relayID, NetLaunchInfo* invit ) { XP_U8 tmpbuf[256]; @@ -326,13 +326,13 @@ relaycon_invite( LaunchParams* params, XP_U32 destDevID, /* write relayID /, or if we have an actual devID write a null byte plus it. */ - if ( 0 == destDevID ) { + if ( 0 == destRelayDevID ) { XP_ASSERT( '\0' != relayID[0] ); indx += writeBytes( &tmpbuf[indx], sizeof(tmpbuf) - indx, (XP_U8*)relayID, 1 + XP_STRLEN( relayID ) ); } else { tmpbuf[indx++] = '\0'; /* null byte: zero-len str */ - indx += writeLong( &tmpbuf[indx], sizeof(tmpbuf) - indx, destDevID ); + indx += writeLong( &tmpbuf[indx], sizeof(tmpbuf) - indx, destRelayDevID ); } XWStreamCtxt* stream = mem_stream_make_raw( MPPARM(params->mpool)