Start adding bt support to linux port. Required removing assumptions

that all connectivity was with relay and over streaming sockets (since
BT is using l2cap's datagram-style sockets.)  With this checkin, a full
robot-vs-robot game is possible with palm as host and linux as client.
Linux as host isn't started yet.
This commit is contained in:
ehouse 2006-08-26 21:15:20 +00:00
parent 7d48f2e430
commit a605fd4d49
8 changed files with 424 additions and 61 deletions

View file

@ -59,6 +59,9 @@ DEFINES += -DFEATURE_TRAY_EDIT
#DEFINES += -DDRAW_WITH_PRIMITIVES
DEFINES += -DBEYOND_IR
# Bluetooth support
DEFINES += -DXWFEATURE_BLUETOOTH
# Let users pick the tiles going into their trays
#DEFINES += -DFEATURE_TRAY_EDIT
DEFINES += -DDONT_ABORT_ENGINE
@ -85,10 +88,11 @@ OBJ = $(PLATFORM)/linuxmain.o \
$(PLATFORM)/cursesdlgutil.o \
$(PLATFORM)/cursesletterask.o \
$(PLATFORM)/filestream.o \
$(PLATFORM)/linuxbt.o \
# $(PLATFORM)/linuxcommpipe.o \
LIBS = -lm -L $(HOME)/usr/local/pilot/lib $(GPROFFLAG)
LIBS = -lm -lbluetooth -L $(HOME)/usr/local/pilot/lib $(GPROFFLAG)
ifneq (,$(findstring DPLATFORM_GTK,$(DEFINES)))
LIBS += `pkg-config --libs gtk+-2.0`

View file

@ -704,7 +704,8 @@ blocking_gotEvent( CursesAppGlobals* globals, int* ch )
--numEvents;
nBytes = linux_receive( &globals->cGlobals, buf, sizeof(buf) );
nBytes = linux_relay_receive( &globals->cGlobals, buf,
sizeof(buf) );
if ( nBytes != -1 ) {
XWStreamCtxt* inboundS;
@ -935,7 +936,10 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
setupCursesUtilCallbacks( &globals, params->util );
globals.cGlobals.defaultServerName = params->relayName;
if ( params->conType == COMMS_CONN_RELAY ) {
globals.cGlobals.u.relay.defaultServerName
= params->connInfo.relay.relayName;
}
cursesListenOnSocket( &globals, 0, NULL ); /* stdin */
@ -952,16 +956,16 @@ cursesmain( XP_Bool isServer, LaunchParams* params )
gameID = (XP_U16)util_getCurSeconds( globals.cGlobals.params->util );
game_makeNewGame( MEMPOOL &globals.cGlobals.game, &params->gi,
params->util, (DrawCtx*)globals.draw,
gameID, &globals.cp, linux_tcp_send, &globals );
gameID, &globals.cp, linux_send, &globals );
if ( globals.cGlobals.game.comms ) {
CommsAddrRec addr;
addr.conType = COMMS_CONN_RELAY;
addr.u.ip_relay.ipAddr = 0; /* ??? */
addr.u.ip_relay.port = params->defaultSendPort;
XP_STRNCPY( addr.u.ip_relay.hostName, params->relayName,
addr.u.ip_relay.port = params->connInfo.relay.defaultSendPort;
XP_STRNCPY( addr.u.ip_relay.hostName, params->connInfo.relay.relayName,
sizeof(addr.u.ip_relay.hostName) - 1 );
XP_STRNCPY( addr.u.ip_relay.cookie, params->cookie,
XP_STRNCPY( addr.u.ip_relay.cookie, params->connInfo.relay.cookie,
sizeof(addr.u.ip_relay.cookie) - 1 );
comms_setAddr( globals.cGlobals.game.comms, &addr );
}

View file

@ -41,6 +41,7 @@
#include "main.h"
#include "linuxmain.h"
#include "linuxbt.h"
/* #include "gtkmain.h" */
#include "draw.h"
@ -247,7 +248,7 @@ createOrLoadObjects( GtkAppGlobals* globals )
params->dict, params->util,
(DrawCtx*)globals->draw,
&globals->cp,
linux_tcp_send, globals );
linux_send, globals );
stream_destroy( stream );
@ -255,25 +256,37 @@ createOrLoadObjects( GtkAppGlobals* globals )
XP_U16 gameID;
CommsAddrRec addr;
addr.conType = params->conType;
gameID = (XP_U16)util_getCurSeconds( globals->cGlobals.params->util );
XP_ASSERT( !!params->relayName );
globals->cGlobals.defaultServerName = params->relayName;
if ( addr.conType == COMMS_CONN_RELAY ) {
XP_ASSERT( !!params->connInfo.relay.relayName );
globals->cGlobals.u.relay.defaultServerName
= params->connInfo.relay.relayName;
}
params->gi.gameID = util_getCurSeconds(globals->cGlobals.params->util);
XP_STATUSF( "grabbed gameID: %ld\n", params->gi.gameID );
game_makeNewGame( MEMPOOL &globals->cGlobals.game, &params->gi,
params->util, (DrawCtx*)globals->draw,
gameID, &globals->cp, linux_tcp_send, globals );
gameID, &globals->cp, linux_send, globals );
addr.conType = COMMS_CONN_RELAY;
addr.u.ip_relay.ipAddr = 0;
addr.u.ip_relay.port = params->defaultSendPort;
XP_STRNCPY( addr.u.ip_relay.hostName, params->relayName,
sizeof(addr.u.ip_relay.hostName) - 1 );
XP_STRNCPY( addr.u.ip_relay.cookie, params->cookie,
sizeof(addr.u.ip_relay.cookie) - 1 );
addr.conType = params->conType;
if ( addr.conType == COMMS_CONN_RELAY ) {
addr.u.ip_relay.ipAddr = 0;
addr.u.ip_relay.port = params->connInfo.relay.defaultSendPort;
XP_STRNCPY( addr.u.ip_relay.hostName, params->connInfo.relay.relayName,
sizeof(addr.u.ip_relay.hostName) - 1 );
XP_STRNCPY( addr.u.ip_relay.cookie, params->connInfo.relay.cookie,
sizeof(addr.u.ip_relay.cookie) - 1 );
} else if ( addr.conType == COMMS_CONN_BT ) {
XP_ASSERT( sizeof(addr.u.bt.btAddr)
>= sizeof(params->connInfo.bt.hostAddr));
XP_MEMCPY( &addr.u.bt.btAddr, &params->connInfo.bt.hostAddr,
sizeof(params->connInfo.bt.hostAddr) );
}
/* This may trigger network activity */
if ( !!globals->cGlobals.game.comms ) {
@ -463,6 +476,8 @@ quit( void* XP_UNUSED(dunno), GtkAppGlobals* globals )
game_dispose( &globals->cGlobals.game ); /* takes care of the dict */
gi_disposePlayerInfo( MEMPOOL &globals->cGlobals.params->gi );
linux_bt_close( &globals->cGlobals );
vtmgr_destroy( MEMPOOL globals->cGlobals.params->vtMgr );
@ -547,7 +562,7 @@ new_game( GtkWidget* XP_UNUSED(widget), GtkAppGlobals* globals )
XP_STATUSF( "grabbed gameID: %ld\n", gameID );
game_reset( MEMPOOL &globals->cGlobals.game, gi,
globals->cGlobals.params->util,
gameID, &globals->cp, linux_tcp_send, globals );
gameID, &globals->cp, linux_send, globals );
if ( isClient ) {
XWStreamCtxt* stream =
@ -1472,7 +1487,14 @@ newConnectionInput( GIOChannel *source,
ssize_t nRead;
unsigned char buf[512];
nRead = linux_receive( &globals->cGlobals, buf, sizeof(buf) );
if ( globals->cGlobals.params->conType == COMMS_CONN_RELAY ) {
nRead = linux_relay_receive( &globals->cGlobals,
buf, sizeof(buf) );
} else if ( globals->cGlobals.params->conType == COMMS_CONN_BT ) {
nRead = linux_bt_receive( &globals->cGlobals, buf, sizeof(buf) );
} else {
XP_ASSERT( 0 );
}
if ( !globals->dropIncommingMsgs && nRead > 0 ) {
XWStreamCtxt* inboundS;
@ -1482,8 +1504,9 @@ newConnectionInput( GIOChannel *source,
if ( !!inboundS ) {
if ( comms_checkIncomingStream( globals->cGlobals.game.comms,
inboundS, NULL ) ) {
redraw = server_receiveMessage(globals->cGlobals.game.server
, inboundS );
redraw =
server_receiveMessage(globals->cGlobals.game.server,
inboundS );
}
stream_destroy( inboundS );
}
@ -1525,6 +1548,7 @@ static void
gtk_socket_changed( void* closure, int oldSock, int newSock )
{
GtkAppGlobals* globals = (GtkAppGlobals*)closure;
XP_ASSERT( oldSock == globals->cGlobals.socket );
if ( oldSock != -1 ) {
g_source_remove( oldSock );
XP_LOGF( "Removed %d from gtk's list of listened-to sockets" );
@ -1532,6 +1556,7 @@ gtk_socket_changed( void* closure, int oldSock, int newSock )
if ( newSock != -1 ) {
gtkListenOnSocket( globals, newSock );
}
globals->cGlobals.socket = newSock;
}
static void

157
linux/linuxbt.c Normal file
View file

@ -0,0 +1,157 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE";-*- */
/*
* Copyright 2006 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_BLUETOOTH
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include "linuxbt.h"
#include "comms.h"
typedef struct LinBtStuff {
CommonGlobals* globals;
XP_Bool amMaster;
} LinBtStuff;
static LinBtStuff*
linBtMake( MPFORMAL XP_Bool amMaster )
{
LinBtStuff* btStuff = (LinBtStuff*)XP_MALLOC( mpool, sizeof(*btStuff) );
XP_MEMSET( btStuff, 0, sizeof(*btStuff) );
btStuff->amMaster = amMaster;
return btStuff;
}
static void
btConnectSocket( LinBtStuff* btStuff, const CommsAddrRec* addrP )
{
struct sockaddr_l2 saddr;
int sock;
XP_MEMSET( &saddr, 0, sizeof(saddr) );
// allocate a socket
sock = socket( AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP );
if ( sock < 0 ) {
XP_LOGF( "%s: socket->%s", __FUNCTION__, strerror(errno) );
} else {
// set the connection parameters (who to connect to)
saddr.l2_family = AF_BLUETOOTH;
saddr.l2_psm = htobs( XW_PSM );
XP_MEMCPY( &saddr.l2_bdaddr, &addrP->u.bt.btAddr,
sizeof(saddr.l2_bdaddr) );
// connect to server
if ( 0 == connect( sock, (struct sockaddr *)&saddr, sizeof(saddr) ) ) {
CommonGlobals* globals = btStuff->globals;
(*globals->socketChanged)( globals->socketChangedClosure,
-1, sock );
} else {
XP_LOGF( "%s: connect->%s", __FUNCTION__, strerror(errno) );
}
}
}
void
linux_bt_open( CommonGlobals* globals, XP_Bool amMaster )
{
LinBtStuff* btStuff = globals->u.bt.btStuff;
if ( !btStuff ) {
btStuff = globals->u.bt.btStuff
= linBtMake( MPPARM(globals->params->util->mpool)
amMaster );
btStuff->globals = globals;
globals->u.bt.btStuff = btStuff;
}
}
void
linux_bt_close( CommonGlobals* globals )
{
LinBtStuff* btStuff = globals->u.bt.btStuff;
if ( !!btStuff ) {
XP_FREE( globals->params->util->mpool, btStuff );
globals->u.bt.btStuff = NULL;
}
}
XP_S16 linux_bt_send( const XP_U8* buf, XP_U16 buflen,
const CommsAddrRec* addrP,
CommonGlobals* globals )
{
LinBtStuff* btStuff = globals->u.bt.btStuff;
CommsAddrRec addr;
XP_S16 nSent = -1;
LOG_FUNC();
XP_ASSERT( !!btStuff );
if ( !addrP ) {
comms_getAddr( globals->game.comms, &addr );
addrP = &addr;
}
if ( globals->socket < 0 ) {
btConnectSocket( btStuff, addrP );
}
if ( globals->socket >= 0 ) {
nSent = write( globals->socket, buf, buflen );
if ( nSent < 0 ) {
XP_LOGF( "%s: send->%s", __FUNCTION__, strerror(errno) );
} else if ( nSent < buflen ) {
XP_LOGF( "%s: send only %d bytes of %d", __FUNCTION__, nSent,
buflen );
}
} else {
XP_LOGF( "%s: socket still not set", __FUNCTION__ );
}
LOG_RETURNF( "%d", nSent );
return nSent;
}
XP_S16
linux_bt_receive( CommonGlobals* globals, XP_U8* buf, XP_U16 buflen )
{
XP_S16 nRead = 0;
int sock = globals->socket;
LOG_FUNC();
XP_ASSERT( sock >= 0 );
nRead = read( sock, buf, buflen );
if ( nRead < 0 ) {
XP_LOGF( "%s: read->%s", __FUNCTION__, strerror(errno) );
}
LOG_RETURNF( "%d", nRead );
return nRead;
}
#endif /* XWFEATURE_BLUETOOTH */

36
linux/linuxbt.h Normal file
View file

@ -0,0 +1,36 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE";-*- */
/*
* Copyright 2006 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 _LINUXBT_H_
#define _LINUXBT_H_
#ifdef XWFEATURE_BLUETOOTH
#include "main.h"
void linux_bt_open( CommonGlobals* globals, XP_Bool amMaster );
void linux_bt_close( CommonGlobals* globals );
XP_S16 linux_bt_send( const XP_U8* buf, XP_U16 buflen,
const CommsAddrRec* addrRec,
CommonGlobals* globals );
XP_S16 linux_bt_receive( CommonGlobals* globals, XP_U8* buf, XP_U16 buflen );
#endif /* XWFEATURE_BLUETOOTH */
#endif /* #ifndef _LINUXBT_H_ */

View file

@ -1,4 +1,4 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE"; -*- */
/*
* Copyright 2000 by Eric House (xwords@eehouse.org). All rights reserved.
*
@ -30,7 +30,12 @@
#include <arpa/inet.h>
#include <time.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include "linuxmain.h"
#include "linuxbt.h"
#include "main.h"
#ifdef PLATFORM_NCURSES
# include "cursesmain.h"
@ -245,6 +250,8 @@ usage( char* appName, char* msg )
"\t [-p relay_port] # relay is at this port\n"
"\t [-a relay_addr] # use relay (via port spec'd above)\n"
"" " (default localhost)\n"
"\t [-B n:name|a:00:11:22:33:44:55]\n"
"\t\t\t# connect via bluetooth [param ignored if -s]\n"
/* "# --------------- OR client-only ----------\n" */
/* "\t [-p client_port] # must != server's port if on same device" */
"\nexample: \n"
@ -255,18 +262,17 @@ usage( char* appName, char* msg )
exit(1);
}
XP_S16
linux_tcp_send( XP_U8* buf, XP_U16 buflen,
static XP_S16
linux_tcp_send( const XP_U8* buf, XP_U16 buflen,
const CommsAddrRec* XP_UNUSED(addrRec),
void* closure )
CommonGlobals* globals )
{
CommonGlobals* globals = (CommonGlobals*)closure;
XP_S16 result = 0;
int socket = globals->socket;
if ( socket == -1 ) {
XP_STATUSF( "linux_tcp_send: socket uninitialized" );
socket = linux_init_socket( globals );
socket = linux_init_relay_socket( globals );
if ( socket != -1 ) {
assert( globals->socket == socket );
(*globals->socketChanged)( globals->socketChangedClosure,
@ -297,8 +303,33 @@ linux_tcp_send( XP_U8* buf, XP_U16 buflen,
return result;
} /* linux_tcp_send */
XP_S16
linux_send( const XP_U8* buf, XP_U16 buflen,
const CommsAddrRec* addrRec,
void* closure )
{
XP_S16 nSent = -1;
CommonGlobals* globals = (CommonGlobals*)closure;
CommsConnType conType;
if ( !!addrRec ) {
conType = addrRec->conType;
} else {
conType = globals->params->conType;
}
if ( conType == COMMS_CONN_RELAY ) {
nSent = linux_tcp_send( buf, buflen, addrRec, globals );
} else if ( conType == COMMS_CONN_BT ) {
nSent = linux_bt_send( buf, buflen, addrRec, globals );
} else {
XP_ASSERT(0);
}
return nSent;
} /* linux_send */
int
linux_init_socket( CommonGlobals* cGlobals )
linux_init_relay_socket( CommonGlobals* cGlobals )
{
struct sockaddr_in to_sock;
struct hostent* host;
@ -312,15 +343,17 @@ linux_init_socket( CommonGlobals* cGlobals )
return -1;
}
to_sock.sin_port = htons(cGlobals->params->defaultSendPort);
to_sock.sin_port = htons(cGlobals->params->
connInfo.relay.defaultSendPort );
XP_STATUSF( "1: sending to port %d",
cGlobals->params->defaultSendPort );
if (( host = gethostbyname(cGlobals->params->relayName) ) == NULL ) {
cGlobals->params->connInfo.relay.defaultSendPort );
host = gethostbyname( cGlobals->params->connInfo.relay.relayName );
if ( NULL == host ) {
XP_WARNF( "gethostbyname returned -1\n" );
return -1;
} else {
XP_WARNF( "gethostbyname for %s worked",
cGlobals->defaultServerName );
cGlobals->u.relay.defaultServerName );
}
memcpy( &(to_sock.sin_addr.s_addr), host->h_addr_list[0],
sizeof(struct in_addr));
@ -338,7 +371,7 @@ linux_init_socket( CommonGlobals* cGlobals )
}
return sock;
} /* linux_init_socket */
} /* linux_init_relay_socket */
static void
linux_close_socket( CommonGlobals* cGlobals )
@ -351,7 +384,7 @@ linux_close_socket( CommonGlobals* cGlobals )
}
int
linux_receive( CommonGlobals* cGlobals, unsigned char* buf, int bufSize )
linux_relay_receive( CommonGlobals* cGlobals, unsigned char* buf, int bufSize )
{
int sock = cGlobals->socket;
unsigned short tmp;
@ -554,11 +587,15 @@ linux_util_getUserString( XW_UtilCtxt* XP_UNUSED(uc), XP_U16 code )
#ifdef BEYOND_IR
static void
linux_util_addrChange( XW_UtilCtxt* XP_UNUSED(uc),
linux_util_addrChange( XW_UtilCtxt* uc,
const CommsAddrRec* XP_UNUSED(oldAddr),
const CommsAddrRec* XP_UNUSED(newAddr) )
const CommsAddrRec* newAddr,
XP_Bool isServer )
{
XP_LOGF( "linux_util_addrChange called; what to do?" );
if ( newAddr->conType == COMMS_CONN_BT ) {
CommonGlobals* cGlobals = (CommonGlobals*)uc->closure;
linux_bt_open( cGlobals, isServer );
}
}
#endif
@ -574,6 +611,40 @@ defaultRandomSeed()
return rs;
} /* defaultRandomSeed */
/* This belongs in linuxbt.c */
static XP_Bool
nameToBtAddr( const char* name, bdaddr_t* ba )
{
XP_Bool success = XP_FALSE;
int id, socket;
LOG_FUNC();
# define RESPMAX 5
id = hci_get_route( NULL );
socket = hci_open_dev( id );
if ( id >= 0 && socket >= 0 ) {
long flags = 0L;
inquiry_info inqInfo[RESPMAX];
inquiry_info* inqInfoP = inqInfo;
int count = hci_inquiry( id, 10, RESPMAX, NULL, &inqInfoP, flags );
int i;
for ( i = 0; i < count; ++i ) {
char buf[64];
if ( 0 >= hci_read_remote_name( socket, &inqInfo[i].bdaddr,
sizeof(buf), buf, 0)) {
if ( 0 == strcmp( buf, name ) ) {
XP_MEMCPY( ba, &inqInfo[i].bdaddr, sizeof(*ba) );
success = XP_TRUE;
XP_LOGF( "%s: matched %s", __FUNCTION__, name );
break;
}
}
}
}
return success;
} /* nameToBtAddr */
int
main( int argc, char** argv )
{
@ -586,6 +657,9 @@ main( int argc, char** argv )
unsigned int seed = defaultRandomSeed();
LaunchParams mainParams;
XP_U16 robotCount = 0;
CommsConnType conType = COMMS_CONN_UNUSED;
const char* btaddr = NULL;
#ifdef DEBUG
{
@ -611,9 +685,9 @@ main( int argc, char** argv )
/* (void)fgetc( stdin ); */
/* defaults */
mainParams.defaultListenPort = DEFAULT_LISTEN_PORT;
mainParams.defaultSendPort = DEFAULT_SEND_PORT;
mainParams.cookie = "COOKIE";
mainParams.connInfo.relay.defaultListenPort = DEFAULT_LISTEN_PORT;
mainParams.connInfo.relay.defaultSendPort = DEFAULT_SEND_PORT;
mainParams.connInfo.relay.cookie = "COOKIE";
mainParams.gi.boardSize = 15;
mainParams.quitAfter = XP_FALSE;
mainParams.sleepOnAnchor = XP_FALSE;
@ -645,7 +719,7 @@ main( int argc, char** argv )
#if defined PLATFORM_GTK
"h:"
#endif
"kKf:l:n:Nsd:a:p:e:r:b:qw:Sit:HUmvcC:" );
"kKf:l:n:Nsd:a:p:e:r:b:qw:Sit:HUmvcC:B:" );
switch( opt ) {
case '?':
usage(argv[0], NULL);
@ -654,7 +728,10 @@ main( int argc, char** argv )
mainParams.showRobotScores = XP_TRUE;
break;
case 'C':
mainParams.cookie = optarg;
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
conType == COMMS_CONN_RELAY );
mainParams.connInfo.relay.cookie = optarg;
conType = COMMS_CONN_RELAY;
break;
case 'd':
mainParams.gi.dictName = copyString( MPPARM(mainParams.util->mpool)
@ -694,6 +771,9 @@ main( int argc, char** argv )
break;
case 'p':
sendPortNumString = optarg;
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
conType == COMMS_CONN_RELAY );
conType = COMMS_CONN_RELAY;
break;
case 'r':
++robotCount;
@ -722,6 +802,9 @@ main( int argc, char** argv )
break;
case 'a':
/* mainParams.info.clientInfo.serverName = */
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
conType == COMMS_CONN_RELAY );
conType = COMMS_CONN_RELAY;
relayName = optarg;
break;
case 'q':
@ -730,6 +813,12 @@ main( int argc, char** argv )
case 'b':
mainParams.gi.boardSize = atoi(optarg);
break;
case 'B':
XP_ASSERT( conType == COMMS_CONN_UNUSED ||
conType == COMMS_CONN_BT );
conType = COMMS_CONN_BT;
btaddr = optarg;
break;
case 'v':
mainParams.verticalScore = XP_TRUE;
break;
@ -766,11 +855,6 @@ main( int argc, char** argv )
mainParams.gi.serverRole = SERVER_ISCLIENT;
}
/* convert strings to whatever */
if ( sendPortNumString != NULL ) {
mainParams.defaultSendPort = atoi( sendPortNumString );
}
/* sanity checks */
totalPlayerCount = mainParams.nLocalPlayers
+ mainParams.info.serverInfo.nRemotePlayers;
@ -803,7 +887,38 @@ main( int argc, char** argv )
}
}
mainParams.relayName = relayName;
if ( conType == COMMS_CONN_RELAY ) {
mainParams.connInfo.relay.relayName = relayName;
/* convert strings to whatever */
if ( sendPortNumString != NULL ) {
mainParams.connInfo.relay.defaultSendPort =
atoi( sendPortNumString );
}
} else if ( conType == COMMS_CONN_BT ) {
bdaddr_t ba;
XP_Bool success = XP_FALSE;
XP_ASSERT( btaddr );
if ( btaddr[1] == ':' ) {
if ( btaddr[0] == 'n' ) {
if ( !nameToBtAddr( btaddr+2, &ba ) ) {
fprintf( stderr, "fatal error: unable to find device %s\n",
btaddr + 2 );
exit(0);
}
success = XP_TRUE;
} else if ( btaddr[0] == 'a' ) {
success = 0 == str2ba( &btaddr[2], &ba );
XP_ASSERT( success );
}
}
if ( !success ) {
usage( argv[0], "bad format for -B param" );
}
XP_MEMCPY( &mainParams.connInfo.bt.hostAddr, &ba,
sizeof(mainParams.connInfo.bt.hostAddr) );
}
mainParams.conType = conType;
/* mainParams.pipe = linuxCommPipeCtxtMake( isServer ); */

