From 1755267d55ebaefb46c95a3009bd5b45910c9dad Mon Sep 17 00:00:00 2001 From: ehouse Date: Mon, 29 Dec 2008 01:35:29 +0000 Subject: [PATCH] Add support to gtk app for tranport over "sms", with files containing base64-encoded data as the messages. Make necessary changes to comms. This is the foundation for doing real SMS transport on handhelds. Currently a full robot game works for two gtk clients provided the server is launched first. --- xwords4/common/comms.c | 41 +++++-- xwords4/common/comms.h | 7 ++ xwords4/linux/Makefile | 2 + xwords4/linux/gtkmain.c | 19 ++- xwords4/linux/linuxmain.c | 59 +++++++-- xwords4/linux/linuxsms.c | 245 ++++++++++++++++++++++++++++++++++++++ xwords4/linux/linuxsms.h | 36 ++++++ xwords4/linux/main.h | 15 ++- 8 files changed, 402 insertions(+), 22 deletions(-) create mode 100644 xwords4/linux/linuxsms.c create mode 100644 xwords4/linux/linuxsms.h diff --git a/xwords4/common/comms.c b/xwords4/common/comms.c index cddb1fcf4..7b7499521 100644 --- a/xwords4/common/comms.c +++ b/xwords4/common/comms.c @@ -330,6 +330,11 @@ addrFromStream( CommsAddrRec* addrP, XWStreamCtxt* stream ) addr.u.ip_relay.ipAddr = stream_getU32( stream ); addr.u.ip_relay.port = stream_getU16( stream ); break; + case COMMS_CONN_SMS: + stringFromStreamHere( stream, addr.u.sms.phone, + sizeof(addr.u.sms.phone) ); + addr.u.sms.port = stream_getU16( stream ); + break; default: /* shut up, compiler */ break; @@ -435,13 +440,24 @@ comms_makeFromStream( MPFORMAL XWStreamCtxt* stream, XW_UtilCtxt* util, return comms; } /* comms_makeFromStream */ +#ifdef COMMS_HEARTBEAT +static void +setDoHeartbeat( CommsCtxt* comms ) +{ + CommsConnType conType = comms->addr.conType; + comms->doHeartbeat = XP_FALSE + || COMMS_CONN_IP_DIRECT == conType + || COMMS_CONN_BT == conType + ; +} +#else +# define setDoHeartbeat(c) +#endif + void comms_start( CommsCtxt* comms ) { -#ifdef COMMS_HEARTBEAT - comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR; -#endif - + setDoHeartbeat( comms ); sendConnect( comms ); } /* comms_start */ @@ -502,6 +518,10 @@ addrToStream( XWStreamCtxt* stream, const CommsAddrRec* addrP ) stream_putU32( stream, addr.u.ip_relay.ipAddr ); stream_putU16( stream, addr.u.ip_relay.port ); break; + case COMMS_CONN_SMS: + stringToStream( stream, addr.u.sms.phone ); + stream_putU16( stream, addr.u.sms.port ); + break; } } /* addrToStream */ @@ -583,7 +603,7 @@ comms_setAddr( CommsCtxt* comms, const CommsAddrRec* addr ) XP_MEMCPY( &comms->addr, addr, sizeof(comms->addr) ); #ifdef COMMS_HEARTBEAT - comms->doHeartbeat = comms->addr.conType != COMMS_CONN_IR; + setDoHeartbeat( comms ); #endif sendConnect( comms ); @@ -1063,6 +1083,13 @@ getRecordFor( CommsCtxt* comms, const CommsAddrRec* addr, break; case COMMS_CONN_IR: /* no way to test */ break; + case COMMS_CONN_SMS: /* no way to test */ + if ( ( 0 == XP_MEMCMP( &addr->u.sms.phone, &rec->addr.u.sms.phone, + sizeof(addr->u.sms.phone) ) ) + && addr->u.sms.port == rec->addr.u.sms.port ) { + matched = XP_TRUE; + } + break; case COMMS_CONN_NONE: matched = channelNo == rec->channelNo; break; @@ -1218,8 +1245,8 @@ comms_checkIncomingStream( CommsCtxt* comms, XWStreamCtxt* stream, payloadSize = stream_getSize( stream ) > 0; /* anything left? */ if ( connID == CONN_ID_NONE ) { /* special case: initial message from client */ - rec = validateInitialMessage( comms, payloadSize > 0, addr, senderID, - &channelNo ); + rec = validateInitialMessage( comms, payloadSize > 0, addr, + senderID, &channelNo ); } else if ( comms->connID == connID ) { rec = validateChannelMessage( comms, addr, channelNo, msgID, lastMsgRcd ); diff --git a/xwords4/common/comms.h b/xwords4/common/comms.h index 32e547091..a1cfb66e3 100644 --- a/xwords4/common/comms.h +++ b/xwords4/common/comms.h @@ -39,6 +39,7 @@ typedef enum { ,COMMS_CONN_IP_DIRECT ,COMMS_CONN_RELAY ,COMMS_CONN_BT + ,COMMS_CONN_SMS } CommsConnType; /* WHAT SHOULD THIS BE? Copied from Whiteboard.... PENDING */ @@ -60,6 +61,8 @@ typedef struct XP_BtAddrStr { XP_UCHAR chars[18]; } XP_BtAddrStr; #endif #define MAX_HOSTNAME_LEN 63 +#define MAX_PHONE_LEN 31 + typedef struct CommsAddrRec { CommsConnType conType; @@ -84,6 +87,10 @@ typedef struct CommsAddrRec { XP_UCHAR hostName[MAX_HOSTNAME_LEN + 1]; XP_BtAddr btAddr; } bt; + struct { + XP_UCHAR phone[MAX_PHONE_LEN + 1]; + XP_U16 port; + } sms; } u; } CommsAddrRec; diff --git a/xwords4/linux/Makefile b/xwords4/linux/Makefile index 6c989e39a..9efa16045 100644 --- a/xwords4/linux/Makefile +++ b/xwords4/linux/Makefile @@ -84,6 +84,7 @@ endif # DEFINES += -DXWFEATURE_IR DEFINES += ${BLUETOOTH} DEFINES += -DXWFEATURE_RELAY +DEFINES += -DXWFEATURE_SMS # Support device-to-device connection via UDP, e.g. using wifi on a # LAN or where the host/server isn't behind a firewall. @@ -136,6 +137,7 @@ OBJ = \ $(PLATFORM)/filestream.o \ $(PLATFORM)/linuxbt.o \ $(PLATFORM)/linuxudp.o \ + $(PLATFORM)/linuxsms.o \ $(PLATFORM)/linuxdict.o \ $(PLATFORM)/linuxutl.o \ $(CURSES_OBJS) $(GTK_OBJS) $(MAIN_OBJS) diff --git a/xwords4/linux/gtkmain.c b/xwords4/linux/gtkmain.c index a996fa519..fff79f582 100644 --- a/xwords4/linux/gtkmain.c +++ b/xwords4/linux/gtkmain.c @@ -45,6 +45,7 @@ #include "linuxutl.h" #include "linuxbt.h" #include "linuxudp.h" +#include "linuxsms.h" /* #include "gtkmain.h" */ #include "draw.h" @@ -363,6 +364,12 @@ createOrLoadObjects( GtkAppGlobals* globals ) XP_STRNCPY( addr.u.ip.hostName_ip, params->connInfo.ip.hostName, sizeof(addr.u.ip.hostName_ip) - 1 ); addr.u.ip.port_ip = params->connInfo.ip.port; +#endif +#ifdef XWFEATURE_SMS + } else if ( addr.conType == COMMS_CONN_SMS ) { + XP_STRNCPY( addr.u.sms.phone, params->connInfo.sms.serverPhone, + sizeof(addr.u.sms.phone) - 1 ); + addr.u.sms.port = params->connInfo.sms.port; #endif } @@ -549,6 +556,9 @@ quit( void* XP_UNUSED(dunno), GtkAppGlobals* globals ) #ifdef XWFEATURE_BLUETOOTH linux_bt_close( &globals->cGlobals ); #endif +#ifdef XWFEATURE_SMS + linux_sms_close( &globals->cGlobals ); +#endif #ifdef XWFEATURE_IP_DIRECT linux_udp_close( &globals->cGlobals ); #endif @@ -1617,6 +1627,12 @@ newConnectionInput( GIOChannel *source, } else if ( globals->cGlobals.params->conType == COMMS_CONN_BT ) { nRead = linux_bt_receive( sock, buf, sizeof(buf) ); #endif +#ifdef XWFEATURE_SMS + } else if ( globals->cGlobals.params->conType == COMMS_CONN_SMS ) { + addrp = &addr; + nRead = linux_sms_receive( &globals->cGlobals, sock, + buf, sizeof(buf), addrp ); +#endif #ifdef XWFEATURE_IP_DIRECT } else if ( globals->cGlobals.params->conType == COMMS_CONN_IP_DIRECT ) { addrp = &addr; @@ -1680,7 +1696,8 @@ gtk_socket_changed( void* closure, int oldSock, int newSock, void** storage ) g_io_channel_unref( info->channel ); XP_FREE( globals->cGlobals.params->util->mpool, info ); *storage = NULL; - XP_LOGF( "Removed socket %d from gtk's list of listened-to sockets", oldSock ); + XP_LOGF( "Removed socket %d from gtk's list of listened-to sockets", + oldSock ); } if ( newSock != -1 ) { info = (SockInfo*)XP_MALLOC( globals->cGlobals.params->util->mpool, diff --git a/xwords4/linux/linuxmain.c b/xwords4/linux/linuxmain.c index ca580236b..740a11c27 100644 --- a/xwords4/linux/linuxmain.c +++ b/xwords4/linux/linuxmain.c @@ -45,6 +45,7 @@ #include "linuxmain.h" #include "linuxutl.h" #include "linuxbt.h" +#include "linuxsms.h" #include "linuxudp.h" #include "main.h" #ifdef PLATFORM_NCURSES @@ -186,6 +187,9 @@ usage( char* appName, char* msg ) "\t [-U] # call 'Undo' after game ends\n" #ifdef XWFEATURE_RELAY "\t [-H] # Don't send heartbeats to relay\n" +#endif +#ifdef XWFEATURE_SMS + "\t [-M phone] # Server phone number for SMS\n" #endif "\t [-r name]* # same-process robot\n" "\t [-n name]* # same-process player (no network used)\n" @@ -445,6 +449,16 @@ linux_send( const XP_U8* buf, XP_U16 buflen, comms_getAddr( globals->game.comms, &addr ); linux_udp_open( globals, &addr ); nSent = linux_udp_send( buf, buflen, addrRec, globals ); +#endif +#if defined XWFEATURE_SMS + } else if ( COMMS_CONN_SMS == conType ) { + CommsAddrRec addr; + if ( !addrRec ) { + comms_getAddr( globals->game.comms, &addr ); + addrRec = &addr; + } + nSent = linux_sms_send( globals, buf, buflen, + addrRec->u.sms.phone, addrRec->u.sms.port ); #endif } else { XP_ASSERT(0); @@ -545,23 +559,26 @@ linuxFireTimer( CommonGlobals* cGlobals, XWTimerReason why ) (*proc)( closure, why ); } /* fireTimer */ -#if defined XWFEATURE_BLUETOOTH || defined XWFEATURE_RELAY +#ifndef XWFEATURE_STANDALONE_ONLY static void linux_util_addrChange( XW_UtilCtxt* uc, const CommsAddrRec* XP_UNUSED(oldAddr), const CommsAddrRec* newAddr ) { + CommonGlobals* cGlobals = (CommonGlobals*)uc->closure; if ( 0 ) { #ifdef XWFEATURE_BLUETOOTH } else if ( newAddr->conType == COMMS_CONN_BT ) { - CommonGlobals* cGlobals = (CommonGlobals*)uc->closure; XP_Bool isServer = comms_getIsServer( cGlobals->game.comms ); linux_bt_open( cGlobals, isServer ); #endif #if defined XWFEATURE_IP_DIRECT } else if ( newAddr->conType == COMMS_CONN_IP_DIRECT ) { - CommonGlobals* cGlobals = (CommonGlobals*)uc->closure; linux_udp_open( cGlobals, newAddr ); +#endif +#if defined XWFEATURE_SMS + } else if ( COMMS_CONN_SMS == newAddr->conType ) { + linux_sms_init( cGlobals, newAddr ); #endif } } @@ -625,8 +642,9 @@ main( int argc, char** argv ) int opt; int totalPlayerCount = 0; XP_Bool isServer = XP_FALSE; - char* portNum = "10999"; + char* portNum = NULL; char* hostName = "localhost"; + char* serverPhone = NULL; /* sms */ unsigned int seed = defaultRandomSeed(); LaunchParams mainParams; XP_U16 robotCount = 0; @@ -708,6 +726,9 @@ main( int argc, char** argv ) "h:I" #endif "kKf:ln:Nsd:e:r:b:q:w:Sit:Umvc" +#ifdef XWFEATURE_SMS + "M:" +#endif #ifdef XWFEATURE_RELAY "a:p:C:H" #endif @@ -767,6 +788,13 @@ main( int argc, char** argv ) mainParams.gi.players[mainParams.nLocalPlayers-1].password = (XP_UCHAR*)optarg; break; +#ifdef XWFEATURE_SMS + case 'M': /* SMS phone number */ + XP_ASSERT( COMMS_CONN_NONE == conType ); + serverPhone = optarg; + conType = COMMS_CONN_SMS; + break; +#endif case 'm': /* dumb robot */ mainParams.gi.robotSmartness = DUMB_ROBOT; break; @@ -787,7 +815,7 @@ main( int argc, char** argv ) ++mainParams.info.serverInfo.nRemotePlayers; break; case 'p': - /* could be RELAY or IP_DIRECT */ + /* could be RELAY or IP_DIRECT or SMS */ portNum = optarg; break; case 'r': @@ -908,19 +936,26 @@ main( int argc, char** argv ) #ifdef XWFEATURE_RELAY } else if ( conType == COMMS_CONN_RELAY ) { mainParams.connInfo.relay.relayName = hostName; - - /* convert strings to whatever */ - if ( portNum != NULL ) { - mainParams.connInfo.relay.defaultSendPort = - atoi( portNum ); + if ( NULL == portNum ) { + portNum = "10999"; } + mainParams.connInfo.relay.defaultSendPort = atoi( portNum ); #endif #ifdef XWFEATURE_IP_DIRECT } else if ( conType == COMMS_CONN_IP_DIRECT ) { mainParams.connInfo.ip.hostName = hostName; - if ( portNum != NULL ) { - mainParams.connInfo.ip.port = atoi( portNum ); + if ( NULL == portNum ) { + portNum = "10999"; } + mainParams.connInfo.ip.port = atoi( portNum ); +#endif +#ifdef XWFEATURE_SMS + } else if ( conType == COMMS_CONN_SMS ) { + mainParams.connInfo.sms.serverPhone = serverPhone; + if ( !portNum ) { + portNum = "1"; + } + mainParams.connInfo.sms.port = atoi(portNum); #endif #ifdef XWFEATURE_BLUETOOTH } else if ( conType == COMMS_CONN_BT ) { diff --git a/xwords4/linux/linuxsms.c b/xwords4/linux/linuxsms.c new file mode 100644 index 000000000..030913cdd --- /dev/null +++ b/xwords4/linux/linuxsms.c @@ -0,0 +1,245 @@ +/* -*-mode: C; compile-command: "make -j MEMDEBUG=TRUE";-*- */ +/* + * Copyright 2006-2008 by Eric House (xwords@eehouse.org). All rights + * reserved. + * + * 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. + */ + +#ifdef XWFEATURE_SMS + +#include +#include +#include +#include +#include +#include + +#include "linuxsms.h" + +#define SMS_DIR "/tmp/xw_sms" +#define LOCK_FILE ".lock" + +/* The idea here is to mimic an SMS-based transport using files. We'll use a + * directory in /tmp to hold "messages", in files with names based on phone + * number and port. Servers and clients will listen for changes in that + * directory and "receive" messages when a change is noted to a file with + * their phone number and on the port they listen to. + * + * Server's phone number is known to both server and client and passed on the + * commandline. Client's "phone number" is the PID of the client process. + * When the client sends to the server the phone number is passed in and its + * return (own) number is included in the "message". + * + * If I'm the server, I create an empty file for each port I listen on. (Only + * one now....). Clients will append to that. Likewise, a client creates a + * file that it will listen on. + * + * Data is encoded using the same mechanism so size constraints can be + * checked. + */ + +struct LinSMSData { + XP_UCHAR myPhone[MAX_PHONE_LEN+1]; + XP_UCHAR myQueue[256]; + FILE* lock; + int wd, fd; /* for inotify */ + void* storage; + XP_U16 count; + XP_U16 port; + XP_Bool amServer; +}; + +static void +makeQueuePath( const XP_UCHAR* phone, XP_U16 port, + XP_UCHAR* path, XP_U16 pathlen ) +{ + snprintf( path, pathlen, "%s/%s_%d", SMS_DIR, phone, port ); +} + +static void +lock_queue( LinSMSData* data ) +{ + char lock[256]; + snprintf( lock, sizeof(lock), "%s/%s", data->myQueue, LOCK_FILE ); + FILE* fp = fopen( lock, "w" ); + XP_ASSERT( NULL == data->lock ); + data->lock = fp; +} + +static void +unlock_queue( LinSMSData* data ) +{ + XP_ASSERT( NULL != data->lock ); + fclose( data->lock ); + data->lock = NULL; +} + +void +linux_sms_init( CommonGlobals* globals, const CommsAddrRec* addr ) +{ + LOG_FUNC(); + + LinSMSData* data = globals->smsData; + if ( !data ) { + data = XP_MALLOC( globals->params->util->mpool, sizeof(*data) ); + XP_ASSERT( !!data ); + XP_MEMSET( data, 0, sizeof(*data) ); + globals->smsData = data; + + data->amServer = comms_getIsServer( globals->game.comms ); + + if ( data->amServer ) { + XP_STRNCPY( data->myPhone, addr->u.sms.phone, + sizeof(data->myPhone) ); + } else { + snprintf( data->myPhone, sizeof(data->myPhone), "%.6d", getpid() ); + } + + makeQueuePath( data->myPhone, addr->u.sms.port, + data->myQueue, sizeof(data->myQueue) ); + data->port = addr->u.sms.port; + + XP_LOGF( "creating %s", data->myQueue ); + (void)g_mkdir_with_parents( data->myQueue, 0777 ); + + int fd = inotify_init(); + data->fd = fd; + data->wd = inotify_add_watch( fd, data->myQueue, IN_MODIFY ); + (*globals->socketChanged)( globals, -1, fd, &data->storage ); + } +} /* linux_sms_init */ + +void +linux_sms_close( CommonGlobals* globals ) +{ + LinSMSData* data = globals->smsData; + if ( !!data ) { + XP_FREE( globals->params->util->mpool, data ); + globals->smsData = NULL; + } +} /* linux_sms_close */ + +XP_S16 +linux_sms_send( CommonGlobals* globals, + const XP_U8* buf, XP_U16 buflen, + const XP_UCHAR* phone, XP_U16 port ) +{ + XP_S16 nSent = -1; + LinSMSData* data = globals->smsData; + XP_ASSERT( !!data ); + char path[256]; + + lock_queue( data ); + + makeQueuePath( phone, port, path, sizeof(path) ); + g_mkdir_with_parents( path, 0777 ); /* just in case */ + int len = strlen( path ); + snprintf( &path[len], sizeof(path)-len, "/%d", ++data->count ); + + gchar* str = g_base64_encode( buf, buflen ); + XP_LOGF( "%s: base64 size of message: %d", __func__, strlen(str ) ); + + FILE* fp = fopen( path, "w" ); + XP_ASSERT( !!fp ); + (void)fprintf( fp, "from: %s\n", data->myPhone ); + (void)fprintf( fp, "%s\n", str ); + fclose( fp ); + + unlock_queue( data ); + + g_free( str ); + nSent = buflen; + + LOG_RETURNF( "%d", nSent ); + return nSent; +} /* linux_sms_send */ + +static XP_S16 +decodeAndDelete( LinSMSData* data, const gchar* name, + XP_U8* buf, XP_U16 buflen, CommsAddrRec* addr ) +{ + XP_S16 nRead = -1; + char path[256]; + snprintf( path, sizeof(path), "%s/%s", data->myQueue, name ); + + gchar* contents; + gsize length; + gboolean success = g_file_get_contents( path, &contents, &length, NULL ); + XP_ASSERT( success ); + unlink( path ); + + if ( 0 == strncmp( "from: ", contents, 6 ) ) { + gchar* eol = strstr( contents, "\n" ); + *eol = '\0'; + XP_STRNCPY( addr->u.sms.phone, &contents[6], sizeof(addr->u.sms.phone) ); + ++eol; /* skip NULL */ + + gsize out_len; + guchar* out = g_base64_decode( eol, &out_len ); + if ( out_len <= buflen ) { + XP_MEMCPY( buf, out, out_len ); + nRead = out_len; + addr->conType = COMMS_CONN_SMS; + addr->u.sms.port = data->port; + } + g_free( out ); + } + + g_free( contents ); + + return nRead; +} /* decodeAndDelete */ + +XP_S16 +linux_sms_receive( CommonGlobals* globals, int sock, + XP_U8* buf, XP_U16 buflen, CommsAddrRec* addr ) +{ + XP_S16 nRead = -1; + LinSMSData* data = globals->smsData; + + XP_ASSERT( sock == data->fd ); + + lock_queue( data ); + + /* read required or we'll just get the event again */ + XP_U8 buffer[sizeof(struct inotify_event) + 16]; + (void)read( sock, buffer, sizeof(buffer) ); + + char shortest[256] = { '\0' }; + GDir* dir = g_dir_open( data->myQueue, 0, NULL ); + for ( ; ; ) { + const gchar* name = g_dir_read_name( dir ); + if ( NULL == name ) { + break; + } else if ( 0 == strcmp( name, LOCK_FILE ) ) { + continue; + } + if ( !shortest[0] || 0 < strcmp( shortest, name ) ) { + snprintf( shortest, sizeof(shortest), "%s", name ); + } + } + g_dir_close( dir ); + + if ( !!shortest[0] ) { + nRead = decodeAndDelete( data, shortest, buf, buflen, addr ); + } + + unlock_queue( data ); + + return nRead; +} /* linux_sms_receive */ + +#endif /* XWFEATURE_SMS */ diff --git a/xwords4/linux/linuxsms.h b/xwords4/linux/linuxsms.h new file mode 100644 index 000000000..8dba0f75d --- /dev/null +++ b/xwords4/linux/linuxsms.h @@ -0,0 +1,36 @@ +/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE";-*- */ +/* + * Copyright 2006-2008 by Eric House (xwords@eehouse.org). All rights + * reserved. + * + * 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. + */ +#ifndef _LINUXSMS_H_ +#define _LINUXSMS_H_ + +#ifdef XWFEATURE_SMS + +#include "main.h" + +void linux_sms_init( CommonGlobals* globals, const CommsAddrRec* addr ); +void linux_sms_close( CommonGlobals* globals ); + +XP_S16 linux_sms_send( CommonGlobals* globals, const XP_U8* buf, + XP_U16 buflen, const XP_UCHAR* phone, XP_U16 port ); +XP_S16 linux_sms_receive( CommonGlobals* globals, int sock, + XP_U8* buf, XP_U16 buflen, CommsAddrRec* addr ); + +#endif /* XWFEATURE_SMS */ +#endif /* #ifndef _LINUXSMS_H_ */ diff --git a/xwords4/linux/main.h b/xwords4/linux/main.h index d30161041..d3c770b9d 100644 --- a/xwords4/linux/main.h +++ b/xwords4/linux/main.h @@ -86,6 +86,12 @@ typedef struct LaunchParams { const char* hostName; int port; } ip; +#endif +#ifdef XWFEATURE_SMS + struct { + const char* serverPhone; + int port; + } sms; #endif } connInfo; @@ -104,6 +110,10 @@ typedef XP_Bool (*Acceptor)( int sock, void* ctxt ); typedef void (*AddAcceptorFunc)(int listener, Acceptor func, CommonGlobals* globals, void** storage ); +#ifdef XWFEATURE_SMS +typedef struct LinSMSData LinSMSData; +#endif + struct CommonGlobals { LaunchParams* params; @@ -130,11 +140,12 @@ struct CommonGlobals { #if defined XWFEATURE_IP_DIRECT struct LinUDPStuff* udpStuff; #endif +#ifdef XWFEATURE_SMS + LinSMSData* smsData; +#endif XWTimerProc timerProcs[NUM_TIMERS_PLUS_ONE]; void* timerClosures[NUM_TIMERS_PLUS_ONE]; - - MPSLOT }; #endif