mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-30 10:26:58 +01:00
0c915e61b0
A full robot vs. robot game now works between two Treos. Added UI to choose BT as transport mechanism, and added new send proc to establish socket connection between host and guest. Works only for two devices: no piconet yet. No error recovery, ability to quit game in middle, start new game, etc.
619 lines
22 KiB
C
619 lines
22 KiB
C
/* -*-mode: C; fill-column: 77; c-basic-offset: 4; compile-command: "make ARCH=68K_ONLY 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_PALM_BLUETOOTH
|
|
|
|
#include "xptypes.h"
|
|
#include "palmbt.h"
|
|
|
|
# include <BtLib.h>
|
|
# include <BtLibTypes.h>
|
|
|
|
#define L2CAPSOCKETMTU 500
|
|
#define SOCK_INVAL 0XFFFF
|
|
|
|
typedef struct PalmBTStuff {
|
|
DataCb cb;
|
|
PalmAppGlobals* globals;
|
|
|
|
XP_U16 btLibRefNum;
|
|
XP_U16 lenOut;
|
|
XP_UCHAR bufOut[L2CAPSOCKETMTU]; /* what's the mmu? */
|
|
BtLibSocketRef dataSocket;
|
|
XP_Bool sendInProgress;
|
|
XP_Bool sendPending;
|
|
XP_Bool amMaster;
|
|
|
|
union {
|
|
struct {
|
|
BtLibDeviceAddressType masterAddr;
|
|
BtLibSocketRef spdSocket;
|
|
} slave;
|
|
struct {
|
|
BtLibSocketRef listenSocket;
|
|
} master;
|
|
} u;
|
|
|
|
BtLibSdpRecordHandle sdpRecordH;
|
|
|
|
} PalmBTStuff;
|
|
|
|
#define LOG_ERR(f,e) palm_bt_log( #f, __FUNCTION__, e )
|
|
|
|
/* WHAT SHOULD THIS BE? Copied from Whiteboard.... PENDING */
|
|
static const BtLibSdpUuidType XWORDS_UUID = {
|
|
btLibUuidSize128,
|
|
{ 0x83, 0xe0, 0x87, 0xae, 0x4e, 0x18, 0x46, 0xbe,
|
|
0x83, 0xe0, 0x7b, 0x3d, 0xe6, 0xa1, 0xc3, 0x3b } };
|
|
|
|
static void initBTStuff( PalmAppGlobals* globals, DataCb cb, XP_Bool amMaster );
|
|
static void palm_bt_log( const char* btfunc, const char* func, Err err );
|
|
static void pbt_connect_slave( PalmBTStuff* btStuff, BtLibL2CapPsmType psm );
|
|
|
|
#ifdef DEBUG
|
|
static const char* btErrToStr( Err err );
|
|
static const char* btEvtToStr( BtLibSocketEventEnum evt );
|
|
static const char* mgmtEvtToStr( BtLibManagementEventEnum event );
|
|
#else
|
|
# define btErrToStr( err ) ""
|
|
# define btEvtToStr( evt ) ""
|
|
# define mgmtEvtToStr( evt ) ""
|
|
#endif
|
|
|
|
/* callbacks */
|
|
static void libMgmtCallback( BtLibManagementEventType* mEvent, UInt32 refCon );
|
|
static void spdSocketCallback( BtLibSocketEventType* sEvent, UInt32 refCon );
|
|
static void l2SocketCallback( BtLibSocketEventType* sEvent, UInt32 refCon );
|
|
|
|
void
|
|
palm_bt_init( PalmAppGlobals* globals, DataCb cb, XP_Bool amMaster )
|
|
{
|
|
XP_LOGF( "%s(amMaster=%d)", __FUNCTION__, (XP_U16)amMaster );
|
|
|
|
initBTStuff( globals, cb, amMaster );
|
|
}
|
|
|
|
void
|
|
palm_bt_close( PalmAppGlobals* globals )
|
|
{
|
|
PalmBTStuff* btStuff = globals->btStuff;
|
|
if ( !!btStuff ) {
|
|
|
|
/* Need to unregister callbacks */
|
|
(void)BtLibUnregisterManagementNotification( btStuff->btLibRefNum,
|
|
libMgmtCallback );
|
|
if ( btStuff->amMaster
|
|
&& btStuff->u.master.listenSocket != SOCK_INVAL ) {
|
|
(void)BtLibSocketClose( btStuff->btLibRefNum,
|
|
btStuff->u.master.listenSocket );
|
|
btStuff->u.master.listenSocket = SOCK_INVAL;
|
|
}
|
|
if ( btStuff->dataSocket != SOCK_INVAL ) {
|
|
(void)BtLibSocketClose( btStuff->btLibRefNum,
|
|
btStuff->u.master.listenSocket );
|
|
btStuff->dataSocket = SOCK_INVAL;
|
|
}
|
|
|
|
if ( btStuff->btLibRefNum != 0 ) {
|
|
Err err = BtLibClose( btStuff->btLibRefNum );
|
|
LOG_ERR( BtLibClose, err );
|
|
XP_ASSERT( errNone == err );
|
|
}
|
|
XP_FREE( globals->mpool, btStuff );
|
|
globals->btStuff = NULL;
|
|
}
|
|
} /* palm_bt_close */
|
|
|
|
XP_Bool
|
|
btSocketIsOpen( PalmAppGlobals* globals )
|
|
{
|
|
return (NULL != globals->btStuff)
|
|
&& (globals->btStuff->dataSocket != 0);
|
|
}
|
|
|
|
static void
|
|
pbt_send_pending( PalmBTStuff* btStuff )
|
|
{
|
|
LOG_FUNC();
|
|
if ( btStuff->sendPending && !btStuff->sendInProgress ) {
|
|
if ( !!btStuff->dataSocket ) {
|
|
Err err = BtLibSocketSend( btStuff->btLibRefNum, btStuff->dataSocket,
|
|
btStuff->bufOut, btStuff->lenOut );
|
|
LOG_ERR( BtLibSocketSend, err );
|
|
if ( err == errNone ) {
|
|
// clear on receipt of btLibSocketEventSendComplete
|
|
btStuff->sendInProgress = XP_TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
XP_S16
|
|
palm_bt_send( const XP_U8* buf, XP_U16 len, PalmAppGlobals* globals )
|
|
{
|
|
PalmBTStuff* btStuff;
|
|
XP_LOGF( "%s(len=%d)", __FUNCTION__, len );
|
|
|
|
btStuff = globals->btStuff;
|
|
XP_ASSERT( !!btStuff );
|
|
|
|
if ( !!btStuff ) {
|
|
if ( !btStuff->sendInProgress ) {
|
|
if ( len > sizeof( btStuff->bufOut ) ) {
|
|
len = sizeof( btStuff->bufOut );
|
|
}
|
|
XP_MEMCPY( btStuff->bufOut, buf, len );
|
|
btStuff->lenOut = len;
|
|
btStuff->sendPending = XP_TRUE;
|
|
|
|
pbt_send_pending( btStuff );
|
|
}
|
|
}
|
|
return -1;
|
|
} /* palm_bt_send */
|
|
|
|
static void
|
|
pbt_find_psm( PalmBTStuff* btStuff )
|
|
{
|
|
Err err;
|
|
XP_ASSERT( !btStuff->amMaster );
|
|
err = BtLibSocketCreate( btStuff->btLibRefNum, &btStuff->u.slave.spdSocket,
|
|
spdSocketCallback,
|
|
(UInt32)btStuff, btLibSdpProtocol );
|
|
LOG_ERR( BtLibSocketCreate, err );
|
|
|
|
err = BtLibSdpGetPsmByUuid( btStuff->btLibRefNum,
|
|
btStuff->u.slave.spdSocket,
|
|
&btStuff->u.slave.masterAddr,
|
|
(BtLibSdpUuidType*)&XWORDS_UUID, 1 );
|
|
LOG_ERR( BtLibSdpGetPSMByUuid, err );
|
|
}
|
|
|
|
static void
|
|
pbt_connect_slave( PalmBTStuff* btStuff, BtLibL2CapPsmType psm )
|
|
{
|
|
Err err;
|
|
LOG_FUNC();
|
|
XP_ASSERT( !btStuff->amMaster );
|
|
|
|
err = BtLibSocketCreate( btStuff->btLibRefNum, &btStuff->dataSocket,
|
|
l2SocketCallback, (UInt32)btStuff,
|
|
btLibL2CapProtocol );
|
|
LOG_ERR( BtLibSocketCreate, err );
|
|
|
|
if ( btLibErrNoError == err ) {
|
|
BtLibSocketConnectInfoType connInfo;
|
|
connInfo.data.L2Cap.remotePsm = psm;
|
|
connInfo.data.L2Cap.localMtu = L2CAPSOCKETMTU;
|
|
connInfo.data.L2Cap.minRemoteMtu = L2CAPSOCKETMTU;
|
|
connInfo.remoteDeviceP = &btStuff->u.slave.masterAddr;
|
|
|
|
err = BtLibSocketConnect( btStuff->btLibRefNum,
|
|
btStuff->dataSocket, &connInfo );
|
|
LOG_ERR( BtLibSocketConnect, err );
|
|
}
|
|
}
|
|
|
|
static void
|
|
pbt_setup_master( PalmBTStuff* btStuff )
|
|
{
|
|
/* Will eventually want to create a piconet here for more than two
|
|
devices to play.... */
|
|
Err err;
|
|
BtLibSocketListenInfoType listenInfo;
|
|
|
|
|
|
btStuff->u.master.listenSocket = SOCK_INVAL;
|
|
|
|
/* 1. BtLibSocketCreate: create an L2CAP socket. */
|
|
err = BtLibSocketCreate( btStuff->btLibRefNum,
|
|
&btStuff->u.master.listenSocket, l2SocketCallback,
|
|
(UInt32)btStuff, btLibL2CapProtocol );
|
|
LOG_ERR( BtLibSocketCreate, err );
|
|
|
|
/* 2. BtLibSocketListen: set up an L2CAP socket as a listener. */
|
|
XP_MEMSET( &listenInfo, 0, sizeof(listenInfo) );
|
|
listenInfo.data.L2Cap.localPsm = BT_L2CAP_RANDOM_PSM;
|
|
listenInfo.data.L2Cap.localMtu = L2CAPSOCKETMTU;
|
|
listenInfo.data.L2Cap.minRemoteMtu = L2CAPSOCKETMTU;
|
|
err = BtLibSocketListen( btStuff->btLibRefNum,
|
|
btStuff->u.master.listenSocket, &listenInfo );
|
|
LOG_ERR( BtLibSocketListen, err );
|
|
|
|
/* 3. BtLibSdpServiceRecordCreate: allocate a memory chunk that
|
|
represents an SDP service record. */
|
|
err = BtLibSdpServiceRecordCreate(btStuff->btLibRefNum, &btStuff->sdpRecordH );
|
|
LOG_ERR( BtLibSdpServiceRecordCreate, err );
|
|
|
|
/* 4. BtLibSdpServiceRecordSetAttributesForSocket: initialize an SDP
|
|
memory record so it can represent the newly-created L2CAP listener
|
|
socket as a service */
|
|
err = BtLibSdpServiceRecordSetAttributesForSocket(
|
|
btStuff->btLibRefNum, btStuff->u.master.listenSocket,
|
|
(BtLibSdpUuidType*)&XWORDS_UUID, 1, APPNAME,
|
|
StrLen(APPNAME), btStuff->sdpRecordH );
|
|
LOG_ERR( BtLibSdpServiceRecordSetAttributesForSocket, err );
|
|
|
|
/* 5. BtLibSdpServiceRecordStartAdvertising: make an SDP memory record
|
|
representing a local SDP service record visible to remote
|
|
devices. */
|
|
err = BtLibSdpServiceRecordStartAdvertising( btStuff->btLibRefNum,
|
|
btStuff->sdpRecordH );
|
|
LOG_ERR( BtLibSdpServiceRecordStartAdvertising, err );
|
|
} /* pbt_setup_master */
|
|
|
|
static void
|
|
pbt_setup_slave( PalmBTStuff* btStuff )
|
|
{
|
|
Err err;
|
|
static const BtLibClassOfDeviceType deviceFilter
|
|
= btLibCOD_ServiceAny
|
|
| btLibCOD_Major_Any // btLibCOD_Major_Computer
|
|
| btLibCOD_Minor_Comp_Any; //btLibCOD_Minor_Comp_Palm;
|
|
|
|
XP_ASSERT( !btStuff->amMaster );
|
|
|
|
err = BtLibDiscoverSingleDevice( btStuff->btLibRefNum, "Crosswords host",
|
|
(BtLibClassOfDeviceType*)&deviceFilter, 1,
|
|
&btStuff->u.slave.masterAddr,
|
|
false, false );
|
|
LOG_ERR( BtLibDiscoverSingleDevice, err );
|
|
|
|
if ( errNone == err ) {
|
|
err = BtLibLinkConnect( btStuff->btLibRefNum,
|
|
&btStuff->u.slave.masterAddr );
|
|
LOG_ERR( BtLibLinkConnect, err );
|
|
XP_ASSERT( err == btLibErrPending );
|
|
}
|
|
} /* pbt_setup_slave */
|
|
|
|
static void
|
|
initBTStuff( PalmAppGlobals* globals, DataCb cb, XP_Bool amMaster )
|
|
{
|
|
PalmBTStuff* btStuff;
|
|
Err err;
|
|
XP_U16 btLibRefNum;
|
|
|
|
btStuff = globals->btStuff;
|
|
if ( btStuff != NULL ) {
|
|
if ( btStuff->amMaster == amMaster ) {
|
|
/* nothing to do */
|
|
} else {
|
|
/* role change. Adapt... */
|
|
XP_ASSERT( 0 );
|
|
}
|
|
} else {
|
|
|
|
btStuff = XP_MALLOC( globals->mpool, sizeof(*btStuff) );
|
|
XP_ASSERT( !!btStuff );
|
|
XP_MEMSET( btStuff, 0, sizeof(*btStuff) );
|
|
globals->btStuff = btStuff;
|
|
|
|
btStuff->globals = globals;
|
|
btStuff->cb = cb;
|
|
btStuff->amMaster = amMaster;
|
|
btStuff->dataSocket = SOCK_INVAL;
|
|
|
|
err = SysLibFind( btLibName, &btLibRefNum );
|
|
XP_LOGF( "%s: SysLibFind(%s) => %d\n", __FUNCTION__, btLibName, err );
|
|
XP_ASSERT( errNone == err );
|
|
btStuff->btLibRefNum = btLibRefNum;
|
|
|
|
err = BtLibOpen( btLibRefNum, false );
|
|
LOG_ERR( BtLibOpen, err );
|
|
XP_ASSERT( errNone == err );
|
|
|
|
err = BtLibRegisterManagementNotification( btLibRefNum, libMgmtCallback,
|
|
(UInt32)btStuff );
|
|
LOG_ERR( BtLibRegisterManagementNotification, err );
|
|
|
|
if ( btStuff->amMaster ) {
|
|
pbt_setup_master( btStuff );
|
|
} else {
|
|
pbt_setup_slave( btStuff );
|
|
}
|
|
}
|
|
} /* initBTStuff */
|
|
|
|
static void
|
|
l2SocketCallback( BtLibSocketEventType* sEvent, UInt32 refCon )
|
|
{
|
|
PalmBTStuff* btStuff = (PalmBTStuff*)refCon;
|
|
BtLibSocketEventEnum event = sEvent->event;
|
|
Err err;
|
|
|
|
XP_LOGF( "%s(%s)", __FUNCTION__, btEvtToStr(event) );
|
|
|
|
switch( event ) {
|
|
case btLibSocketEventConnectRequest:
|
|
err = BtLibSocketRespondToConnection( btStuff->btLibRefNum,
|
|
sEvent->socket, true );
|
|
LOG_ERR( BtLibSocketRespondToConnection, err );
|
|
break;
|
|
case btLibSocketEventConnectedInbound:
|
|
if ( sEvent->status == errNone ) {
|
|
btStuff->dataSocket = sEvent->eventData.newSocket;
|
|
XP_LOGF( "we have a data socket!!!" );
|
|
pbt_send_pending( btStuff );
|
|
} else {
|
|
XP_LOGF( "%s: status = %d(%s)", __FUNCTION__,
|
|
sEvent->status, btErrToStr(sEvent->status) );
|
|
}
|
|
break;
|
|
case btLibSocketEventConnectedOutbound:
|
|
pbt_send_pending( btStuff );
|
|
break;
|
|
case btLibSocketEventData:
|
|
(*btStuff->cb)( btStuff->globals, sEvent->eventData.data.data,
|
|
sEvent->eventData.data.dataLen );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} /* l2SocketCallback */
|
|
|
|
/***********************************************************************
|
|
* Callbacks
|
|
***********************************************************************/
|
|
static void
|
|
spdSocketCallback( BtLibSocketEventType* sEvent, UInt32 refCon )
|
|
{
|
|
Err err;
|
|
PalmBTStuff* btStuff = (PalmBTStuff*)refCon;
|
|
BtLibSocketEventEnum event = sEvent->event;
|
|
|
|
XP_LOGF( "%s(%s)", __FUNCTION__, btEvtToStr(event) );
|
|
XP_ASSERT( sEvent->socket == btStuff->u.slave.spdSocket );
|
|
XP_ASSERT( !btStuff->amMaster );
|
|
|
|
switch( event ) {
|
|
case btLibSocketEventSdpGetPsmByUuid:
|
|
if ( btLibErrNoError == sEvent->status ) {
|
|
err = BtLibSocketClose( btStuff->btLibRefNum,
|
|
sEvent->socket );
|
|
LOG_ERR( BtLibSocketClose, err );
|
|
btStuff->u.slave.spdSocket = SOCK_INVAL;
|
|
pbt_connect_slave( btStuff, sEvent->eventData.sdpByUuid.param.psm );
|
|
}
|
|
break;
|
|
default: /* happy now, compiler? */
|
|
break;
|
|
}
|
|
} /* spdSocketCallback */
|
|
|
|
static void
|
|
libMgmtCallback( BtLibManagementEventType* mEvent, UInt32 refCon )
|
|
{
|
|
PalmBTStuff* btStuff = (PalmBTStuff*)refCon;
|
|
BtLibManagementEventEnum event = mEvent->event;
|
|
XP_LOGF( "%s(%s)", __FUNCTION__, mgmtEvtToStr(event) );
|
|
|
|
switch( event ) {
|
|
case btLibManagementEventACLConnectOutbound:
|
|
if ( btLibErrNoError == mEvent->status ) {
|
|
XP_LOGF( "successful ACL connection to master!" );
|
|
pbt_find_psm( btStuff );
|
|
}
|
|
break;
|
|
|
|
case btLibManagementEventACLConnectInbound:
|
|
if ( btLibErrNoError == mEvent->status ) {
|
|
XP_LOGF( "successful ACL connection!" );
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} /* libMgmtCallback */
|
|
|
|
/***********************************************************************
|
|
* Debug helpers for verbose logging
|
|
***********************************************************************/
|
|
#ifdef DEBUG
|
|
# define CASESTR(e) case(e): return #e
|
|
|
|
static const char*
|
|
btEvtToStr( BtLibSocketEventEnum evt )
|
|
{
|
|
switch( evt ) {
|
|
CASESTR(btLibSocketEventConnectRequest);
|
|
CASESTR(btLibSocketEventConnectedOutbound);
|
|
CASESTR(btLibSocketEventConnectedInbound);
|
|
CASESTR(btLibSocketEventDisconnected);
|
|
CASESTR(btLibSocketEventData);
|
|
CASESTR(btLibSocketEventSendComplete);
|
|
CASESTR(btLibSocketEventSdpServiceRecordHandle);
|
|
CASESTR(btLibSocketEventSdpGetAttribute);
|
|
CASESTR(btLibSocketEventSdpGetStringLen);
|
|
CASESTR(btLibSocketEventSdpGetNumListEntries);
|
|
CASESTR(btLibSocketEventSdpGetNumLists);
|
|
CASESTR(btLibSocketEventSdpGetRawAttribute);
|
|
CASESTR(btLibSocketEventSdpGetRawAttributeSize);
|
|
CASESTR(btLibSocketEventSdpGetServerChannelByUuid);
|
|
CASESTR(btLibSocketEventSdpGetPsmByUuid);
|
|
default:
|
|
XP_ASSERT(0);
|
|
return "";
|
|
}
|
|
} /* btEvtToStr */
|
|
|
|
static const char*
|
|
mgmtEvtToStr( BtLibManagementEventEnum event )
|
|
{
|
|
switch( event ) {
|
|
CASESTR(btLibManagementEventRadioState);
|
|
CASESTR(btLibManagementEventInquiryResult);
|
|
CASESTR(btLibManagementEventInquiryComplete);
|
|
CASESTR(btLibManagementEventInquiryCanceled);
|
|
CASESTR(btLibManagementEventACLDisconnect);
|
|
CASESTR(btLibManagementEventACLConnectInbound);
|
|
CASESTR(btLibManagementEventACLConnectOutbound);
|
|
CASESTR(btLibManagementEventPiconetCreated);
|
|
CASESTR(btLibManagementEventPiconetDestroyed);
|
|
CASESTR(btLibManagementEventModeChange);
|
|
CASESTR(btLibManagementEventAccessibilityChange);
|
|
CASESTR(btLibManagementEventEncryptionChange);
|
|
CASESTR(btLibManagementEventRoleChange);
|
|
CASESTR(btLibManagementEventNameResult);
|
|
CASESTR(btLibManagementEventLocalNameChange);
|
|
CASESTR(btLibManagementEventAuthenticationComplete);
|
|
CASESTR(btLibManagementEventPasskeyRequest);
|
|
CASESTR(btLibManagementEventPasskeyRequestComplete);
|
|
CASESTR(btLibManagementEventPairingComplete);
|
|
default:
|
|
XP_ASSERT(0);
|
|
return "unknown";
|
|
}
|
|
} /* mgmtEvtToStr */
|
|
|
|
static const char*
|
|
btErrToStr( Err err )
|
|
{
|
|
switch ( err ) {
|
|
CASESTR(btLibErrNoError);
|
|
CASESTR(btLibErrError);
|
|
CASESTR(btLibErrNotOpen);
|
|
CASESTR(btLibErrBluetoothOff);
|
|
CASESTR(btLibErrNoPrefs);
|
|
CASESTR(btLibErrAlreadyOpen);
|
|
CASESTR(btLibErrOutOfMemory);
|
|
CASESTR(btLibErrFailed);
|
|
CASESTR(btLibErrInProgress);
|
|
CASESTR(btLibErrParamError);
|
|
CASESTR(btLibErrTooMany);
|
|
CASESTR(btLibErrPending);
|
|
CASESTR(btLibErrNotInProgress);
|
|
CASESTR(btLibErrRadioInitFailed);
|
|
CASESTR(btLibErrRadioFatal);
|
|
CASESTR(btLibErrRadioInitialized);
|
|
CASESTR(btLibErrRadioSleepWake);
|
|
CASESTR(btLibErrNoConnection);
|
|
CASESTR(btLibErrAlreadyRegistered);
|
|
CASESTR(btLibErrNoAclLink);
|
|
CASESTR(btLibErrSdpRemoteRecord);
|
|
CASESTR(btLibErrSdpAdvertised);
|
|
CASESTR(btLibErrSdpFormat);
|
|
CASESTR(btLibErrSdpNotAdvertised);
|
|
CASESTR(btLibErrSdpQueryVersion);
|
|
CASESTR(btLibErrSdpQueryHandle);
|
|
CASESTR(btLibErrSdpQuerySyntax);
|
|
CASESTR(btLibErrSdpQueryPduSize);
|
|
CASESTR(btLibErrSdpQueryContinuation);
|
|
CASESTR(btLibErrSdpQueryResources);
|
|
CASESTR(btLibErrSdpQueryDisconnect);
|
|
CASESTR(btLibErrSdpInvalidResponse);
|
|
CASESTR(btLibErrSdpAttributeNotSet);
|
|
CASESTR(btLibErrSdpMapped);
|
|
CASESTR(btLibErrSocket);
|
|
CASESTR(btLibErrSocketProtocol);
|
|
CASESTR(btLibErrSocketRole);
|
|
CASESTR(btLibErrSocketPsmUnavailable);
|
|
CASESTR(btLibErrSocketChannelUnavailable);
|
|
CASESTR(btLibErrSocketUserDisconnect);
|
|
CASESTR(btLibErrCanceled);
|
|
CASESTR(btLibErrBusy);
|
|
CASESTR(btLibMeStatusUnknownHciCommand);
|
|
CASESTR(btLibMeStatusNoConnection);
|
|
CASESTR(btLibMeStatusHardwareFailure);
|
|
CASESTR(btLibMeStatusPageTimeout);
|
|
CASESTR(btLibMeStatusAuthenticateFailure);
|
|
CASESTR(btLibMeStatusMissingKey);
|
|
CASESTR(btLibMeStatusMemoryFull);
|
|
CASESTR(btLibMeStatusConnnectionTimeout);
|
|
CASESTR(btLibMeStatusMaxConnections);
|
|
CASESTR(btLibMeStatusMaxScoConnections);
|
|
CASESTR(btLibMeStatusMaxAclConnections);
|
|
CASESTR(btLibMeStatusCommandDisallowed);
|
|
CASESTR(btLibMeStatusLimitedResources);
|
|
CASESTR(btLibMeStatusSecurityError);
|
|
CASESTR(btLibMeStatusPersonalDevice);
|
|
CASESTR(btLibMeStatusHostTimeout);
|
|
CASESTR(btLibMeStatusUnsupportedFeature);
|
|
CASESTR(btLibMeStatusInvalidHciParam);
|
|
CASESTR(btLibMeStatusUserTerminated);
|
|
CASESTR(btLibMeStatusLowResources);
|
|
CASESTR(btLibMeStatusPowerOff);
|
|
CASESTR(btLibMeStatusLocalTerminated);
|
|
CASESTR(btLibMeStatusRepeatedAttempts);
|
|
CASESTR(btLibMeStatusPairingNotAllowed);
|
|
CASESTR(btLibMeStatusUnknownLmpPDU);
|
|
CASESTR(btLibMeStatusUnsupportedRemote);
|
|
CASESTR(btLibMeStatusScoOffsetRejected);
|
|
CASESTR(btLibMeStatusScoIntervalRejected);
|
|
CASESTR(btLibMeStatusScoAirModeRejected);
|
|
CASESTR(btLibMeStatusInvalidLmpParam);
|
|
CASESTR(btLibMeStatusUnspecifiedError);
|
|
CASESTR(btLibMeStatusUnsupportedLmpParam);
|
|
CASESTR(btLibMeStatusRoleChangeNotAllowed);
|
|
CASESTR(btLibMeStatusLmpResponseTimeout);
|
|
CASESTR(btLibMeStatusLmpTransdCollision);
|
|
CASESTR(btLibMeStatusLmpPduNotAllowed);
|
|
CASESTR(btLibL2DiscReasonUnknown);
|
|
CASESTR(btLibL2DiscUserRequest);
|
|
CASESTR(btLibL2DiscRequestTimeout);
|
|
CASESTR(btLibL2DiscLinkDisc);
|
|
CASESTR(btLibL2DiscQosViolation);
|
|
CASESTR(btLibL2DiscSecurityBlock);
|
|
CASESTR(btLibL2DiscConnPsmUnsupported);
|
|
CASESTR(btLibL2DiscConnSecurityBlock);
|
|
CASESTR(btLibL2DiscConnNoResources);
|
|
CASESTR(btLibL2DiscConfigUnacceptable);
|
|
CASESTR(btLibL2DiscConfigReject);
|
|
CASESTR(btLibL2DiscConfigOptions);
|
|
CASESTR(btLibServiceShutdownAppUse);
|
|
CASESTR(btLibServiceShutdownPowerCycled);
|
|
CASESTR(btLibServiceShutdownAclDrop);
|
|
CASESTR(btLibServiceShutdownTimeout);
|
|
CASESTR(btLibServiceShutdownDetached);
|
|
CASESTR(btLibErrInUseByService);
|
|
CASESTR(btLibErrNoPiconet);
|
|
CASESTR(btLibErrRoleChange);
|
|
CASESTR(btLibErrSdpNotMapped);
|
|
CASESTR(btLibErrAlreadyConnected);
|
|
CASESTR(btLibErrStackNotOpen);
|
|
CASESTR(btLibErrBatteryTooLow);
|
|
CASESTR(btLibErrNotFound);
|
|
CASESTR(btLibNotYetSupported);
|
|
default:
|
|
return "unknown err";
|
|
}
|
|
} /* btErrToStr */
|
|
|
|
static void
|
|
palm_bt_log( const char* btfunc, const char* func, Err err )
|
|
{
|
|
/* if ( errNone != err ) { */
|
|
XP_LOGF( "%s from %s called in %s", btErrToStr(err), btfunc, func );
|
|
/* } */
|
|
}
|
|
|
|
#endif /* DEBUG */
|
|
|
|
/*
|
|
use piconet? With that, HOST sets it up and clients join. That establishes
|
|
ACL links that can then be used to open sockets. I think. How to get from
|
|
piconet advertising to clients connecting?
|
|
|
|
See http://www.palmos.com/dev/support/docs/palmos/BTCompanion.html
|
|
|
|
NOTE: I've read conflicting reports on whether a listening socket is good for
|
|
accepting more than one inbound connection. Confirm. Or just do a piconet.
|
|
|
|
*/
|
|
#endif /* #ifdef XWFEATURE_PALM_BLUETOOTH */
|