From e88af19e0a1976daf24d2c296eb7d43d960ccd8f Mon Sep 17 00:00:00 2001
From: Andy2 <andy2@trand>
Date: Wed, 10 Aug 2011 18:28:34 -0700
Subject: [PATCH] toward the ability to send replies to messages received in
 background without user having to open the game, which will e.g. allow a host
 to assign tiles, or a robot to move, without the phone's owner noticing
 there's a message.  This is on a branch because it may never work.

---
 xwords4/android/XWords4/jni/xportwrapper.c | 13 +++++
 xwords4/android/XWords4/jni/xwjni.c        |  1 +
 xwords4/common/comms.c                     | 64 ++++++++++++++++------
 xwords4/common/comms.h                     |  3 +
 4 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/xwords4/android/XWords4/jni/xportwrapper.c b/xwords4/android/XWords4/jni/xportwrapper.c
index 1077de037..10ba9402a 100644
--- a/xwords4/android/XWords4/jni/xportwrapper.c
+++ b/xwords4/android/XWords4/jni/xportwrapper.c
@@ -111,6 +111,18 @@ 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,
+                      const XP_UCHAR* relayID, void* closure )
+{
+    LOG_FUNC();
+    AndTransportProcs* aprocs = (AndTransportProcs*)closure;
+    if ( NULL != aprocs && NULL != aprocs->jxport ) {
+    }
+    LOG_RETURNF( "%s", "false" );
+    return XP_FALSE;
+}
+
 static void
 and_xport_relayError( void* closure, XWREASON relayErr )
 {
@@ -148,6 +160,7 @@ makeXportProcs( MPFORMAL JNIEnv** envp, jobject jxport )
     aprocs->tp.rstatus = and_xport_relayStatus;
     aprocs->tp.rconnd = and_xport_relayConnd;
     aprocs->tp.rerror = and_xport_relayError;
+    aprocs->tp.sendNoConn = and_xport_sendNoConn;
     aprocs->tp.closure = aprocs;
 
     return (TransportProcs*)aprocs;
diff --git a/xwords4/android/XWords4/jni/xwjni.c b/xwords4/android/XWords4/jni/xwjni.c
index 572a86fb8..36d214a6b 100644
--- a/xwords4/android/XWords4/jni/xwjni.c
+++ b/xwords4/android/XWords4/jni/xwjni.c
@@ -1013,6 +1013,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1receiveMessage
         ServerCtxt* server = state->game.server;
         server_do( server );    /* in case work's pending */
         (void)server_receiveMessage( server, stream );
+        server_do( server );    /* in case MORE work's pending */
     }
 
     stream_destroy( stream );
diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c
index 9d2f2aabf..ea3db896d 100644
--- a/xwords4/common/comms.c
+++ b/xwords4/common/comms.c
@@ -175,6 +175,8 @@ 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 );
+static XP_Bool sendNoConn( const CommsCtxt* comms, 
+                           const MsgQueueElem* elem, XWHostID destID );
 static XWHostID getDestID( CommsCtxt* comms, XP_PlayerAddr channelNo );
 static void set_reset_timer( CommsCtxt* comms );
 # ifdef DEBUG
@@ -797,25 +799,32 @@ comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr )
 } /* comms_setAddr */
 
 #ifdef XWFEATURE_RELAY
+static XP_Bool
+haveRelayID( const CommsCtxt* comms )
+{
+    XP_Bool result = 0 != comms->r.connName[0]
+        && comms->r.myHostID != HOST_ID_NONE;
+    return result;
+}
+
+static XP_Bool
+formatRelayID( const CommsCtxt* comms, XWHostID hostID,
+               XP_UCHAR* buf, XP_U16* lenp )
+{
+    XP_U16 strln = 1 + XP_SNPRINTF( buf, *lenp, "%s/%d", 
+                                    comms->r.connName, hostID );
+    XP_ASSERT( *lenp >= strln );
+    *lenp = strln;
+    return XP_TRUE;
+}
+
+/* Get *my* "relayID", a combo of connname and host id */
 XP_Bool
 comms_getRelayID( const CommsCtxt* comms, XP_UCHAR* buf, XP_U16* lenp )
 {
-    XP_Bool success = comms->r.connName[0] != 0;
-    if ( success ) {
-        XP_U16 len = sizeof( comms->r.connName ) + 16;
-        XP_UCHAR local[len];
-        XP_SNPRINTF( local, sizeof(local), "%s/%d", 
-                     comms->r.connName, comms->r.myHostID );
-        XP_U16 strln = XP_STRLEN(local);
-        success = *lenp >= strln;
-        if ( success ) {
-            *lenp = strln;
-            XP_MEMCPY( buf, local, strln );
-            XP_LOGF( "%s: keysize=%d", __func__, strln );
-        }
-    }
-    LOG_RETURNF( "%d", success );
-    return success;
+    XP_Bool result = haveRelayID( comms )
+        && formatRelayID( comms, comms->r.myHostID, buf, lenp );
+    return result;
 }
 #endif
 
@@ -1117,8 +1126,10 @@ sendMsg( CommsCtxt* comms, MsgQueueElem* elem )
     if ( 0 ) {
 #ifdef XWFEATURE_RELAY
     } else if ( conType == COMMS_CONN_RELAY ) {
-        if ( comms->r.relayState >= COMMS_RELAYSTATE_CONNECTED ) {
-            XWHostID destID = getDestID( comms, channelNo );
+        XWHostID destID = getDestID( comms, channelNo );
+        if ( haveRelayID( comms ) && sendNoConn( comms, elem, destID ) ) {
+            /* do nothing */
+        } else if ( comms->r.relayState >= COMMS_RELAYSTATE_CONNECTED ) {
             if ( send_via_relay( comms, XWRELAY_MSG_TORELAY, destID, 
                                  elem->msg, elem->len ) ){
                 result = elem->len;
@@ -2121,6 +2132,23 @@ send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID,
     return success;
 } /* send_via_relay */
 
+static XP_Bool
+sendNoConn( const CommsCtxt* comms, const MsgQueueElem* elem, XWHostID destID )
+{
+    LOG_FUNC();
+    XP_Bool success = XP_FALSE;
+
+    XP_UCHAR relayID[64];
+    XP_U16 len = sizeof(relayID);
+    success = NULL != comms->procs.sendNoConn
+        && formatRelayID( comms, destID, relayID, &len )
+        && (*comms->procs.sendNoConn)( elem->msg, elem->len, relayID,
+                                       comms->procs.closure );
+
+    LOG_RETURNF( "%d", success );
+    return success;
+}
+
 /* Send a CONNECT message to the relay.  This opens up a connection to the
  * relay, and tells it our hostID and cookie so that it can associatate it
  * with a socket.  In the CONNECT_RESP we should get back what?
diff --git a/xwords4/common/comms.h b/xwords4/common/comms.h
index 1abf90ae9..c00725642 100644
--- a/xwords4/common/comms.h
+++ b/xwords4/common/comms.h
@@ -124,6 +124,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,
+                                    const XP_UCHAR* relayID, void* closure );
 #endif
 
 typedef struct _TransportProcs {
@@ -135,6 +137,7 @@ typedef struct _TransportProcs {
     RelayStatusProc rstatus;
     RelayConndProc rconnd;
     RelayErrorProc rerror;
+    RelayNoConnProc sendNoConn;
 #endif
     void* closure;
 } TransportProcs;