revert to old invite data format

Had inadventently changed how NetLaunchInfo was transmitted, and crashed
on receiving from older builds. Fix to not crash, and then fix to send
and recieve in the old format.
This commit is contained in:
Eric House 2018-07-27 07:24:27 -07:00
parent e637f49b95
commit 2f10712379
7 changed files with 93 additions and 65 deletions

View file

@ -365,7 +365,7 @@ public class BTService extends XWService {
break;
case INVITE:
String jsonData = intent.getStringExtra( GAMEDATA_KEY );
NetLaunchInfo nli = new NetLaunchInfo( this, jsonData );
NetLaunchInfo nli = NetLaunchInfo.makeFrom( this, jsonData );
Log.i( TAG, "onStartCommand: nli: %s", nli.toString() );
String btAddr = intent.getStringExtra( ADDR_KEY );
m_sender.add( new BTQueueElem( BTCmd.INVITE, nli, btAddr ) );
@ -545,7 +545,7 @@ public class BTService extends XWService {
NetLaunchInfo nli;
if ( BT_PROTO_JSONS == proto ) {
String asJson = is.readUTF();
nli = new NetLaunchInfo( BTService.this, asJson );
nli = NetLaunchInfo.makeFrom( BTService.this, asJson );
} else {
short len = is.readShort();
byte[] nliData = new byte[len];

View file

@ -2260,7 +2260,7 @@ public class GamesListDelegate extends ListDelegateBase
{
String data = NFCUtils.getFromIntent( intent );
if ( null != data ) {
NetLaunchInfo nli = new NetLaunchInfo( m_activity, data );
NetLaunchInfo nli = NetLaunchInfo.makeFrom( m_activity, data );
if ( nli.isValid() ) {
startNewNetGame( nli );
}

View file

@ -149,7 +149,8 @@ public class MultiService {
{
Assert.assertTrue( isMissingDictIntent( intent ) );
String nliData = intent.getStringExtra( NLI_DATA );
NetLaunchInfo nli = new NetLaunchInfo( context, nliData );
NetLaunchInfo nli = NetLaunchInfo.makeFrom( context, nliData );
Assert.assertTrue( nli != null || !BuildConfig.DEBUG );
return nli;
}

View file

@ -1,7 +1,7 @@
/* -*- compile-command: "find-and-gradle.sh insXw4Deb"; -*- */
/* -*- compile-command: "find-and-gradle.sh inXw4Deb"; -*- */
/*
* Copyright 2009-2011 by Eric House (xwords@eehouse.org). All
* rights reserved.
* Copyright 2009 - 2018 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
@ -90,7 +90,7 @@ public class NetLaunchInfo implements Serializable {
inviteID = GameUtils.formatGameID( Utils.nextRandomInt() );
}
public NetLaunchInfo( Context context, String data )
private NetLaunchInfo( Context context, String data ) throws JSONException
{
init( context, data );
}
@ -128,6 +128,17 @@ public class NetLaunchInfo implements Serializable {
return nli;
}
public static NetLaunchInfo makeFrom( Context context, String data )
{
NetLaunchInfo nli = null;
try {
nli = new NetLaunchInfo( context, data );
} catch ( JSONException jse ) {
Log.ex( TAG, jse );
}
return nli;
}
public NetLaunchInfo( Context context, Uri data )
{
this();
@ -422,63 +433,58 @@ public class NetLaunchInfo implements Serializable {
return result;
}
private void init( Context context, String data )
private void init( Context context, String data ) throws JSONException
{
CommsConnTypeSet supported = CommsConnTypeSet.getSupported( context );
try {
JSONObject json = new JSONObject( data );
JSONObject json = new JSONObject( data );
int flags = json.optInt(ADDRS_KEY, -1);
boolean hasAddrs = -1 != flags;
m_addrs = hasAddrs ?
new CommsConnTypeSet( flags ) : new CommsConnTypeSet();
int flags = json.optInt(ADDRS_KEY, -1);
boolean hasAddrs = -1 != flags;
m_addrs = hasAddrs ?
new CommsConnTypeSet( flags ) : new CommsConnTypeSet();
lang = json.optInt( MultiService.LANG, -1 );
forceChannel = json.optInt( MultiService.FORCECHANNEL, 0 );
dict = json.optString( MultiService.DICT );
gameName = json.optString( MultiService.GAMENAME );
nPlayersT = json.optInt( MultiService.NPLAYERST, -1 );
nPlayersH = json.optInt( MultiService.NPLAYERSH, 1 ); // absent ok
gameID = json.optInt( MultiService.GAMEID, 0 );
lang = json.optInt( MultiService.LANG, -1 );
forceChannel = json.optInt( MultiService.FORCECHANNEL, 0 );
dict = json.optString( MultiService.DICT );
gameName = json.optString( MultiService.GAMENAME );
nPlayersT = json.optInt( MultiService.NPLAYERST, -1 );
nPlayersH = json.optInt( MultiService.NPLAYERSH, 1 ); // absent ok
gameID = json.optInt( MultiService.GAMEID, 0 );
// Try each type
for ( CommsConnType typ : supported.getTypes() ) {
if ( hasAddrs && !m_addrs.contains( typ ) ) {
continue;
}
boolean doAdd;
switch ( typ ) {
case COMMS_CONN_BT:
btAddress = json.optString( MultiService.BT_ADDRESS );
btName = json.optString( MultiService.BT_NAME );
doAdd = !hasAddrs && !btAddress.isEmpty();
break;
case COMMS_CONN_RELAY:
room = json.getString( MultiService.ROOM );
inviteID = json.optString( MultiService.INVITEID );
doAdd = !hasAddrs && !room.isEmpty();
break;
case COMMS_CONN_SMS:
phone = json.optString( PHONE_KEY );
isGSM = json.optBoolean( GSM_KEY, false );
osVers = json.optInt( OSVERS_KEY, 0 );
doAdd = !hasAddrs && !phone.isEmpty();
break;
case COMMS_CONN_P2P:
p2pMacAddress = json.optString( P2P_MAC_KEY );
doAdd = !hasAddrs && null != p2pMacAddress;
break;
default:
doAdd = false;
Assert.fail();
}
if ( doAdd ) {
m_addrs.add( typ );
}
// Try each type
for ( CommsConnType typ : supported.getTypes() ) {
if ( hasAddrs && !m_addrs.contains( typ ) ) {
continue;
}
boolean doAdd;
switch ( typ ) {
case COMMS_CONN_BT:
btAddress = json.optString( MultiService.BT_ADDRESS );
btName = json.optString( MultiService.BT_NAME );
doAdd = !hasAddrs && !btAddress.isEmpty();
break;
case COMMS_CONN_RELAY:
room = json.getString( MultiService.ROOM );
inviteID = json.optString( MultiService.INVITEID );
doAdd = !hasAddrs && !room.isEmpty();
break;
case COMMS_CONN_SMS:
phone = json.optString( PHONE_KEY );
isGSM = json.optBoolean( GSM_KEY, false );
osVers = json.optInt( OSVERS_KEY, 0 );
doAdd = !hasAddrs && !phone.isEmpty();
break;
case COMMS_CONN_P2P:
p2pMacAddress = json.optString( P2P_MAC_KEY );
doAdd = !hasAddrs && null != p2pMacAddress;
break;
default:
doAdd = false;
Assert.fail();
}
if ( doAdd ) {
m_addrs.add( typ );
}
} catch ( JSONException jse ) {
Log.ex( TAG, jse );
}
removeUnsupported( supported );

View file

@ -397,7 +397,7 @@ public class RelayService extends XWService
case GOT_INVITE:
int srcDevID = intent.getIntExtra( INVITE_FROM, 0 );
NetLaunchInfo nli
= new NetLaunchInfo( this, intent.getStringExtra(NLI_DATA) );
= NetLaunchInfo.makeFrom( this, intent.getStringExtra(NLI_DATA) );
receiveInvitation( srcDevID, nli );
break;
case SEND:
@ -820,7 +820,7 @@ public class RelayService extends XWService
Log.d( TAG, "sendInvitation(%d->%d/%s [%s])", srcDevID, destDevID,
relayID, nliStr );
NetLaunchInfo nli = new NetLaunchInfo( this, nliStr );
NetLaunchInfo nli = NetLaunchInfo.makeFrom( this, nliStr );
byte[] nliData = XwJNI.nliToStream( nli );
if ( BuildConfig.DEBUG ) {
NetLaunchInfo tmp = XwJNI.nliFromStream( nliData );

View file

@ -376,10 +376,15 @@ public class SMSService extends XWService {
private void inviteRemote( String phone, String nliData )
{
try {
byte[] asBytes = nliData.getBytes( "UTF-8" );
ByteArrayOutputStream bas = new ByteArrayOutputStream();
DataOutputStream das = new DataOutputStream( bas );
das.writeUTF( nliData );
byte[] asBytes = bas.toByteArray();
resendFor( phone, SMS_CMD.INVITE, 0, asBytes, true );
} catch ( java.io.UnsupportedEncodingException uee ) {
Log.ex( TAG, uee );
} catch ( java.io.IOException ioe ) {
Log.ex( TAG, ioe );
}
}
@ -459,8 +464,7 @@ public class SMSService extends XWService {
Log.i( TAG, "receive(cmd=%s)", msg.cmd );
switch( msg.cmd ) {
case INVITE:
NetLaunchInfo nli = new NetLaunchInfo( this, new String(msg.data) );
makeForInvite( phone, nli );
makeForInvite( phone, msg.data );
break;
case DATA:
if ( feedMessage( msg.gameID, msg.data, new CommsAddrRec( phone ) ) ) {
@ -504,6 +508,23 @@ public class SMSService extends XWService {
GameUtils.postInvitedNotification( this, gameID, body, rowid );
}
private void makeForInvite( String phone, byte[] data )
{
try {
ByteArrayInputStream bais = new ByteArrayInputStream( data );
DataInputStream dis = new DataInputStream( bais );
String nliData = dis.readUTF();
NetLaunchInfo nli = NetLaunchInfo.makeFrom( this, nliData );
if ( null != nli ) {
makeForInvite( phone, nli );
} else {
Log.e( TAG, "null nli; bad data?" );
}
} catch ( java.io.IOException ioe ) {
Log.ex( TAG, ioe );
}
}
private void makeForInvite( String phone, NetLaunchInfo nli )
{
if ( handleInvitation( nli, phone, DictFetchOwner.OWNER_SMS ) ) {

View file

@ -760,7 +760,7 @@ public class WiDirService extends XWService {
{
Log.d( TAG, "handleGotInvite()" );
String nliData = intent.getStringExtra( KEY_NLI );
NetLaunchInfo nli = new NetLaunchInfo( this, nliData );
NetLaunchInfo nli = NetLaunchInfo.makeFrom( this, nliData );
String returnMac = intent.getStringExtra( KEY_SRC );
if ( !handleInvitation( nli, returnMac, DictFetchOwner.OWNER_P2P ) ) {