diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.java index 994cf6791..884b57f2a 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.java @@ -223,6 +223,8 @@ public class MQTTUtils extends Thread MqttMessage message = new MqttMessage( pair.mPackets[ii] ); message.setRetained( true ); mClient.publish( pair.mTopics[ii], message ); + Log.d( TAG, "%H: published msg of len %d to topic %s", MQTTUtils.this, + pair.mPackets[ii].length, pair.mTopics[ii] ); } } catch ( MqttException me ) { me.printStackTrace(); @@ -635,8 +637,12 @@ public class MQTTUtils extends Thread public void messageArrived( String topic, MqttMessage message ) throws Exception { - Log.d( TAG, "%H.messageArrived(topic=%s)", this, topic ); - mRxMsgThread.add( topic, message.getPayload() ); + byte[] payload = message.getPayload(); + Log.d( TAG, "%H.messageArrived(topic=%s, len=%d)", this, topic, + payload.length ); + if ( 0 < payload.length ) { + mRxMsgThread.add( topic, payload ); + } ConnStatusHandler .updateStatusIn( mContext, CommsConnType.COMMS_CONN_MQTT, true ); @@ -706,6 +712,8 @@ public class MQTTUtils extends Thread = new LinkedBlockingQueue<>(); void add( String topic, byte[] msg ) { + Log.d( TAG, "%H.RxMsgThread.add(topic: %s, len: %d)", MQTTUtils.this, + topic, msg.length ); mQueue.add( new MessagePair( topic, msg ) ); } @@ -803,11 +811,15 @@ public class MQTTUtils extends Thread private void handleInvitation( NetLaunchInfo nli ) { handleInvitation( nli, null, MultiService.DictFetchOwner.OWNER_MQTT ); + // Now nuke the invitation so we don't keep getting it, e.g. if + // the sender deletes the game + TopicsAndPackets tap = XwJNI.dvc_makeMQTTNukeInvite( nli ); + addToSendQueue( getContext(), tap ); } private void receiveMessage( long rowid, MultiMsgSink sink, byte[] msg ) { - Log.d( TAG, "receiveMessage(rowid=%d, len=%d)", rowid, msg.length ); + // Log.d( TAG, "receiveMessage(rowid=%d, len=%d)", rowid, msg.length ); receiveMessage( rowid, sink, msg, mReturnAddr ); } } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java index 872d6fb22..57815ab04 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java @@ -169,6 +169,11 @@ public class XwJNI { return dvc_makeMQTTInvites( getJNI().m_ptrGlobals, invitee, nli ); } + public static TopicsAndPackets dvc_makeMQTTNukeInvite( NetLaunchInfo nli ) + { + return dvc_makeMQTTNukeInvite( getJNI().m_ptrGlobals, nli ); + } + public static TopicsAndPackets dvc_makeMQTTMessages( String addressee, int gameID, byte[] buf ) { return dvc_makeMQTTMessages( getJNI().m_ptrGlobals, addressee, gameID, buf ); @@ -777,6 +782,8 @@ public class XwJNI { dvc_makeMQTTInvites( long jniState, String invitee, NetLaunchInfo nli ); + private static native TopicsAndPackets dvc_makeMQTTNukeInvite( long jniState, + NetLaunchInfo nli ); private static native TopicsAndPackets dvc_makeMQTTMessages( long jniState, String addressee, diff --git a/xwords4/android/jni/xwjni.c b/xwords4/android/jni/xwjni.c index da0682602..f763dd1d5 100644 --- a/xwords4/android/jni/xwjni.c +++ b/xwords4/android/jni/xwjni.c @@ -758,6 +758,25 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1makeMQTTInvites return result; } +JNIEXPORT jobject JNICALL +Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1makeMQTTNukeInvite +( JNIEnv* env, jclass C, jlong jniGlobalPtr, jobject jnli ) +{ + jobject result; + DVC_HEADER(jniGlobalPtr); + + NetLaunchInfo nli; + loadNLI( env, &nli, jnli ); + + MTPData mtp = { .env = env, }; + + dvc_makeMQTTNukeInvite( globalState->dutil, env, + msgAndTopicProc, &mtp, &nli ); + result = wrapResults( &mtp ); + DVC_HEADER_END(); + return result; +} + JNIEXPORT jobject JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1makeMQTTMessages ( JNIEnv* env, jclass C, jlong jniGlobalPtr, jstring jAddressee, diff --git a/xwords4/common/device.c b/xwords4/common/device.c index 8a29e5589..386d176f8 100644 --- a/xwords4/common/device.c +++ b/xwords4/common/device.c @@ -282,7 +282,9 @@ addProto3HeaderCmd( XW_DUtilCtxt* dutil, XWEnv xwe, MQTTCmd cmd, static void callProc( MsgAndTopicProc proc, void* closure, const XP_UCHAR* topic, XWStreamCtxt* stream ) { - (*proc)( closure, topic, stream_getPtr(stream), stream_getSize(stream) ); + const XP_U8* msgBuf = !!stream ? stream_getPtr(stream) : NULL; + XP_U16 msgLen = !!stream ? stream_getSize(stream) : 0; + (*proc)( closure, topic, msgBuf, msgLen ); } void @@ -314,6 +316,26 @@ dvc_makeMQTTInvites( XW_DUtilCtxt* dutil, XWEnv xwe, stream_destroy( stream, xwe ); } +void +dvc_makeMQTTNukeInvite( XW_DUtilCtxt* dutil, XWEnv xwe, + MsgAndTopicProc proc, void* closure, + const NetLaunchInfo* nli ) +{ + LOG_FUNC(); +#ifdef MQTT_GAMEID_TOPICS + MQTTDevID myID; + dvc_getMQTTDevID( dutil, xwe, &myID ); + XP_UCHAR devTopic[32]; + formatMQTTDevTopic( &myID, devTopic, VSIZE(devTopic) ); + XP_UCHAR gameTopic[64]; + size_t siz = XP_SNPRINTF( gameTopic, VSIZE(gameTopic), + "%s/%X", devTopic, nli->gameID ); + XP_ASSERT( siz < VSIZE(gameTopic) ); + XP_USE(siz); + callProc( proc, closure, gameTopic, NULL ); +#endif +} + /* Ship with == 1, but increase to test */ #define MULTI_MSG_COUNT 1 diff --git a/xwords4/common/device.h b/xwords4/common/device.h index 96d169e9b..5c1f04072 100644 --- a/xwords4/common/device.h +++ b/xwords4/common/device.h @@ -42,6 +42,9 @@ void dvc_makeMQTTInvites( XW_DUtilCtxt* dutil, XWEnv xwe, MsgAndTopicProc proc, void* closure, const MQTTDevID* addressee, const NetLaunchInfo* nli ); +void dvc_makeMQTTNukeInvite( XW_DUtilCtxt* dutil, XWEnv xwe, + MsgAndTopicProc proc, void* closure, + const NetLaunchInfo* nli ); void dvc_makeMQTTMessages( XW_DUtilCtxt* dutil, XWEnv xwe, MsgAndTopicProc proc, void* closure, diff --git a/xwords4/linux/lindutil.c b/xwords4/linux/lindutil.c index 76e1e9dd7..f7eb043db 100644 --- a/xwords4/linux/lindutil.c +++ b/xwords4/linux/lindutil.c @@ -31,6 +31,7 @@ #include "linuxdict.h" #include "cursesmain.h" #include "gtkmain.h" +#include "mqttcon.h" static XP_U32 linux_dutil_getCurSeconds( XW_DUtilCtxt* duc, XWEnv xwe ); static const XP_UCHAR* linux_dutil_getUserString( XW_DUtilCtxt* duc, XWEnv xwe, XP_U16 code ); @@ -129,6 +130,7 @@ linux_dutil_onInviteReceived( XW_DUtilCtxt* duc, XWEnv XP_UNUSED(xwe), } else { inviteReceivedGTK( params->appGlobals, nli ); } + mqttc_onInviteHandled( params, nli ); } static void diff --git a/xwords4/linux/mqttcon.c b/xwords4/linux/mqttcon.c index e88311f8c..95a5ee2a8 100644 --- a/xwords4/linux/mqttcon.c +++ b/xwords4/linux/mqttcon.c @@ -302,6 +302,15 @@ mqttc_send( LaunchParams* params, XP_U32 gameID, return len; } +void +mqttc_onInviteHandled( LaunchParams* params, const NetLaunchInfo* nli ) +{ + LOG_FUNC(); + MQTTConStorage* storage = getStorage( params ); + dvc_makeMQTTNukeInvite( params->dutil, NULL_XWE, + msgAndTopicProc, storage, nli ); +} + void mqttc_notifyGameGone( LaunchParams* params, const MQTTDevID* addressee, XP_U32 gameID ) { diff --git a/xwords4/linux/mqttcon.h b/xwords4/linux/mqttcon.h index a0906ff70..725e5fe2f 100644 --- a/xwords4/linux/mqttcon.h +++ b/xwords4/linux/mqttcon.h @@ -30,6 +30,7 @@ const MQTTDevID* mqttc_getDevID( LaunchParams* params ); const gchar* mqttc_getDevIDStr( LaunchParams* params ); void mqttc_invite( LaunchParams* params, const NetLaunchInfo* nli, const MQTTDevID* mqttInvitee ); +void mqttc_onInviteHandled( LaunchParams* params, const NetLaunchInfo* nli ); XP_S16 mqttc_send( LaunchParams* params, XP_U32 gameID, const XP_U8* buf, XP_U16 len, const MQTTDevID* addressee ); void mqttc_notifyGameGone( LaunchParams* params, const MQTTDevID* addressee, XP_U32 gameID );