From 87517edd6fa47e5542c433ba1223708907cb57f1 Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 30 Sep 2015 06:50:04 -0700 Subject: [PATCH] fix counting of messages sent by "Resend messages" menuitem: actually count them, and do so based on new msgNo passed from comms that's concatenation of channelNo and msgID so that duplicates (over multiple transports) aren't counted twice. --- xwords4/android/XWords4/jni/xportwrapper.c | 22 +++++---- .../eehouse/android/xw4/CommsTransport.java | 4 +- .../org/eehouse/android/xw4/MultiMsgSink.java | 27 ++++++++--- .../android/xw4/jni/TransportProcs.java | 4 +- xwords4/common/comms.c | 48 ++++++++++++------- xwords4/common/comms.h | 4 +- xwords4/linux/cursesmain.c | 1 + xwords4/linux/gtkboard.c | 5 +- xwords4/linux/linuxmain.c | 6 ++- xwords4/linux/linuxmain.h | 2 +- 10 files changed, 80 insertions(+), 43 deletions(-) diff --git a/xwords4/android/XWords4/jni/xportwrapper.c b/xwords4/android/XWords4/jni/xportwrapper.c index b9d60c108..6be6482bf 100644 --- a/xwords4/android/XWords4/jni/xportwrapper.c +++ b/xwords4/android/XWords4/jni/xportwrapper.c @@ -66,15 +66,16 @@ and_xport_getFlags( void* closure ) } static XP_S16 -and_xport_send( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addr, - CommsConnType conType, XP_U32 gameID, void* closure ) +and_xport_send( const XP_U8* buf, XP_U16 len, const XP_UCHAR* msgNo, + const CommsAddrRec* addr, CommsConnType conType, + XP_U32 gameID, void* closure ) { jint result = -1; LOG_FUNC(); AndTransportProcs* aprocs = (AndTransportProcs*)closure; if ( NULL != aprocs->jxport ) { JNIEnv* env = ENVFORME( aprocs->ti ); - const char* sig = "([BL" PKG_PATH("jni/CommsAddrRec") + const char* sig = "([BLjava/lang/String;L" PKG_PATH("jni/CommsAddrRec") ";L" PKG_PATH("jni/CommsAddrRec$CommsConnType") ";I)I"; jmethodID mid = getMethodID( env, aprocs->jxport, "transportSend", sig ); @@ -83,15 +84,15 @@ and_xport_send( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addr, jobject jaddr = makeJAddr( env, addr ); jobject jConType = intToJEnum(env, conType, PKG_PATH("jni/CommsAddrRec$CommsConnType")); + jstring jMsgNo = !!msgNo ? (*env)->NewStringUTF( env, msgNo ) : NULL; result = (*env)->CallIntMethod( env, aprocs->jxport, mid, - jbytes, jaddr, jConType, gameID ); - deleteLocalRefs( env, jaddr, jbytes, jConType, DELETE_NO_REF ); + jbytes, jMsgNo, jaddr, jConType, gameID ); + deleteLocalRefs( env, jaddr, jbytes, jMsgNo, jConType, DELETE_NO_REF ); } LOG_RETURNF( "%d", result ); return result; } - static void and_xport_relayStatus( void* closure, CommsRelayState newState ) { @@ -126,7 +127,7 @@ and_xport_relayConnd( void* closure, XP_UCHAR* const room, XP_Bool reconnect, } static XP_Bool -and_xport_sendNoConn( const XP_U8* buf, XP_U16 len, +and_xport_sendNoConn( const XP_U8* buf, XP_U16 len, const XP_UCHAR* msgNo, const XP_UCHAR* relayID, void* closure ) { jboolean result = false; @@ -134,14 +135,15 @@ and_xport_sendNoConn( const XP_U8* buf, XP_U16 len, if ( NULL != aprocs && NULL != aprocs->jxport ) { JNIEnv* env = ENVFORME( aprocs->ti ); - const char* sig = "([BLjava/lang/String;)Z"; + const char* sig = "([BLjava/lang/String;Ljava/lang/String;)Z"; jmethodID mid = getMethodID( env, aprocs->jxport, "relayNoConnProc", sig ); jbyteArray jbytes = makeByteArray( env, len, (jbyte*)buf ); jstring jRelayID = (*env)->NewStringUTF( env, relayID ); + jstring jMsgNo = !!msgNo ? (*env)->NewStringUTF( env, msgNo ) : NULL; result = (*env)->CallBooleanMethod( env, aprocs->jxport, mid, - jbytes, jRelayID ); - deleteLocalRefs( env, jbytes, jRelayID, DELETE_NO_REF ); + jbytes, jMsgNo, jRelayID ); + deleteLocalRefs( env, jbytes, jRelayID, jMsgNo, DELETE_NO_REF ); } LOG_RETURNF( "%d", result ); return result; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java index 8f529d47c..e092f5d5b 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/CommsTransport.java @@ -356,7 +356,7 @@ public class CommsTransport implements TransportProcs, public int getFlags() { return COMMS_XPORT_FLAGS_NONE; } - public int transportSend( byte[] buf, CommsAddrRec addr, + public int transportSend( byte[] buf, String msgNo, CommsAddrRec addr, CommsConnType conType, int gameID ) { DbgUtils.logdf( "CommsTransport.transportSend(len=%d, typ=%s)", @@ -429,7 +429,7 @@ public class CommsTransport implements TransportProcs, m_tpHandler.tpmRelayErrorProc( relayErr ); } - public boolean relayNoConnProc( byte[] buf, String relayID ) + public boolean relayNoConnProc( byte[] buf, String msgNo, String relayID ) { Assert.fail(); return false; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiMsgSink.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiMsgSink.java index 2d73b5305..91f8b5242 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiMsgSink.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/MultiMsgSink.java @@ -21,8 +21,10 @@ package org.eehouse.android.xw4; import android.content.Context; -import java.util.HashMap; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; import junit.framework.Assert; @@ -32,7 +34,9 @@ import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; public class MultiMsgSink implements TransportProcs { private long m_rowid; private Context m_context; - private int m_nSent = 0; + // Use set to count so message sent over both BT and Relay is counted only + // once. + private Set m_sentSet = new HashSet(); public MultiMsgSink( Context context, long rowid ) { @@ -70,15 +74,15 @@ public class MultiMsgSink implements TransportProcs { public int numSent() { - return m_nSent; + return m_sentSet.size(); } /***** TransportProcs interface *****/ public int getFlags() { return COMMS_XPORT_FLAGS_HASNOCONN; } - public int transportSend( byte[] buf, CommsAddrRec addr, CommsConnType typ, - int gameID ) + public int transportSend( byte[] buf, String msgNo, CommsAddrRec addr, + CommsConnType typ, int gameID ) { int nSent = -1; switch ( typ ) { @@ -97,6 +101,10 @@ public class MultiMsgSink implements TransportProcs { } DbgUtils.logf( "MultiMsgSink.transportSend(): sent %d via %s", nSent, typ.toString() ); + if ( 0 < nSent ) { + DbgUtils.logdf( "MultiMsgSink.transportSend: adding %s", msgNo ); + m_sentSet.add( msgNo ); + } return nSent; } @@ -114,11 +122,16 @@ public class MultiMsgSink implements TransportProcs { { } - public boolean relayNoConnProc( byte[] buf, String relayID ) + public boolean relayNoConnProc( byte[] buf, String msgNo, String relayID ) { // Assert.fail(); int nSent = RelayService.sendNoConnPacket( m_context, getRowID(), relayID, buf ); - return buf.length == nSent; + boolean success = buf.length == nSent; + if ( success ) { + DbgUtils.logdf( "MultiMsgSink.relayNoConnProc: adding %s", msgNo ); + m_sentSet.add( msgNo ); + } + return success; } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/TransportProcs.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/TransportProcs.java index 4d228f276..6810f4809 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/TransportProcs.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/TransportProcs.java @@ -28,7 +28,7 @@ public interface TransportProcs { public static final int COMMS_XPORT_FLAGS_HASNOCONN = 1; int getFlags(); - int transportSend( byte[] buf, CommsAddrRec addr, + int transportSend( byte[] buf, String msgNo, CommsAddrRec addr, CommsConnType conType, int gameID ); enum CommsRelayState { COMMS_RELAYSTATE_UNCONNECTED @@ -61,7 +61,7 @@ public interface TransportProcs { }; void relayErrorProc( XWRELAY_ERROR relayErr ); - boolean relayNoConnProc( byte[] buf, String relayID ); + boolean relayNoConnProc( byte[] buf, String msgNo, String relayID ); public interface TPMsgHandler { public void tpmRelayConnd( String room, int devOrder, boolean allHere, diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index 2a04068a7..7f5755d44 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -207,7 +207,8 @@ static XP_U16 makeFlags( const CommsCtxt* comms ); static XP_Bool relayConnect( CommsCtxt* comms ); static void relayDisconnect( CommsCtxt* comms ); static XP_Bool send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, - XWHostID destID, void* data, int dlen ); + XWHostID destID, void* data, int dlen, + const XP_UCHAR* msgNo ); static XP_Bool sendNoConn( CommsCtxt* comms, const MsgQueueElem* elem, XWHostID destID ); static XWHostID getDestID( CommsCtxt* comms, XP_PlayerAddr channelNo ); @@ -239,7 +240,7 @@ static void setHeartbeatTimer( CommsCtxt* comms ); static XP_S16 send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType msgTyp, XP_PlayerAddr channelNo, CommsConnType typ, - void* data, int dlen ); + void* data, int dlen, const XP_UCHAR* msgNo ); #endif #if defined COMMS_HEARTBEAT || defined XWFEATURE_COMMSACK @@ -776,7 +777,7 @@ sendConnect( CommsCtxt* comms, XP_Bool breakExisting ) case COMMS_CONN_BT: case COMMS_CONN_IP_DIRECT: /* This will only work on host side when there's a single guest! */ - (void)send_via_bt_or_ip( comms, BTIPMSG_RESET, CHANNEL_NONE, typ, NULL, 0 ); + (void)send_via_bt_or_ip( comms, BTIPMSG_RESET, CHANNEL_NONE, typ, NULL, 0, NULL ); (void)comms_resendAll( comms, XP_FALSE ); break; #endif @@ -999,6 +1000,13 @@ comms_formatRelayID( const CommsCtxt* comms, XP_U16 indx, return success; } +static void +formatMsgNo( const MsgQueueElem* elem, XP_UCHAR* buf, XP_U16 len ) +{ + XP_SNPRINTF( buf, len, "%d:%d", elem->channelNo & CHANNEL_MASK, + elem->msgID ); +} + /* Get *my* "relayID", a combo of connname and host id */ XP_Bool comms_getRelayID( const CommsCtxt* comms, XP_UCHAR* buf, XP_U16* lenp ) @@ -1384,8 +1392,10 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem ) /* do nothing */ nSent = elem->len; } else if ( comms->rr.relayState >= COMMS_RELAYSTATE_CONNECTED ) { + XP_UCHAR msgNo[16]; + formatMsgNo( elem, msgNo, sizeof(msgNo) ); if ( send_via_relay( comms, XWRELAY_MSG_TORELAY, destID, - elem->msg, elem->len ) ){ + elem->msg, elem->len, msgNo ) ){ nSent = elem->len; } } else { @@ -1421,8 +1431,10 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem ) XP_ASSERT( !!comms->procs.send ); XP_U32 gameid = gameID( comms ); logAddr( comms, &addr, __func__ ); - nSent = (*comms->procs.send)( elem->msg, elem->len, &addr, typ, - gameid, comms->procs.closure ); + XP_UCHAR msgNo[16]; + formatMsgNo( elem, msgNo, sizeof(msgNo) ); + nSent = (*comms->procs.send)( elem->msg, elem->len, msgNo, &addr, + typ, gameid, comms->procs.closure ); break; } } /* switch */ @@ -1451,7 +1463,8 @@ static void send_ack( CommsCtxt* comms ) { LOG_FUNC(); - (void)send_via_relay( comms, XWRELAY_ACK, comms->rr.myHostID, NULL, 0 ); + (void)send_via_relay( comms, XWRELAY_ACK, comms->rr.myHostID, NULL, 0, + NULL ); } XP_S16 @@ -2398,7 +2411,7 @@ p_comms_timerFired( void* closure, XWTimerReason XP_UNUSED_DBG(why) ) } else if ( (comms->addr.conType == COMMS_CONN_RELAY ) && (comms->rr.heartbeat != HEARTBEAT_NONE) ) { (void)send_via_relay( comms, XWRELAY_HEARTBEAT, HOST_ID_NONE, - NULL, 0 ); + NULL, 0, NULL ); /* No need to reset timer. send_via_relay does that. */ #endif #ifdef COMMS_HEARTBEAT @@ -2956,7 +2969,7 @@ relay_msg_to_stream( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID, static XP_Bool send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID, - void* data, int dlen ) + void* data, int dlen, const XP_UCHAR* msgNo ) { XP_Bool success = XP_FALSE; if ( comms_getAddrDisabled( comms, COMMS_CONN_RELAY, XP_TRUE ) ) { @@ -2977,8 +2990,9 @@ send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID, comms_getAddr( comms, &addr ); XP_LOGF( "%s: passing %d bytes to sendproc", __func__, len ); - result = (*comms->procs.send)( stream_getPtr(tmpStream), len, &addr, - COMMS_CONN_RELAY, gameID(comms), + result = (*comms->procs.send)( stream_getPtr(tmpStream), len, + msgNo, &addr, COMMS_CONN_RELAY, + gameID(comms), comms->procs.closure ); success = result == len; if ( success ) { @@ -3009,8 +3023,10 @@ sendNoConn( CommsCtxt* comms, const MsgQueueElem* elem, XWHostID destID ) if ( NULL != stream ) { XP_U16 len = stream_getSize( stream ); if ( 0 < len ) { + XP_UCHAR msgNo[16]; + formatMsgNo( elem, msgNo, sizeof(msgNo) ); success = (*comms->procs.sendNoConn)( stream_getPtr( stream ), - len, relayID, + len, msgNo, relayID, comms->procs.closure ); } stream_destroy( stream ); @@ -3034,7 +3050,7 @@ relayConnect( CommsCtxt* comms ) comms->rr.connecting = XP_TRUE; success = send_via_relay( comms, comms->rr.connName[0]? XWRELAY_GAME_RECONNECT : XWRELAY_GAME_CONNECT, - comms->rr.myHostID, NULL, 0 ); + comms->rr.myHostID, NULL, 0, NULL ); comms->rr.connecting = XP_FALSE; } return success; @@ -3044,7 +3060,7 @@ relayConnect( CommsCtxt* comms ) #if defined XWFEATURE_IP_DIRECT || defined XWFEATURE_DIRECTIP static XP_S16 send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType msgTyp, XP_PlayerAddr channelNo, - CommsConnType typ, void* data, int dlen ) + CommsConnType typ, void* data, int dlen, const XP_UCHAR* msgNo ) { XP_S16 nSent; XP_U8* buf; @@ -3060,7 +3076,7 @@ send_via_bt_or_ip( CommsCtxt* comms, BTIPMsgType msgTyp, XP_PlayerAddr channelNo XP_MEMCPY( &buf[1], data, dlen ); } - nSent = (*comms->procs.send)( buf, dlen+1, addr, typ, gameID(comms), + nSent = (*comms->procs.send)( buf, dlen+1, msgNo, addr, typ, gameID(comms), comms->procs.closure ); XP_FREE( comms->mpool, buf ); @@ -3080,7 +3096,7 @@ relayDisconnect( CommsCtxt* comms ) if ( addr_hasType( &comms->addr, COMMS_CONN_RELAY ) ) { if ( comms->rr.relayState > COMMS_RELAYSTATE_CONNECT_PENDING ) { (void)send_via_relay( comms, XWRELAY_GAME_DISCONNECT, HOST_ID_NONE, - NULL, 0 ); + NULL, 0, NULL ); } set_relay_state( comms, COMMS_RELAYSTATE_UNCONNECTED ); } diff --git a/xwords4/common/comms.h b/xwords4/common/comms.h index 877076e83..f63f0c70d 100644 --- a/xwords4/common/comms.h +++ b/xwords4/common/comms.h @@ -112,6 +112,7 @@ typedef struct _CommsAddrRec { } CommsAddrRec; typedef XP_S16 (*TransportSend)( const XP_U8* buf, XP_U16 len, + const XP_UCHAR* msgNo, const CommsAddrRec* addr, CommsConnType conType, XP_U32 gameID, void* closure ); @@ -126,7 +127,8 @@ typedef void (*RelayConndProc)( void* closure, XP_UCHAR* const room, XP_U16 devOrder, /* 1 means created room, etc. */ XP_Bool allHere, XP_U16 nMissing ); typedef void (*RelayErrorProc)( void* closure, XWREASON relayErr ); -typedef XP_Bool (*RelayNoConnProc)( const XP_U8* buf, XP_U16 len, +typedef XP_Bool (*RelayNoConnProc)( const XP_U8* buf, XP_U16 len, + const XP_UCHAR* msgNo, const XP_UCHAR* relayID, void* closure ); #endif diff --git a/xwords4/linux/cursesmain.c b/xwords4/linux/cursesmain.c index 3a538baaf..df723ab42 100644 --- a/xwords4/linux/cursesmain.c +++ b/xwords4/linux/cursesmain.c @@ -1588,6 +1588,7 @@ positionSizeStuff( CursesAppGlobals* globals, int width, int height ) static XP_Bool relay_sendNoConn_curses( const XP_U8* msg, XP_U16 len, + const XP_UCHAR* XP_UNUSED(msgNo), const XP_UCHAR* relayID, void* closure ) { CursesAppGlobals* globals = (CursesAppGlobals*)closure; diff --git a/xwords4/linux/gtkboard.c b/xwords4/linux/gtkboard.c index e8120828f..f168c72cf 100644 --- a/xwords4/linux/gtkboard.c +++ b/xwords4/linux/gtkboard.c @@ -410,8 +410,9 @@ relay_error_gtk( void* closure, XWREASON relayErr ) } static XP_Bool -relay_sendNoConn_gtk( const XP_U8* msg, XP_U16 len, const XP_UCHAR* relayID, - void* closure ) +relay_sendNoConn_gtk( const XP_U8* msg, XP_U16 len, + const XP_UCHAR* XP_UNUSED(msgNo), + const XP_UCHAR* relayID, void* closure ) { GtkGameGlobals* globals = (GtkGameGlobals*)closure; XP_Bool success = XP_FALSE; diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index 44366033f..21d742251 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -1234,9 +1234,11 @@ linux_reset( void* closure ) #endif XP_S16 -linux_send( const XP_U8* buf, XP_U16 buflen, const CommsAddrRec* addrRec, - CommsConnType conType, XP_U32 gameID, void* closure ) +linux_send( const XP_U8* buf, XP_U16 buflen, const XP_UCHAR* msgNo, + const CommsAddrRec* addrRec, CommsConnType conType, XP_U32 gameID, + void* closure ) { + XP_LOGF( "%s(mid=%s)", __func__, msgNo ); XP_S16 nSent = -1; CommonGlobals* cGlobals = (CommonGlobals*)closure; diff --git a/xwords4/linux/linuxmain.h b/xwords4/linux/linuxmain.h index 29c5d5f7c..5f902c810 100644 --- a/xwords4/linux/linuxmain.h +++ b/xwords4/linux/linuxmain.h @@ -36,7 +36,7 @@ typedef struct LinuxBMStruct { } LinuxBMStruct; int initListenerSocket( int port ); -XP_S16 linux_send( const XP_U8* buf, XP_U16 buflen, +XP_S16 linux_send( const XP_U8* buf, XP_U16 buflen, const XP_UCHAR* msgNo, const CommsAddrRec* addrRec, CommsConnType conType, XP_U32 gameID, void* closure ); #ifndef XWFEATURE_STANDALONE_ONLY