View file

@ -37,10 +37,11 @@ typedef struct LinuxBMStruct {
DictionaryCtxt* linux_dictionary_make( MPFORMAL const char* dictFileName );
int initListenerSocket( int port );
XP_S16 linux_tcp_send( XP_U8* buf, XP_U16 buflen, const CommsAddrRec* addrRec,
void* closure );
int linux_init_socket( CommonGlobals* cGlobals );
int linux_receive( CommonGlobals* cGlobals, unsigned char* buf, int bufSize );
XP_S16 linux_send( const XP_U8* buf, XP_U16 buflen,
const CommsAddrRec* addrRec, void* closure );
int linux_init_relay_socket( CommonGlobals* cGlobals );
int linux_relay_receive( CommonGlobals* cGlobals, unsigned char* buf,
int bufSize );
void linuxFireTimer( CommonGlobals* cGlobals, XWTimerReason why );

View file

@ -20,6 +20,8 @@
#ifndef _MAIN_H_
#define _MAIN_H_
#include <bluetooth/bluetooth.h> /* for bdaddr_t, which should move */
#include "comtypes.h"
#include "util.h"
#include "game.h"
@ -43,7 +45,6 @@ typedef struct LaunchParams {
DictionaryCtxt* dict;
CurGameInfo gi;
char* fileName;
char* cookie;
VTableMgr* vtMgr;
XP_U16 nLocalPlayers;
XP_U16 nHidden;
@ -60,15 +61,24 @@ typedef struct LaunchParams {
Connectedness serverRole;
char* relayName;
CommsConnType conType;
union {
struct {
char* relayName;
char* cookie;
short defaultSendPort;
short defaultListenPort;
} relay;
struct {
bdaddr_t hostAddr; /* unused if a host */
} bt;
} connInfo;
union {
ServerInfo serverInfo;
ClientInfo clientInfo;
} info;
short defaultSendPort;
short defaultListenPort;
} LaunchParams;
typedef void (*SocketChangedFunc)(void* closure, int oldsock, int newsock );
@ -78,14 +88,25 @@ typedef struct CommonGlobals {
XWGame game;
XP_U16 lastNTilesToUse;
/* UDP comms stuff */
char* defaultServerName;
int socket;
SocketChangedFunc socketChanged;
void* socketChangedClosure;
int socket; /* either relay or bt */
union {
struct {
char* defaultServerName;
} relay;
struct {
struct LinBtStuff* btStuff;
} bt;
} u;
TimerProc timerProcs[NUM_TIMERS_PLUS_ONE];
void* timerClosures[NUM_TIMERS_PLUS_ONE];
MPSLOT
} CommonGlobals;
#endif