2005-07-06 00:05:37 +02:00
|
|
|
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
|
|
|
/*
|
2011-02-04 14:41:44 +01:00
|
|
|
* Copyright 2005-2011 by Eric House (xwords@eehouse.org). All rights
|
2009-07-30 14:54:17 +02:00
|
|
|
* reserved.
|
2005-07-06 00:05:37 +02:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "assert.h"
|
2009-07-28 07:06:25 +02:00
|
|
|
#include "string.h"
|
2005-07-06 00:05:37 +02:00
|
|
|
#include "states.h"
|
|
|
|
#include "xwrelay_priv.h"
|
|
|
|
|
|
|
|
typedef struct StateTable {
|
|
|
|
XW_RELAY_STATE stateStart;
|
|
|
|
XW_RELAY_EVENT stateEvent;
|
|
|
|
XW_RELAY_ACTION stateAction;
|
|
|
|
XW_RELAY_STATE stateEnd; /* Do I need this? Or does the code that
|
|
|
|
performs the action determine the state? */
|
|
|
|
} StateTable;
|
|
|
|
|
2005-08-02 06:57:13 +02:00
|
|
|
/* Connecting. The problem is that we don't know how many devices to expect.
|
|
|
|
So hosts connect and get a response. Hosts send messages to be forwarded.
|
|
|
|
We may or may not have an ID for the recipient host. If we do, we forward.
|
|
|
|
If we don't, we drop. No big deal. So is there any difference between
|
|
|
|
CONNECTING and CONNECTED? I don't think so. Messages come in and we try
|
|
|
|
to forward. Connection requests come in and we accept them if the host in
|
|
|
|
question is unknown. NOT QUITE. There's a DOS vulnerability there. It's
|
|
|
|
best if we can put the game in a state where others can't connect, if the
|
|
|
|
window where new devices can sign in using a given cookie is fairly small.
|
|
|
|
|
2005-10-02 17:39:38 +02:00
|
|
|
New rules on accepting connections and reconnections:
|
|
|
|
|
2010-09-10 10:30:40 +02:00
|
|
|
- Connect messages contain nPlayersHere (local) and nPlayersTotal params.
|
2005-10-02 17:39:38 +02:00
|
|
|
|
|
|
|
- On connect action, we either note the total expected, or increase the
|
|
|
|
total we have. Ditto on reconnect. On disconnect, we take the departing
|
|
|
|
hosts marbles away from the game.
|
|
|
|
|
|
|
|
- We only accept [re]connections when we're missing players, and we only
|
|
|
|
forward messages when all devices/players are accounted for. There's a
|
|
|
|
notification sent when the last shows up, so devices can send pending
|
|
|
|
messages at that time.
|
|
|
|
|
|
|
|
- There's at least one bug with this scheme: we don't know how many players
|
|
|
|
to expect until the server shows up, so we'll keep accepting clients
|
|
|
|
until that happens. Probably need a config variable that sets an upper
|
|
|
|
bound on the number of players.
|
2005-08-02 06:57:13 +02:00
|
|
|
*/
|
|
|
|
|
2010-07-30 06:04:33 +02:00
|
|
|
static StateTable g_stateTable[] = {
|
2011-06-21 03:13:15 +02:00
|
|
|
{ XWS_EMPTY, XWE_DEVCONNECT, XWA_SEND_CONNRSP, XWS_WAITMORE },
|
2010-09-16 10:53:43 +02:00
|
|
|
{ XWS_WAITMORE, XWE_DEVCONNECT, XWA_SEND_CONNRSP, XWS_WAITMORE },
|
|
|
|
{ XWS_WAITMORE, XWE_GOTONEACK, XWA_NOTEACK, XWS_WAITMORE },
|
|
|
|
{ XWS_WAITMORE, XWE_ACKTIMEOUT, XWA_DROPDEVICE, XWS_WAITMORE },
|
|
|
|
{ XWS_WAITMORE, XWE_ALLHERE, XWA_SENDALLHERE, XWS_ALLCONND },
|
2005-07-06 00:05:37 +02:00
|
|
|
|
2010-09-16 14:39:25 +02:00
|
|
|
{ XWS_WAITMORE, XWE_RECONNECT, XWA_SEND_RERSP, XWS_WAITMORE },
|
|
|
|
{ XWS_WAITMORE, XWE_FORWARDMSG, XWA_FWD, XWS_WAITMORE },
|
2010-09-13 22:49:13 +02:00
|
|
|
|
2010-09-16 14:39:25 +02:00
|
|
|
{ XWS_ALLCONND, XWE_RECONNECT, XWA_SEND_RERSP, XWS_ALLCONND },
|
|
|
|
{ XWS_ALLCONND, XWE_ALLHERE, XWA_NONE, XWS_ALLCONND },
|
2010-09-17 03:59:56 +02:00
|
|
|
{ XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_ALLCONND },
|
2011-06-21 03:13:15 +02:00
|
|
|
{ XWS_ALLCONND, XWE_GOTONEACK, XWA_NONE, XWS_ALLCONND },
|
2010-09-10 10:30:40 +02:00
|
|
|
|
|
|
|
/* { XWS_WAITMORE, XWE_GAMEFULL, XWA_SENDALLHERE, XWS_ALLCONND }, */
|
|
|
|
/* { XWS_WAITMORE, XWE_CHECKFULL, XWA_, XWS_WAITMORE }, */
|
|
|
|
/* { XWS_INITED, XWE_DEVCONNECT, XWA_SEND_NO_ROOM, XWS_DEAD }, */
|
|
|
|
|
|
|
|
/* { XWS_WAITMORE, XWE_DEVCONNECT, XWA_CHECK_FULL, XWS_FULLCHK }, */
|
|
|
|
/* { XWS_FULLCHK, XWE_FULLCHK */
|
2009-12-14 05:10:23 +01:00
|
|
|
|
2010-09-10 10:30:40 +02:00
|
|
|
/* { XWS_ROOMCHK, XWE_HAVE_ROOM, XWA_SEND_GUEST_RSP, XWS_CHK_ALLHERE }, */
|
|
|
|
/* { XWS_ROOMCHK, XWE_TOO_MANY, XWA_SEND_TOO_MANY, XWS_WAITGUESTS }, */
|
|
|
|
|
2010-09-16 10:53:43 +02:00
|
|
|
|
|
|
|
|
2010-09-17 03:59:56 +02:00
|
|
|
/* { XWS_CHK_ALLHERE, XWE_ALLHERE, XWA_SENDALLHERE, XWS_ALLCONND }, */
|
|
|
|
/* { XWS_ALLCONND, XWE_SOMEMISSING, XWA_NONE, XWS_ALLCONND }, */
|
|
|
|
{ XWS_ALLCONND, XWE_ALLGONE, XWA_NONE, XWS_ALLCONND },
|
2005-10-19 05:40:26 +02:00
|
|
|
|
2010-09-17 03:59:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* { XWS_CHK_ALLHERE, XWE_SOMEMISSING, XWA_NONE, XWS_WAITMORE }, */
|
|
|
|
|
2011-06-23 16:12:50 +02:00
|
|
|
{ XWS_ALLCONND, XWE_DISCONN, XWA_DISCONNECT, XWS_WAITMORE },
|
|
|
|
{ XWS_WAITMORE, XWE_DISCONN, XWA_DISCONNECT, XWS_WAITMORE },
|
2009-11-02 02:01:47 +01:00
|
|
|
|
2009-11-09 06:29:06 +01:00
|
|
|
/* EMPTY means have messages to send but no connections. Time out and free
|
|
|
|
memory after a while. BUT: don't I really want to keep these forever and
|
|
|
|
free the oldest ones if memory usage realy does become a problem.
|
|
|
|
There's no problem now! */
|
2010-09-17 03:59:56 +02:00
|
|
|
/* { XWS_WAITMORE, XWE_NOMORESOCKETS, XWA_NONE, XWS_WAITMORE }, */
|
|
|
|
/* { XWS_MISSING, XWE_NOMORESOCKETS, XWA_NOTE_EMPTY, XWS_MSGONLY }, */
|
|
|
|
/* { XWS_MSGONLY, XWE_NOMOREMSGS, XWA_NONE, XWS_DEAD }, */
|
2010-09-10 10:30:40 +02:00
|
|
|
/* { XWS_MSGONLY, XWE_NOMOREMSGS, XWA_NONE, XWS_DEAD }, */
|
2007-11-10 06:41:49 +01:00
|
|
|
|
2011-06-21 03:13:15 +02:00
|
|
|
{ XWS_ANY, XWE_NOMORESOCKETS, XWA_NONE, XWS_EMPTY },
|
|
|
|
{ XWS_ANY, XWE_SHUTDOWN, XWA_SHUTDOWN, XWS_EMPTY },
|
|
|
|
/* drop timeout (unless we're in XWS_WAITMORE; see above) */
|
|
|
|
{ XWS_ANY, XWE_ACKTIMEOUT, XWA_NONE, XWS_SAME },
|
2005-10-02 17:39:38 +02:00
|
|
|
|
2010-09-16 10:53:43 +02:00
|
|
|
/* This doesn't make sense. Can't go straight to ALLCOND if don't have all
|
|
|
|
players/devices. */
|
2011-06-21 03:13:15 +02:00
|
|
|
{ XWS_EMPTY, XWE_RECONNECT, XWA_SEND_RERSP, XWS_WAITMORE },
|
2010-09-16 14:39:25 +02:00
|
|
|
{ XWS_MSGONLY, XWE_RECONNECT, XWA_SEND_RERSP, XWS_WAITMORE },
|
2010-09-11 10:40:40 +02:00
|
|
|
|
2010-09-17 03:59:56 +02:00
|
|
|
/* { XWS_MISSING, XWE_RECONNECT, XWA_SEND_RERSP, XWS_CHK_ALLHERE_2 }, */
|
|
|
|
/* { XWS_CHK_ALLHERE_2, XWE_ALLHERE, XWA_SNDALLHERE_2, XWS_ALLCONND }, */
|
|
|
|
/* { XWS_CHK_ALLHERE_2, XWE_SOMEMISSING, XWA_NONE, XWS_MISSING }, */
|
2005-10-02 17:39:38 +02:00
|
|
|
|
2010-09-10 10:30:40 +02:00
|
|
|
{ XWS_WAITMORE, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_WAITMORE },
|
2010-09-17 03:59:56 +02:00
|
|
|
/* { XWS_ALLCONND, XWE_REMOVESOCKET, XWA_REMOVESOCK_2, XWS_MISSING }, */
|
|
|
|
/* { XWS_MISSING, XWE_REMOVESOCKET, XWA_REMOVESOCK_2, XWS_MISSING }, */
|
2005-10-02 17:39:38 +02:00
|
|
|
|
2007-11-19 00:38:56 +01:00
|
|
|
#ifdef RELAY_HEARTBEAT
|
2009-07-29 06:25:21 +02:00
|
|
|
{ XWS_ALLCONND, XWE_HEARTFAILED, XWA_HEARTDISCONN, XWS_MISSING },
|
2010-09-10 10:30:40 +02:00
|
|
|
{ XWS_WAITMORE, XWE_HEARTFAILED, XWA_HEARTDISCONN, XWS_WAITMORE },
|
2005-10-02 18:08:42 +02:00
|
|
|
{ XWS_MISSING, XWE_HEARTFAILED, XWA_HEARTDISCONN, XWS_MISSING },
|
2005-10-02 17:39:38 +02:00
|
|
|
|
|
|
|
/* Heartbeat arrived */
|
2010-09-10 10:30:40 +02:00
|
|
|
{ XWS_WAITMORE, XWE_HEARTRCVD, XWA_NOTEHEART, XWS_WAITMORE },
|
2009-07-29 06:25:21 +02:00
|
|
|
{ XWS_ALLCONND, XWE_HEARTRCVD, XWA_NOTEHEART, XWS_ALLCONND },
|
2005-10-02 18:08:42 +02:00
|
|
|
{ XWS_MISSING, XWE_HEARTRCVD, XWA_NOTEHEART, XWS_MISSING },
|
2007-11-19 00:38:56 +01:00
|
|
|
#endif
|
2005-10-02 17:39:38 +02:00
|
|
|
|
2011-06-21 03:13:15 +02:00
|
|
|
{ XWS_EMPTY, XWE_DEVGONE, XWA_RMDEV, XWS_EMPTY },
|
2010-11-11 15:40:50 +01:00
|
|
|
{ XWS_WAITMORE, XWE_DEVGONE, XWA_RMDEV, XWS_WAITMORE },
|
|
|
|
/* This should be impossible unless device allows deleting an open/connected
|
|
|
|
game */
|
|
|
|
{ XWS_ALLCONND, XWE_DEVGONE, XWA_RMDEV, XWS_WAITMORE },
|
|
|
|
{ XWS_WAITMORE, XWE_GAMEDEAD, XWA_TELLGAMEDEAD, XWS_WAITMORE },
|
2011-02-04 14:41:44 +01:00
|
|
|
{ XWS_ALLCONND, XWE_GAMEDEAD, XWA_TELLGAMEDEAD, XWS_ALLCONND },
|
2010-11-11 15:40:50 +01:00
|
|
|
|
2005-10-02 17:39:38 +02:00
|
|
|
/* Connect timer */
|
2011-06-21 03:13:15 +02:00
|
|
|
{ XWS_WAITMORE, XWE_CONNTIMER, XWA_TIMERDISCONN, XWS_EMPTY },
|
2010-09-17 03:59:56 +02:00
|
|
|
/* { XWS_MISSING, XWE_CONNTIMER, XWA_NONE, XWS_MISSING }, */
|
2009-07-29 06:25:21 +02:00
|
|
|
{ XWS_ALLCONND, XWE_CONNTIMER, XWA_NONE, XWS_ALLCONND },
|
2005-10-02 17:39:38 +02:00
|
|
|
|
2010-09-10 10:30:40 +02:00
|
|
|
{ XWS_WAITMORE, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_WAITMORE },
|
2010-09-17 03:59:56 +02:00
|
|
|
/* { XWS_ALLCONND, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_MISSING }, */
|
|
|
|
/* { XWS_MISSING, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_MISSING }, */
|
2011-06-21 03:13:15 +02:00
|
|
|
{ XWS_EMPTY, XWE_NOTIFYDISCON, XWA_NOTIFYDISCON, XWS_EMPTY },
|
2005-10-02 17:39:38 +02:00
|
|
|
|
|
|
|
/* This is our bread-n-butter */
|
2009-07-29 06:25:21 +02:00
|
|
|
{ XWS_ALLCONND, XWE_FORWARDMSG, XWA_FWD, XWS_ALLCONND },
|
2010-09-17 03:59:56 +02:00
|
|
|
/* { XWS_MISSING, XWE_FORWARDMSG, XWA_FWD, XWS_MISSING }, */
|
2005-09-02 08:56:34 +02:00
|
|
|
|
2011-06-21 03:13:15 +02:00
|
|
|
{ XWS_EMPTY, XWE_REMOVESOCKET, XWA_REMOVESOCK_1, XWS_EMPTY }
|
2005-07-06 00:05:37 +02:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-11-10 06:41:49 +01:00
|
|
|
bool
|
2005-07-06 00:05:37 +02:00
|
|
|
getFromTable( XW_RELAY_STATE curState, XW_RELAY_EVENT curEvent,
|
|
|
|
XW_RELAY_ACTION* takeAction, XW_RELAY_STATE* nextState )
|
|
|
|
{
|
2007-11-10 06:41:49 +01:00
|
|
|
bool found = false;
|
2005-07-06 00:05:37 +02:00
|
|
|
StateTable* stp = g_stateTable;
|
2007-11-10 06:41:49 +01:00
|
|
|
const StateTable* end = stp + sizeof(g_stateTable)/sizeof(g_stateTable[0]);
|
|
|
|
while ( stp < end ) {
|
2005-10-19 05:40:26 +02:00
|
|
|
if ( stp->stateStart == curState || stp->stateStart == XWS_ANY ) {
|
2005-10-02 18:08:42 +02:00
|
|
|
if ( stp->stateEvent == curEvent || stp->stateEvent == XWE_ANY ) {
|
2005-09-02 08:56:34 +02:00
|
|
|
*takeAction = stp->stateAction;
|
2011-06-21 03:13:15 +02:00
|
|
|
*nextState =
|
|
|
|
stp->stateEnd == XWS_SAME? curState : stp->stateEnd;
|
2007-11-10 06:41:49 +01:00
|
|
|
found = true;
|
|
|
|
break;
|
2005-09-02 08:56:34 +02:00
|
|
|
}
|
2005-07-06 00:05:37 +02:00
|
|
|
}
|
|
|
|
++stp;
|
|
|
|
}
|
|
|
|
|
2007-11-10 06:41:49 +01:00
|
|
|
return found;
|
2005-07-06 00:05:37 +02:00
|
|
|
} /* getFromTable */
|
|
|
|
|
2009-07-28 07:06:25 +02:00
|
|
|
#define CASESTR(s) case s: str = #s; break
|
2005-07-06 00:05:37 +02:00
|
|
|
|
2007-11-13 04:53:10 +01:00
|
|
|
const char*
|
2005-07-06 00:05:37 +02:00
|
|
|
stateString( XW_RELAY_STATE state )
|
|
|
|
{
|
2009-07-28 07:06:25 +02:00
|
|
|
const char* str = NULL;
|
2005-07-06 00:05:37 +02:00
|
|
|
switch( state ) {
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWS_NONE);
|
2005-10-19 05:40:26 +02:00
|
|
|
CASESTR(XWS_ANY);
|
2011-06-21 03:13:15 +02:00
|
|
|
CASESTR(XWS_EMPTY);
|
2010-09-10 10:30:40 +02:00
|
|
|
CASESTR(XWS_WAITMORE);
|
2010-09-14 22:54:52 +02:00
|
|
|
CASESTR(XWS_WAITING_ACKS);
|
2009-07-29 06:25:21 +02:00
|
|
|
CASESTR(XWS_ALLCONND);
|
2010-09-17 03:59:56 +02:00
|
|
|
/* CASESTR(XWS_MISSING); */
|
2010-09-11 10:40:40 +02:00
|
|
|
CASESTR(XWS_MSGONLY);
|
2010-09-17 03:59:56 +02:00
|
|
|
/* CASESTR(XWS_CHK_ALLHERE); */
|
|
|
|
/* CASESTR(XWS_CHK_ALLHERE_2); */
|
|
|
|
/* CASESTR(XWS_CHKCOUNTS_INIT); */
|
|
|
|
/* CASESTR(XWS_ROOMCHK); */
|
2009-07-28 07:06:25 +02:00
|
|
|
default:
|
|
|
|
assert(0);
|
2005-07-06 00:05:37 +02:00
|
|
|
}
|
2009-07-28 07:06:25 +02:00
|
|
|
|
|
|
|
assert( 0 == strncmp( "XWS_", str, 4 ) );
|
|
|
|
str += 4;
|
|
|
|
|
|
|
|
return str;
|
2005-07-06 00:05:37 +02:00
|
|
|
}
|
|
|
|
|
2007-11-13 04:53:10 +01:00
|
|
|
const char*
|
2005-07-06 00:05:37 +02:00
|
|
|
eventString( XW_RELAY_EVENT evt )
|
|
|
|
{
|
2009-07-28 07:06:25 +02:00
|
|
|
const char* str = NULL;
|
2005-07-06 00:05:37 +02:00
|
|
|
switch( evt ) {
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWE_NONE);
|
2010-09-10 10:30:40 +02:00
|
|
|
CASESTR(XWE_DEVCONNECT);
|
2009-12-04 09:03:27 +01:00
|
|
|
CASESTR(XWE_RECONNECT);
|
2010-09-14 22:54:52 +02:00
|
|
|
CASESTR(XWE_GOTONEACK);
|
|
|
|
CASESTR(XWE_GOTLASTACK);
|
|
|
|
CASESTR(XWE_ACKTIMEOUT);
|
2009-12-04 09:03:27 +01:00
|
|
|
CASESTR(XWE_DISCONN);
|
2010-11-11 15:40:50 +01:00
|
|
|
CASESTR(XWE_DEVGONE);
|
|
|
|
CASESTR(XWE_GAMEDEAD);
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWE_FORWARDMSG);
|
2007-11-19 00:38:56 +01:00
|
|
|
#ifdef RELAY_HEARTBEAT
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWE_HEARTRCVD);
|
|
|
|
CASESTR(XWE_HEARTFAILED);
|
2007-11-19 00:38:56 +01:00
|
|
|
#endif
|
|
|
|
CASESTR(XWE_CONNTIMER);
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWE_ANY);
|
|
|
|
CASESTR(XWE_REMOVESOCKET);
|
|
|
|
CASESTR(XWE_NOMORESOCKETS);
|
2009-11-08 22:35:39 +01:00
|
|
|
CASESTR(XWE_NOMOREMSGS);
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWE_NOTIFYDISCON);
|
|
|
|
CASESTR(XWE_ALLHERE);
|
2010-09-17 03:59:56 +02:00
|
|
|
/* CASESTR(XWE_SOMEMISSING); */
|
|
|
|
/* CASESTR(XWE_TOO_MANY); */
|
|
|
|
/* CASESTR(XWE_HAVE_ROOM); */
|
2009-12-14 05:10:23 +01:00
|
|
|
|
2005-10-30 06:07:58 +01:00
|
|
|
CASESTR(XWE_SHUTDOWN);
|
2009-07-28 07:06:25 +02:00
|
|
|
default:
|
|
|
|
assert(0);
|
2005-07-06 00:05:37 +02:00
|
|
|
}
|
2009-07-28 07:06:25 +02:00
|
|
|
return str;
|
2005-07-06 00:05:37 +02:00
|
|
|
}
|
|
|
|
|
2007-11-13 04:53:10 +01:00
|
|
|
const char*
|
2005-10-02 17:39:38 +02:00
|
|
|
actString( XW_RELAY_ACTION act )
|
|
|
|
{
|
2009-07-28 07:06:25 +02:00
|
|
|
const char* str = NULL;
|
2005-10-02 17:39:38 +02:00
|
|
|
switch ( act ) {
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWA_NONE);
|
|
|
|
CASESTR(XWA_SEND_RERSP);
|
|
|
|
CASESTR(XWA_SENDALLHERE);
|
2009-12-04 09:03:27 +01:00
|
|
|
CASESTR(XWA_SEND_NO_ROOM);
|
|
|
|
CASESTR(XWA_SEND_TOO_MANY);
|
|
|
|
CASESTR(XWA_SEND_DUP_ROOM);
|
2010-09-10 10:30:40 +02:00
|
|
|
CASESTR(XWA_SEND_INITRSP);
|
|
|
|
CASESTR(XWA_SEND_CONNRSP);
|
2010-09-14 22:54:52 +02:00
|
|
|
CASESTR(XWA_NOTEACK);
|
|
|
|
/* CASESTR(XWA_ADDDEVICE); */
|
|
|
|
CASESTR(XWA_DROPDEVICE);
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWA_SNDALLHERE_2);
|
|
|
|
CASESTR(XWA_FWD);
|
|
|
|
CASESTR(XWA_NOTEHEART);
|
|
|
|
CASESTR(XWA_TIMERDISCONN);
|
|
|
|
CASESTR(XWA_DISCONNECT);
|
2010-11-11 15:40:50 +01:00
|
|
|
CASESTR(XWA_RMDEV);
|
|
|
|
CASESTR(XWA_TELLGAMEDEAD);
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWA_NOTIFYDISCON);
|
2009-12-14 05:10:23 +01:00
|
|
|
CASESTR(XWA_REMOVESOCK_1);
|
|
|
|
CASESTR(XWA_REMOVESOCK_2);
|
2005-10-02 18:08:42 +02:00
|
|
|
CASESTR(XWA_HEARTDISCONN);
|
2005-10-30 06:07:58 +01:00
|
|
|
CASESTR(XWA_SHUTDOWN);
|
2009-12-14 05:10:23 +01:00
|
|
|
CASESTR(XWA_CHECK_HAVE_ROOM);
|
2009-11-08 22:35:39 +01:00
|
|
|
CASESTR(XWA_NOTE_EMPTY);
|
2009-07-28 07:06:25 +02:00
|
|
|
default:
|
|
|
|
assert(0);
|
2005-10-02 17:39:38 +02:00
|
|
|
}
|
2009-07-28 07:06:25 +02:00
|
|
|
return str;
|
2005-10-02 17:39:38 +02:00
|
|
|
}
|
2005-07-06 00:05:37 +02:00
|
|
|
#undef CASESTR
|