Don't use service records; don't reset connection state as part of

reset for new game; handle case where callback happens inside of
BtLibLinkDisconnect call.
This commit is contained in:
ehouse 2006-09-23 15:24:30 +00:00
parent 04c5401711
commit 95fe18c4c7

View file

@ -48,7 +48,7 @@ typedef enum {
} PBT_STATE; } PBT_STATE;
#define PBT_MAX_ACTS 4 #define PBT_MAX_ACTS 4
#define HASWORK(s) ((s)->vol.queueCur != (s)->vol.queueNext) #define HASWORK(s) ((s)->queueCur != (s)->queueNext)
#define MAX_INCOMING 4 #define MAX_INCOMING 4
typedef struct PalmBTStuff { typedef struct PalmBTStuff {
@ -63,10 +63,6 @@ typedef struct PalmBTStuff {
XP_U16 lens[MAX_INCOMING]; XP_U16 lens[MAX_INCOMING];
XP_U8 bufIn[L2CAPSOCKETMTU*2]; /* what's the mmu? */ XP_U8 bufIn[L2CAPSOCKETMTU*2]; /* what's the mmu? */
XP_U16 queueCur;
XP_U16 queueNext;
PBT_ACTION actQueue[PBT_MAX_ACTS];
XP_Bool sendInProgress; XP_Bool sendInProgress;
XP_Bool sendPending; XP_Bool sendPending;
} vol; } vol;
@ -79,6 +75,10 @@ typedef struct PalmBTStuff {
PBT_STATE p_connState; PBT_STATE p_connState;
BtLibAccessibleModeEnum accState; BtLibAccessibleModeEnum accState;
XP_U16 queueCur;
XP_U16 queueNext;
PBT_ACTION actQueue[PBT_MAX_ACTS];
union { union {
struct { struct {
} slave; } slave;
@ -86,9 +86,6 @@ typedef struct PalmBTStuff {
BtLibSocketRef listenSocket; BtLibSocketRef listenSocket;
} master; } master;
} u; } u;
BtLibSdpRecordHandle sdpRecordH;
} PalmBTStuff; } PalmBTStuff;
#ifdef DEBUG #ifdef DEBUG
@ -380,24 +377,6 @@ pbt_setup_master( PalmBTStuff* btStuff )
CALL_ERR( err, BtLibSocketListen, btStuff->btLibRefNum, CALL_ERR( err, BtLibSocketListen, btStuff->btLibRefNum,
btStuff->u.master.listenSocket, &listenInfo ); btStuff->u.master.listenSocket, &listenInfo );
/* 3. BtLibSdpServiceRecordCreate: allocate a memory chunk that
represents an SDP service record. */
CALL_ERR( err, BtLibSdpServiceRecordCreate,
btStuff->btLibRefNum, &btStuff->sdpRecordH );
/* 4. BtLibSdpServiceRecordSetAttributesForSocket: initialize an
SDP memory record so it can represent the newly-created L2CAP
listener socket as a service */
CALL_ERR( err, BtLibSdpServiceRecordSetAttributesForSocket,
btStuff->btLibRefNum, btStuff->u.master.listenSocket,
(BtLibSdpUuidType*)&XWORDS_UUID, 1, APPNAME,
StrLen(APPNAME), btStuff->sdpRecordH );
/* 5. BtLibSdpServiceRecordStartAdvertising: make an SDP memory
record representing a local SDP service record visible to
remote devices. */
CALL_ERR( err, BtLibSdpServiceRecordStartAdvertising,
btStuff->btLibRefNum, btStuff->sdpRecordH );
} }
} /* pbt_setup_master */ } /* pbt_setup_master */
@ -417,16 +396,6 @@ pbt_takedown_master( PalmBTStuff* btStuff )
btStuff->dataSocket ); btStuff->dataSocket );
} }
if ( !!btStuff->sdpRecordH ) {
CALL_ERR( err, BtLibSdpServiceRecordStopAdvertising,
btLibRefNum, btStuff->sdpRecordH );
XP_ASSERT( errNone == err ); /* no errors if it was being advertised */
CALL_ERR( err, BtLibSdpServiceRecordDestroy, btLibRefNum,
btStuff->sdpRecordH );
btStuff->sdpRecordH = NULL;
}
if ( SOCK_INVAL != btStuff->u.master.listenSocket ) { if ( SOCK_INVAL != btStuff->u.master.listenSocket ) {
CALL_ERR( err, BtLibSocketClose, btLibRefNum, CALL_ERR( err, BtLibSocketClose, btLibRefNum,
btStuff->u.master.listenSocket ); btStuff->u.master.listenSocket );
@ -442,8 +411,8 @@ pbt_do_work( PalmBTStuff* btStuff )
PBT_ACTION act; PBT_ACTION act;
Err err; Err err;
act = btStuff->vol.actQueue[btStuff->vol.queueCur++]; act = btStuff->actQueue[btStuff->queueCur++];
btStuff->vol.queueCur %= PBT_MAX_ACTS; btStuff->queueCur %= PBT_MAX_ACTS;
XP_LOGF( "%s: evt=%s; state=%s", __FUNCTION__, actToStr(act), XP_LOGF( "%s: evt=%s; state=%s", __FUNCTION__, actToStr(act),
stateToStr(GET_STATE(btStuff)) ); stateToStr(GET_STATE(btStuff)) );
@ -454,18 +423,18 @@ pbt_do_work( PalmBTStuff* btStuff )
/* sends btLibManagementEventACLConnectOutbound */ /* sends btLibManagementEventACLConnectOutbound */
CALL_ERR( err, BtLibLinkConnect, btStuff->btLibRefNum, CALL_ERR( err, BtLibLinkConnect, btStuff->btLibRefNum,
&btStuff->otherAddr ); &btStuff->otherAddr );
SET_STATE( btStuff, PBTST_ACL_CONNECTING ); if ( btLibErrPending == err ) {
} else { SET_STATE( btStuff, PBTST_ACL_CONNECTING );
err = btLibErrAlreadyConnected; } else if ( btLibErrAlreadyConnected == err ) {
} SET_STATE( btStuff, PBTST_ACL_CONNECTED );
if ( btLibErrAlreadyConnected == err ) { pbt_postpone( btStuff, PBT_ACT_CONNECT_L2C );
pbt_postpone( btStuff, PBT_ACT_CONNECT_L2C ); }
} }
break; break;
case PBT_ACT_CONNECT_L2C: case PBT_ACT_CONNECT_L2C:
if ( GET_STATE(btStuff) == PBTST_ACL_CONNECTED ) { if ( GET_STATE(btStuff) == PBTST_ACL_CONNECTED ) {
XP_ASSERT( SOCK_INVAL == btStuff->dataSocket ); XP_ASSERT( SOCK_INVAL == btStuff->dataSocket ); /* fired */
CALL_ERR( err, BtLibSocketCreate, btStuff->btLibRefNum, CALL_ERR( err, BtLibSocketCreate, btStuff->btLibRefNum,
&btStuff->dataSocket, &btStuff->dataSocket,
l2SocketCallback, (UInt32)btStuff, l2SocketCallback, (UInt32)btStuff,
@ -481,7 +450,14 @@ pbt_do_work( PalmBTStuff* btStuff )
/* sends btLibSocketEventConnectedOutbound */ /* sends btLibSocketEventConnectedOutbound */
CALL_ERR( err, BtLibSocketConnect, btStuff->btLibRefNum, CALL_ERR( err, BtLibSocketConnect, btStuff->btLibRefNum,
btStuff->dataSocket, &connInfo ); btStuff->dataSocket, &connInfo );
SET_STATE( btStuff, PBTST_L2C_CONNECTING ); if ( errNone == err ) {
SET_STATE( btStuff, PBTST_L2C_CONNECTED );
} else if ( btLibErrPending == err ) {
SET_STATE( btStuff, PBTST_L2C_CONNECTING );
} else {
SET_STATE( btStuff, PBTST_NONE );
pbt_postpone( btStuff, PBT_ACT_CONNECT_ACL );
}
} else { } else {
btStuff->dataSocket = SOCK_INVAL; btStuff->dataSocket = SOCK_INVAL;
} }
@ -511,9 +487,9 @@ pbt_postpone( PalmBTStuff* btStuff, PBT_ACTION act )
XP_LOGF( "%s(%s)", __FUNCTION__, actToStr(act) ); XP_LOGF( "%s(%s)", __FUNCTION__, actToStr(act) );
EvtAddEventToQueue( &eventToPost ); EvtAddEventToQueue( &eventToPost );
btStuff->vol.actQueue[ btStuff->vol.queueNext++ ] = act; btStuff->actQueue[ btStuff->queueNext++ ] = act;
btStuff->vol.queueNext %= PBT_MAX_ACTS; btStuff->queueNext %= PBT_MAX_ACTS;
XP_ASSERT( btStuff->vol.queueNext != btStuff->vol.queueCur ); XP_ASSERT( btStuff->queueNext != btStuff->queueCur );
} }
static void static void
@ -666,8 +642,11 @@ pbt_killL2C( PalmBTStuff* btStuff, BtLibSocketRef sock )
} }
/* Harm in calling this when not connected? */ /* Harm in calling this when not connected? */
CALL_ERR( err, BtLibLinkDisconnect, btLibRefNum, &btStuff->otherAddr ); if ( GET_STATE(btStuff) != PBTST_NONE ) {
SET_STATE( btStuff, PBTST_NONE ); SET_STATE( btStuff, PBTST_NONE ); /* set first */
/* sends btLibManagementEventACLDisconnect */
CALL_ERR( err, BtLibLinkDisconnect, btLibRefNum, &btStuff->otherAddr );
}
} /* pbt_killL2C */ } /* pbt_killL2C */
static void static void
@ -750,6 +729,16 @@ l2SocketCallback( BtLibSocketEventType* sEvent, UInt32 refCon )
} }
break; break;
case btLibL2DiscConnPsmUnsupported:
/* Probably need to warn the user when this happens since not having
established trust will be a common error. Or: figure out if
there's a way to fall back and establish trust programatically.
For alpha just do the error message. :-) Also, no point in
continuing to try to connect. User will have to quit in order to
establish trust. So warn once per inited session. */
XP_LOGF( "Crosswords not running on host or host not trusted." );
break;
default: default:
break; break;
} }
@ -782,14 +771,14 @@ libMgmtCallback( BtLibManagementEventType* mEvent, UInt32 refCon )
XP_LOGF( "successful ACL connection to master!" ); XP_LOGF( "successful ACL connection to master!" );
pbt_postpone( btStuff, PBT_ACT_CONNECT_L2C ); pbt_postpone( btStuff, PBT_ACT_CONNECT_L2C );
} else { } else {
SET_STATE(btStuff, PBTST_NONE); SET_STATE( btStuff, PBTST_NONE );
pbt_postpone( btStuff, PBT_ACT_CONNECT_ACL ); pbt_postpone( btStuff, PBT_ACT_CONNECT_ACL );
} }
break; break;
case btLibManagementEventACLConnectInbound: case btLibManagementEventACLConnectInbound:
if ( btLibErrNoError == mEvent->status ) { if ( btLibErrNoError == mEvent->status ) {
SET_STATE(btStuff, PBTST_ACL_CONNECTED); SET_STATE( btStuff, PBTST_ACL_CONNECTED );
XP_LOGF( "successful ACL connection!" ); XP_LOGF( "successful ACL connection!" );
XP_MEMCPY( &btStuff->otherAddr, XP_MEMCPY( &btStuff->otherAddr,
&mEvent->eventData.bdAddr, &mEvent->eventData.bdAddr,
@ -797,6 +786,7 @@ libMgmtCallback( BtLibManagementEventType* mEvent, UInt32 refCon )
} }
break; break;
case btLibManagementEventACLDisconnect: case btLibManagementEventACLDisconnect:
/* This is getting called from inside the BtLibLinkDisconnect call!!!! */
XP_ASSERT( 0 == XP_MEMCMP( &mEvent->eventData.bdAddr, XP_ASSERT( 0 == XP_MEMCMP( &mEvent->eventData.bdAddr,
&btStuff->otherAddr, &btStuff->otherAddr,
sizeof(btStuff->otherAddr) ) ); sizeof(btStuff->otherAddr) ) );
@ -805,7 +795,7 @@ libMgmtCallback( BtLibManagementEventType* mEvent, UInt32 refCon )
btStuff->dataSocket ); btStuff->dataSocket );
btStuff->dataSocket = SOCK_INVAL; btStuff->dataSocket = SOCK_INVAL;
} }
SET_STATE(btStuff, PBTST_NONE); SET_STATE( btStuff, PBTST_NONE );
/* See comment at btLibSocketEventDisconnected */ /* See comment at btLibSocketEventDisconnected */
if ( PBT_SLAVE == btStuff->setState ) { if ( PBT_SLAVE == btStuff->setState ) {
pbt_postpone( btStuff, PBT_ACT_CONNECT_ACL ); pbt_postpone( btStuff, PBT_ACT_CONNECT_ACL );