mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-28 07:58:08 +01:00
toward improving bt support in gtk client: add scan button that only
picks up devices currently open for discovery
This commit is contained in:
parent
d25e20221b
commit
f0c5d1f865
4 changed files with 170 additions and 48 deletions
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "gtkconnsdlg.h"
|
||||
#include "gtkutils.h"
|
||||
#include "linuxbt.h"
|
||||
|
||||
typedef struct _GtkConnsState {
|
||||
GtkGameGlobals* globals;
|
||||
|
@ -32,8 +33,12 @@ typedef struct _GtkConnsState {
|
|||
GtkWidget* hostName;
|
||||
GtkWidget* port;
|
||||
GtkWidget* bthost;
|
||||
GtkWidget* smsphone;
|
||||
GtkWidget* smsport;
|
||||
GtkWidget* bgScanButton;
|
||||
|
||||
GtkWidget* notebook;
|
||||
|
||||
CommsConnType pageTypes[COMMS_CONN_NTYPES];
|
||||
|
||||
gboolean cancelled;
|
||||
|
@ -91,9 +96,13 @@ handle_ok( GtkWidget* XP_UNUSED(widget), gpointer closure )
|
|||
#endif
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
case COMMS_CONN_BT:
|
||||
txt = gtk_entry_get_text( GTK_ENTRY(state->bthost) );
|
||||
XP_STRNCPY( state->addr->u.bt.hostName, txt,
|
||||
sizeof(state->addr->u.bt.hostName) );
|
||||
break;
|
||||
#endif
|
||||
case COMMS_CONN_SMS:
|
||||
XP_ASSERT(0);
|
||||
break;
|
||||
default:
|
||||
XP_ASSERT( 0 ); /* keep compiler happy */
|
||||
|
@ -107,6 +116,25 @@ handle_ok( GtkWidget* XP_UNUSED(widget), gpointer closure )
|
|||
gtk_main_quit();
|
||||
} /* handle_ok */
|
||||
|
||||
static void
|
||||
handle_scan( GtkWidget* XP_UNUSED(widget), gpointer closure )
|
||||
{
|
||||
GtkConnsState* state = (GtkConnsState*)closure;
|
||||
XP_USE(state);
|
||||
LOG_FUNC();
|
||||
|
||||
GSList* devNames = linux_bt_scan();
|
||||
if ( !devNames ) {
|
||||
XP_LOGF( "%s: got nothing", __func__ );
|
||||
} else {
|
||||
GSList* iter;
|
||||
for ( iter = devNames; !!iter; iter = iter->next ) {
|
||||
gchar* name = iter->data;
|
||||
XP_LOGF( "%s: got %s", __func__, name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_cancel( GtkWidget* XP_UNUSED(widget), void* closure )
|
||||
{
|
||||
|
@ -140,21 +168,27 @@ makeRelayPage( GtkConnsState* state )
|
|||
gtk_box_pack_start( GTK_BOX(vbox), gtk_label_new( hint ), FALSE, TRUE, 0 );
|
||||
|
||||
GtkWidget* hbox = makeLabeledField( "Room", &state->invite );
|
||||
gtk_entry_set_text( GTK_ENTRY(state->invite),
|
||||
state->addr->u.ip_relay.invite );
|
||||
if ( COMMS_CONN_RELAY == state->addr->conType ) {
|
||||
gtk_entry_set_text( GTK_ENTRY(state->invite),
|
||||
state->addr->u.ip_relay.invite );
|
||||
}
|
||||
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
|
||||
gtk_widget_set_sensitive( state->invite, !state->readOnly );
|
||||
|
||||
hbox = makeLabeledField( "Relay address", &state->hostName );
|
||||
gtk_entry_set_text( GTK_ENTRY(state->hostName),
|
||||
state->addr->u.ip_relay.hostName );
|
||||
if ( COMMS_CONN_RELAY == state->addr->conType ) {
|
||||
gtk_entry_set_text( GTK_ENTRY(state->hostName),
|
||||
state->addr->u.ip_relay.hostName );
|
||||
}
|
||||
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
|
||||
gtk_widget_set_sensitive( state->hostName, !state->readOnly );
|
||||
|
||||
hbox = makeLabeledField( "Relay port", &state->port );
|
||||
char buf[16];
|
||||
snprintf( buf, sizeof(buf), "%d", state->addr->u.ip_relay.port );
|
||||
gtk_entry_set_text( GTK_ENTRY(state->port), buf );
|
||||
if ( COMMS_CONN_RELAY == state->addr->conType ) {
|
||||
char buf[16];
|
||||
snprintf( buf, sizeof(buf), "%d", state->addr->u.ip_relay.port );
|
||||
gtk_entry_set_text( GTK_ENTRY(state->port), buf );
|
||||
}
|
||||
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
|
||||
gtk_widget_set_sensitive( state->port, !state->readOnly );
|
||||
|
||||
|
@ -169,10 +203,42 @@ makeBTPage( GtkConnsState* state )
|
|||
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
|
||||
|
||||
GtkWidget* hbox = makeLabeledField( "Host device", &state->bthost );
|
||||
gtk_entry_set_text( GTK_ENTRY(state->bthost), state->addr->u.bt.hostName );
|
||||
if ( COMMS_CONN_BT == state->addr->conType ) {
|
||||
gtk_entry_set_text( GTK_ENTRY(state->bthost), state->addr->u.bt.hostName );
|
||||
}
|
||||
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
|
||||
gtk_widget_set_sensitive( state->bthost, !state->readOnly );
|
||||
|
||||
state->bgScanButton = makeButton( "Scan", GTK_SIGNAL_FUNC(handle_scan),
|
||||
state );
|
||||
gtk_box_pack_start( GTK_BOX(vbox), state->bgScanButton, FALSE, TRUE, 0 );
|
||||
|
||||
gtk_widget_show( vbox );
|
||||
|
||||
return vbox;
|
||||
} /* makeBTPage */
|
||||
|
||||
static GtkWidget*
|
||||
makeSMSPage( GtkConnsState* state )
|
||||
{
|
||||
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
|
||||
|
||||
GtkWidget* hbox = makeLabeledField( "Host phone", &state->smsphone );
|
||||
if ( COMMS_CONN_SMS == state->addr->conType ) {
|
||||
gtk_entry_set_text( GTK_ENTRY(state->smsphone), state->addr->u.sms.phone );
|
||||
}
|
||||
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
|
||||
gtk_widget_set_sensitive( state->smsphone, !state->readOnly );
|
||||
|
||||
hbox = makeLabeledField( "Host port", &state->smsport );
|
||||
if ( COMMS_CONN_SMS == state->addr->conType ) {
|
||||
gchar port[32];
|
||||
snprintf( port, sizeof(port), "%d", state->addr->u.sms.port );
|
||||
gtk_entry_set_text( GTK_ENTRY(state->smsphone), port );
|
||||
}
|
||||
gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 0 );
|
||||
gtk_widget_set_sensitive( state->smsport, !state->readOnly );
|
||||
|
||||
gtk_widget_show( vbox );
|
||||
|
||||
return vbox;
|
||||
|
@ -209,6 +275,10 @@ gtkConnsDlg( GtkGameGlobals* globals, CommsAddrRec* addr, DeviceRole role,
|
|||
makeBTPage(&state),
|
||||
gtk_label_new( "Bluetooth" ) );
|
||||
#endif
|
||||
state.pageTypes[nTypes++] = COMMS_CONN_SMS;
|
||||
(void)gtk_notebook_append_page( GTK_NOTEBOOK(state.notebook),
|
||||
makeSMSPage(&state),
|
||||
gtk_label_new( "SMS" ) );
|
||||
|
||||
vbox = gtk_vbox_new( FALSE, 0 );
|
||||
gtk_box_pack_start( GTK_BOX(vbox), state.notebook, FALSE, TRUE, 0 );
|
||||
|
@ -222,7 +292,7 @@ gtkConnsDlg( GtkGameGlobals* globals, CommsAddrRec* addr, DeviceRole role,
|
|||
/* buttons at the bottom */
|
||||
hbox = gtk_hbox_new( FALSE, 0 );
|
||||
gtk_box_pack_start( GTK_BOX(hbox),
|
||||
makeButton( "Ok", GTK_SIGNAL_FUNC(handle_ok) , &state ),
|
||||
makeButton( "Ok", GTK_SIGNAL_FUNC(handle_ok), &state ),
|
||||
FALSE, TRUE, 0 );
|
||||
if ( !readOnly ) {
|
||||
gtk_box_pack_start( GTK_BOX(hbox),
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
#if defined BT_USE_L2CAP
|
||||
# include <bluetooth/l2cap.h>
|
||||
#elif defined BT_USE_RFCOMM
|
||||
|
@ -516,4 +518,89 @@ linux_bt_socketclosed( CommonGlobals* globals, int XP_UNUSED_DBG(sock) )
|
|||
btStuff->socket = -1;
|
||||
}
|
||||
|
||||
#define RESPMAX 20
|
||||
|
||||
typedef gboolean (*bt_proc)( const bdaddr_t* bdaddr, int socket, void* closure );
|
||||
|
||||
static void
|
||||
btDevsIterate( bt_proc proc, void* closure )
|
||||
{
|
||||
int id, socket;
|
||||
LOG_FUNC();
|
||||
|
||||
id = hci_get_route( NULL );
|
||||
socket = hci_open_dev( id );
|
||||
if ( id >= 0 && socket >= 0 ) {
|
||||
long flags = IREQ_CACHE_FLUSH;
|
||||
inquiry_info inqInfo[RESPMAX];
|
||||
inquiry_info* inqInfoP = inqInfo;
|
||||
int count = hci_inquiry( id, 8/*wait seconds*/,
|
||||
RESPMAX, NULL, &inqInfoP, flags );
|
||||
|
||||
int ii;
|
||||
for ( ii = 0; ii < count; ++ii ) {
|
||||
const bdaddr_t* bdaddr = &inqInfo[ii].bdaddr;
|
||||
if ( !(*proc)( bdaddr, socket, closure ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _get_ba_data {
|
||||
const char* name;
|
||||
bdaddr_t* ba;
|
||||
gboolean success;
|
||||
} get_ba_data;
|
||||
|
||||
static gboolean
|
||||
get_ba_proc( const bdaddr_t* bdaddr, int socket, void* closure )
|
||||
{
|
||||
get_ba_data* data = (get_ba_data*)closure;
|
||||
char buf[64];
|
||||
if ( 0 >= hci_read_remote_name( socket, bdaddr, sizeof(buf), buf, 0 ) ) {
|
||||
if ( 0 == strcmp( buf, data->name ) ) {
|
||||
XP_MEMCPY( data->ba, bdaddr, sizeof(*data->ba) );
|
||||
data->success = XP_TRUE;
|
||||
XP_LOGF( "%s: matched %s", __func__, data->name );
|
||||
char addrStr[32];
|
||||
ba2str( data->ba, addrStr );
|
||||
XP_LOGF( "bt_addr is %s", addrStr );
|
||||
}
|
||||
}
|
||||
return !data->success;
|
||||
}
|
||||
|
||||
XP_Bool
|
||||
nameToBtAddr( const char* name, bdaddr_t* ba )
|
||||
{
|
||||
LOG_FUNC();
|
||||
get_ba_data data = { .name = name, .ba = ba, .success = FALSE };
|
||||
btDevsIterate( get_ba_proc, &data );
|
||||
return data.success;
|
||||
} /* nameToBtAddr */
|
||||
|
||||
static gboolean
|
||||
append_name_proc( const bdaddr_t* bdaddr, int socket, void* closure )
|
||||
{
|
||||
GSList** list = (GSList**)closure;
|
||||
char buf[64];
|
||||
char addr[19] = { 0 };
|
||||
ba2str( bdaddr, addr );
|
||||
XP_LOGF( "%s: adding %s", __func__, addr );
|
||||
if ( 0 >= hci_read_remote_name( socket, bdaddr, sizeof(buf), buf, 0 ) ) {
|
||||
gchar* name = g_strdup( buf );
|
||||
*list = g_slist_append( *list, name );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GSList*
|
||||
linux_bt_scan()
|
||||
{
|
||||
GSList* list = NULL;
|
||||
btDevsIterate( append_name_proc, &list );
|
||||
return list;
|
||||
}
|
||||
|
||||
#endif /* XWFEATURE_BLUETOOTH */
|
||||
|
|
|
@ -35,5 +35,9 @@ XP_S16 linux_bt_receive( int sock, XP_U8* buf, XP_U16 buflen );
|
|||
|
||||
void linux_bt_socketclosed( CommonGlobals* globals, int sock );
|
||||
|
||||
GSList* linux_bt_scan();
|
||||
|
||||
XP_Bool nameToBtAddr( const char* name, bdaddr_t* ba );
|
||||
|
||||
#endif /* XWFEATURE_BLUETOOTH */
|
||||
#endif /* #ifndef _LINUXBT_H_ */
|
||||
|
|
|
@ -1446,45 +1446,6 @@ defaultRandomSeed()
|
|||
return rs;
|
||||
} /* defaultRandomSeed */
|
||||
|
||||
/* This belongs in linuxbt.c */
|
||||
#ifdef XWFEATURE_BLUETOOTH
|
||||
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", __func__, name );
|
||||
char addrStr[32];
|
||||
ba2str(ba, addrStr);
|
||||
XP_LOGF( "bt_addr is %s", addrStr );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
} /* nameToBtAddr */
|
||||
#endif
|
||||
|
||||
#ifdef XWFEATURE_SLOW_ROBOT
|
||||
static bool
|
||||
parsePair( const char* optarg, XP_U16* min, XP_U16* max )
|
||||
|
|
Loading…
Add table
Reference in a new issue