From 16aafccec6e6ab44ea736b5dca800dde53ae82ec Mon Sep 17 00:00:00 2001 From: Eric House Date: Thu, 22 Aug 2013 06:29:20 -0700 Subject: [PATCH] to telnet interface add ability to forget device and to send to one not known (which will make message available next time it connects or via GCM); rename methods. --- xwords4/relay/cref.cpp | 2 +- xwords4/relay/ctrl.cpp | 9 ++++++++- xwords4/relay/devmgr.cpp | 19 +++++++++++++++--- xwords4/relay/devmgr.h | 5 +++-- xwords4/relay/xwrelay.cpp | 41 +++++++++++++++++++++------------------ 5 files changed, 50 insertions(+), 26 deletions(-) diff --git a/xwords4/relay/cref.cpp b/xwords4/relay/cref.cpp index 115659ae6..c9b9f745e 100644 --- a/xwords4/relay/cref.cpp +++ b/xwords4/relay/cref.cpp @@ -948,7 +948,7 @@ CookieRef::increasePlayerCounts( CRefEvent* evt, bool reconn, HostID* hidp, if ( ID_TYPE_NONE != devIDType ) { devID = DBMgr::Get()->RegisterDevice( evt->u.con.devID ); if ( addr->isUDP() ) { - DevMgr::Get()->Remember( devID, addr ); + DevMgr::Get()->rememberDevice( devID, addr ); } } *devIDp = devID; diff --git a/xwords4/relay/ctrl.cpp b/xwords4/relay/ctrl.cpp index 6ef3eea9b..991d66dc0 100644 --- a/xwords4/relay/ctrl.cpp +++ b/xwords4/relay/ctrl.cpp @@ -554,7 +554,14 @@ cmd_devs( int socket, const char* cmd, int argc, gchar** args ) devid ); } found = true; - } else if ( 0 == strcmp( "rm", args[1] ) ) { + } else if ( 0 == strcmp( "rm", args[1] ) && 2 < argc ) { + DevIDRelay devid = (DevIDRelay)strtoul( args[2], NULL, 10 ); + if ( DevMgr::Get()->forgetDevice( devid ) ) { + string_printf( result, "dev %d removed\n", devid ); + } else { + string_printf( result, "dev %d unknown\n", devid ); + } + found = true; } if ( found ) { diff --git a/xwords4/relay/devmgr.cpp b/xwords4/relay/devmgr.cpp index 0129b7732..00aeadc39 100644 --- a/xwords4/relay/devmgr.cpp +++ b/xwords4/relay/devmgr.cpp @@ -36,7 +36,7 @@ DevMgr::Get() } /* Get */ void -DevMgr::Remember( DevIDRelay devid, const AddrInfo::AddrUnion* saddr ) +DevMgr::rememberDevice( DevIDRelay devid, const AddrInfo::AddrUnion* saddr ) { if ( DBMgr::DEVID_NONE != devid ) { gchar* b64 = g_base64_encode( (unsigned char*)&saddr->u.addr, @@ -81,9 +81,9 @@ DevMgr::Remember( DevIDRelay devid, const AddrInfo::AddrUnion* saddr ) } void -DevMgr::Remember( DevIDRelay devid, const AddrInfo* addr ) +DevMgr::rememberDevice( DevIDRelay devid, const AddrInfo* addr ) { - Remember( devid, addr->saddr() ); + rememberDevice( devid, addr->saddr() ); } const AddrInfo::AddrUnion* @@ -102,6 +102,19 @@ DevMgr::get( DevIDRelay devid ) return result; } +bool +DevMgr::forgetDevice( DevIDRelay devid ) +{ + MutexLock ml( &m_mapLock ); + map::iterator iter = m_devAddrMap.find( devid ); + bool found = m_devAddrMap.end() != iter; + if ( found ) { + m_devAddrMap.erase( iter ); + } + return found; +} + + // Print info about every device, ordered by how old they are (how long since // last remembered). Build a separate array with the mutex held, then release // it, so that as much work as possible is done on the calling thread without diff --git a/xwords4/relay/devmgr.h b/xwords4/relay/devmgr.h index 83fdd89e8..a3414d989 100644 --- a/xwords4/relay/devmgr.h +++ b/xwords4/relay/devmgr.h @@ -31,12 +31,13 @@ using namespace std; class DevMgr { public: static DevMgr* Get(); - void Remember( DevIDRelay devid, const AddrInfo::AddrUnion* saddr ); - void Remember( DevIDRelay devid, const AddrInfo* addr ); + void rememberDevice( DevIDRelay devid, const AddrInfo::AddrUnion* saddr ); + void rememberDevice( DevIDRelay devid, const AddrInfo* addr ); const AddrInfo::AddrUnion* get( DevIDRelay devid ); /* Called from ctrl port */ void printDevices( string& str, DevIDRelay devid /* 0 means all */ ); + bool forgetDevice( DevIDRelay devid ); private: diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index f54516120..5b0a6086e 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -649,30 +649,33 @@ post_message( DevIDRelay devid, const char* message, OnMsgAckProc proc, void* procClosure ) { const AddrInfo::AddrUnion* addru = DevMgr::Get()->get( devid ); - bool success = !!addru; - if ( success ) { - AddrInfo addr( addru ); - short len = strlen(message); - short netLen = htons(len); - uint32_t packetID; - uint8_t buf[1 + sizeof(netLen) + len]; - XWRelayReg cmd = XWPDEV_ALERT; - buf[0] = cmd; - memcpy( &buf[1], &netLen, sizeof(netLen) ); - memcpy( &buf[1 + sizeof(netLen)], message, len ); + bool canSendNow = !!addru; + short len = strlen( message ); + short netLen = htons( len ); + uint8_t buf[1 + sizeof(netLen) + len]; + XWRelayReg cmd = XWPDEV_ALERT; + buf[0] = cmd; + memcpy( &buf[1], &netLen, sizeof(netLen) ); + memcpy( &buf[1 + sizeof(netLen)], message, len ); - bool sent = send_via_udp( &addr, &packetID, cmd, &buf[1], - VSIZE(buf)-1, NULL ); + bool sent = false; + if ( canSendNow ) { + AddrInfo addr( addru ); + uint32_t packetID; + + sent = send_via_udp( &addr, &packetID, cmd, &buf[1], + VSIZE(buf)-1, NULL ); if ( sent ) { MsgClosure* mc = new MsgClosure( devid, buf, VSIZE(buf), proc, procClosure ); UDPAckTrack::setOnAck( onPostedMsgAcked, packetID, (void*)mc ); - } else { - DBMgr::Get()->StoreMessage( devid, (const unsigned char*)buf, - VSIZE(buf) ); } } - return success; + if ( !sent ) { + DBMgr::Get()->StoreMessage( devid, (const unsigned char*)buf, + VSIZE(buf) ); + } + return sent; } /* A CONNECT message from a device gives us the hostID and socket we'll @@ -1405,7 +1408,7 @@ registerDevice( const DevID* devID, const AddrInfo* addr, int clientVers, &maxInterval, sizeof(maxInterval), NULL ); // Map the address to the devid for future sending purposes. - DevMgr::Get()->Remember( relayID, addr ); + DevMgr::Get()->rememberDevice( relayID, addr ); } } @@ -1558,7 +1561,7 @@ handle_udp_packet( UdpThreadClosure* utc ) ptr += idLen; const AddrInfo* addr = utc->addr(); - DevMgr::Get()->Remember( devID.asRelayID(), addr ); + DevMgr::Get()->rememberDevice( devID.asRelayID(), addr ); if ( XWPDEV_RQSTMSGS == header.cmd ) { retrieveMessages( devID, addr );