mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
Add code, disabled in Makefile, to use rfcomm rather than l2cap for
data with the goal of detecting disconnects more quickly. Stops working after a few packets (client only tested against host on linux so far), and doesn't compile for ARM yet, but the framework is there. Am framing packets on Palm side which may not be necessary.
This commit is contained in:
parent
bcb25d96b2
commit
0cdd8a41c4
2 changed files with 232 additions and 58 deletions
|
@ -115,8 +115,9 @@ MYDEFS_COMMON += -DXWFEATURE_SEARCHLIMIT
|
||||||
# experimental at this point!
|
# experimental at this point!
|
||||||
# MYDEFS_COMMON += -DXWFEATURE_RELAY
|
# MYDEFS_COMMON += -DXWFEATURE_RELAY
|
||||||
|
|
||||||
# turn on bluetooth comms option for 68K and ARM -- which won't work yet
|
# turn on bluetooth comms option for 68K and ARM
|
||||||
BLUETOOTH = -DXWFEATURE_BLUETOOTH
|
BLUETOOTH = -DXWFEATURE_BLUETOOTH -DBT_USE_L2CAP
|
||||||
|
#BLUETOOTH = -DXWFEATURE_BLUETOOTH -DBT_USE_RFCOMM
|
||||||
MYDEFS_COMMON += $(BLUETOOTH)
|
MYDEFS_COMMON += $(BLUETOOTH)
|
||||||
|
|
||||||
# Add menu allowing to choose to run 68K or ARM
|
# Add menu allowing to choose to run 68K or ARM
|
||||||
|
|
285
palm/palmbt.c
285
palm/palmbt.c
|
@ -27,6 +27,14 @@
|
||||||
# include <BtLib.h>
|
# include <BtLib.h>
|
||||||
# include <BtLibTypes.h>
|
# include <BtLibTypes.h>
|
||||||
|
|
||||||
|
#if defined BT_USE_L2CAP
|
||||||
|
# define SEL_PROTO btLibL2CapProtocol
|
||||||
|
# define TRUE_IF_RFCOMM XP_FALSE
|
||||||
|
#elif defined BT_USE_RFCOMM
|
||||||
|
# define SEL_PROTO btLibRfCommProtocol
|
||||||
|
# define TRUE_IF_RFCOMM XP_TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
#define L2CAPSOCKETMTU 500
|
#define L2CAPSOCKETMTU 500
|
||||||
#define SOCK_INVAL ((BtLibSocketRef)-1)
|
#define SOCK_INVAL ((BtLibSocketRef)-1)
|
||||||
|
|
||||||
|
@ -40,7 +48,7 @@ typedef enum {
|
||||||
, PBT_ACT_SETUP_LISTEN
|
, PBT_ACT_SETUP_LISTEN
|
||||||
, PBT_ACT_CONNECT_ACL
|
, PBT_ACT_CONNECT_ACL
|
||||||
, PBT_ACT_GETSDP /* slave only */
|
, PBT_ACT_GETSDP /* slave only */
|
||||||
, PBT_ACT_CONNECT_L2C
|
, PBT_ACT_CONNECT_DATA /* l2cap or rfcomm */
|
||||||
, PBT_ACT_TELLCONN
|
, PBT_ACT_TELLCONN
|
||||||
, PBT_ACT_TELLNOHOST
|
, PBT_ACT_TELLNOHOST
|
||||||
, PBT_ACT_GOTDATA /* can be duplicated */
|
, PBT_ACT_GOTDATA /* can be duplicated */
|
||||||
|
@ -56,8 +64,8 @@ typedef enum {
|
||||||
, PBTST_ACL_CONNECTED /* slave */
|
, PBTST_ACL_CONNECTED /* slave */
|
||||||
, PBTST_SDP_QUERYING /* slave */
|
, PBTST_SDP_QUERYING /* slave */
|
||||||
, PBTST_SDP_QUERIED /* slave */
|
, PBTST_SDP_QUERIED /* slave */
|
||||||
, PBTST_L2C_CONNECTING /* slave */
|
, PBTST_DATA_CONNECTING /* slave; l2cap or rfcomm */
|
||||||
, PBTST_L2C_CONNECTED /* slave */
|
, PBTST_DATA_CONNECTED /* slave; l2cap or rfcomm */
|
||||||
} PBT_STATE;
|
} PBT_STATE;
|
||||||
|
|
||||||
#define PBT_MAX_ACTS 8 /* six wasn't enough */
|
#define PBT_MAX_ACTS 8 /* six wasn't enough */
|
||||||
|
@ -94,7 +102,11 @@ typedef struct PalmBTStuff {
|
||||||
|
|
||||||
struct /*union*/ {
|
struct /*union*/ {
|
||||||
struct {
|
struct {
|
||||||
|
#if defined BT_USE_L2CAP
|
||||||
BtLibL2CapPsmType remotePsm;
|
BtLibL2CapPsmType remotePsm;
|
||||||
|
#elif defined BT_USE_RFCOMM
|
||||||
|
BtLibRfCommServerIdType remoteService;
|
||||||
|
#endif
|
||||||
BtLibSocketRef sdpSocket;
|
BtLibSocketRef sdpSocket;
|
||||||
} slave;
|
} slave;
|
||||||
struct {
|
struct {
|
||||||
|
@ -140,8 +152,9 @@ static void pbt_setup_master( PalmBTStuff* btStuff );
|
||||||
static void pbt_takedown_master( PalmBTStuff* btStuff );
|
static void pbt_takedown_master( PalmBTStuff* btStuff );
|
||||||
static void pbt_do_work( PalmBTStuff* btStuff, BtCbEvtProc proc );
|
static void pbt_do_work( PalmBTStuff* btStuff, BtCbEvtProc proc );
|
||||||
static void pbt_postpone( PalmBTStuff* btStuff, PBT_ACTION act );
|
static void pbt_postpone( PalmBTStuff* btStuff, PBT_ACTION act );
|
||||||
static XP_S16 pbt_enque( PBT_queue* queue, const XP_U8* data, XP_S16 len );
|
static XP_S16 pbt_enqueue( PBT_queue* queue, const XP_U8* data, XP_S16 len,
|
||||||
static void pbt_processIncoming( PalmBTStuff* btStuff, BtCbEvtProc proc );
|
XP_Bool addLen, XP_Bool append );
|
||||||
|
static void pbt_handoffIncoming( PalmBTStuff* btStuff, BtCbEvtProc proc );
|
||||||
|
|
||||||
static void waitACL( PalmBTStuff* btStuff );
|
static void waitACL( PalmBTStuff* btStuff );
|
||||||
static void pbt_reset( PalmBTStuff* btStuff );
|
static void pbt_reset( PalmBTStuff* btStuff );
|
||||||
|
@ -268,10 +281,10 @@ palm_bt_doWork( PalmAppGlobals* globals, BtCbEvtProc proc, BtUIState* btUIStateP
|
||||||
case PBTST_ACL_CONNECTED:
|
case PBTST_ACL_CONNECTED:
|
||||||
case PBTST_SDP_QUERYING:
|
case PBTST_SDP_QUERYING:
|
||||||
case PBTST_SDP_QUERIED:
|
case PBTST_SDP_QUERIED:
|
||||||
case PBTST_L2C_CONNECTING:
|
case PBTST_DATA_CONNECTING:
|
||||||
btUIState = BTUI_CONNECTING;
|
btUIState = BTUI_CONNECTING;
|
||||||
break;
|
break;
|
||||||
case PBTST_L2C_CONNECTED:
|
case PBTST_DATA_CONNECTED:
|
||||||
btUIState = btStuff->picoRole == PBT_MASTER?
|
btUIState = btStuff->picoRole == PBT_MASTER?
|
||||||
BTUI_SERVING : BTUI_CONNECTED;
|
BTUI_SERVING : BTUI_CONNECTED;
|
||||||
break;
|
break;
|
||||||
|
@ -387,6 +400,7 @@ pbt_peekQueue( const PBT_queue* queue, const XP_U8** bufp )
|
||||||
if ( len > 0 ) {
|
if ( len > 0 ) {
|
||||||
*bufp = &queue->bufs[0];
|
*bufp = &queue->bufs[0];
|
||||||
}
|
}
|
||||||
|
LOG_RETURNF( "%d", len );
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,15 +423,11 @@ pbt_send_pending( PalmBTStuff* btStuff )
|
||||||
Err err;
|
Err err;
|
||||||
LOG_FUNC();
|
LOG_FUNC();
|
||||||
|
|
||||||
if ( !btStuff->vol.sendInProgress ) {
|
if ( !btStuff->vol.sendInProgress && (SOCK_INVAL != btStuff->dataSocket)) {
|
||||||
const XP_U8* buf;
|
const XP_U8* buf;
|
||||||
XP_U16 len = pbt_peekQueue( &btStuff->vol.out, &buf );
|
XP_U16 len = pbt_peekQueue( &btStuff->vol.out, &buf );
|
||||||
|
if ( len > 0 ) {
|
||||||
if ( SOCK_INVAL == btStuff->dataSocket ) {
|
LOG_HEX( buf, len, __func__ );
|
||||||
/* XP_LOGF( "%s: abort: inval socket", __func__ ); */
|
|
||||||
} else if ( len <= 0 ) {
|
|
||||||
/* XP_LOGF( "%s: abort: len is %d", __func__, len ); */
|
|
||||||
} else {
|
|
||||||
CALL_ERR( err, BtLibSocketSend, btStuff->btLibRefNum,
|
CALL_ERR( err, BtLibSocketSend, btStuff->btLibRefNum,
|
||||||
btStuff->dataSocket, (char*)buf, len );
|
btStuff->dataSocket, (char*)buf, len );
|
||||||
if ( btLibErrPending == err ) {
|
if ( btLibErrPending == err ) {
|
||||||
|
@ -428,6 +438,24 @@ pbt_send_pending( PalmBTStuff* btStuff )
|
||||||
LOG_RETURN_VOID();
|
LOG_RETURN_VOID();
|
||||||
} /* pbt_send_pending */
|
} /* pbt_send_pending */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static void
|
||||||
|
dump_queue( PBT_queue* queue, const char* caller )
|
||||||
|
{
|
||||||
|
XP_U16 i, total = 0;
|
||||||
|
LOG_FUNC();
|
||||||
|
for ( i = 0; ; ++i ) {
|
||||||
|
XP_U16 len = queue->lens[i];
|
||||||
|
if ( 0 == len ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
XP_LOGF( "buffer %d (len %d):", i, len );
|
||||||
|
LOG_HEX( &queue->bufs[total], len, "" );
|
||||||
|
total += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
XP_S16
|
XP_S16
|
||||||
palm_bt_send( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addr,
|
palm_bt_send( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addr,
|
||||||
PalmAppGlobals* globals, XP_Bool* userCancelled )
|
PalmAppGlobals* globals, XP_Bool* userCancelled )
|
||||||
|
@ -461,7 +489,7 @@ palm_bt_send( const XP_U8* buf, XP_U16 len, const CommsAddrRec* addr,
|
||||||
pbt_setup_slave( btStuff, addr );
|
pbt_setup_slave( btStuff, addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
nSent = pbt_enque( &btStuff->vol.out, buf, len );
|
nSent = pbt_enqueue( &btStuff->vol.out, buf, len, TRUE_IF_RFCOMM, XP_FALSE );
|
||||||
pbt_send_pending( btStuff );
|
pbt_send_pending( btStuff );
|
||||||
}
|
}
|
||||||
LOG_RETURNF( "%d", nSent );
|
LOG_RETURNF( "%d", nSent );
|
||||||
|
@ -522,14 +550,20 @@ pbt_setup_master( PalmBTStuff* btStuff )
|
||||||
/* 1. BtLibSocketCreate: create an L2CAP socket. */
|
/* 1. BtLibSocketCreate: create an L2CAP socket. */
|
||||||
CALL_ERR( err, BtLibSocketCreate, btStuff->btLibRefNum,
|
CALL_ERR( err, BtLibSocketCreate, btStuff->btLibRefNum,
|
||||||
&btStuff->u.master.listenSocket, socketCallback,
|
&btStuff->u.master.listenSocket, socketCallback,
|
||||||
(UInt32)btStuff, btLibL2CapProtocol );
|
(UInt32)btStuff, SEL_PROTO );
|
||||||
XP_ASSERT( errNone == err );
|
XP_ASSERT( errNone == err );
|
||||||
|
|
||||||
/* 2. BtLibSocketListen: set up an L2CAP socket as a listener. */
|
/* 2. BtLibSocketListen: set up an L2CAP socket as a listener. */
|
||||||
XP_MEMSET( &listenInfo, 0, sizeof(listenInfo) );
|
XP_MEMSET( &listenInfo, 0, sizeof(listenInfo) );
|
||||||
|
#if defined BT_USE_L2CAP
|
||||||
listenInfo.data.L2Cap.localPsm = BT_L2CAP_RANDOM_PSM;
|
listenInfo.data.L2Cap.localPsm = BT_L2CAP_RANDOM_PSM;
|
||||||
listenInfo.data.L2Cap.localMtu = L2CAPSOCKETMTU;
|
listenInfo.data.L2Cap.localMtu = L2CAPSOCKETMTU;
|
||||||
listenInfo.data.L2Cap.minRemoteMtu = L2CAPSOCKETMTU;
|
listenInfo.data.L2Cap.minRemoteMtu = L2CAPSOCKETMTU;
|
||||||
|
#elif defined BT_USE_RFCOMM
|
||||||
|
// remoteService: assigned by rfcomm
|
||||||
|
listenInfo.data.RfComm.maxFrameSize = BT_RF_DEFAULT_FRAMESIZE;
|
||||||
|
listenInfo.data.RfComm.advancedCredit = 10;
|
||||||
|
#endif
|
||||||
/* Doesn't send events; returns errNone unless no resources avail. */
|
/* Doesn't send events; returns errNone unless no resources avail. */
|
||||||
CALL_ERR( err, BtLibSocketListen, btStuff->btLibRefNum,
|
CALL_ERR( err, BtLibSocketListen, btStuff->btLibRefNum,
|
||||||
btStuff->u.master.listenSocket, &listenInfo );
|
btStuff->u.master.listenSocket, &listenInfo );
|
||||||
|
@ -543,10 +577,6 @@ pbt_setup_master( PalmBTStuff* btStuff )
|
||||||
btStuff->u.master.listenSocket = SOCK_INVAL;
|
btStuff->u.master.listenSocket = SOCK_INVAL;
|
||||||
pbt_postpone( btStuff, PBT_ACT_SETUP_LISTEN );
|
pbt_postpone( btStuff, PBT_ACT_SETUP_LISTEN );
|
||||||
}
|
}
|
||||||
} else if ( PBTST_NONE == GET_STATE(btStuff) ) {
|
|
||||||
SET_STATE( btStuff, PBTST_LISTENING );
|
|
||||||
} else {
|
|
||||||
XP_LOGF( "listen socket is set" );
|
|
||||||
}
|
}
|
||||||
XP_ASSERT( NULL != btStuff->u.master.sdpRecordH );
|
XP_ASSERT( NULL != btStuff->u.master.sdpRecordH );
|
||||||
} /* pbt_setup_master */
|
} /* pbt_setup_master */
|
||||||
|
@ -658,12 +688,19 @@ pbt_do_work( PalmBTStuff* btStuff, BtCbEvtProc proc )
|
||||||
&btStuff->u.slave.sdpSocket, socketCallback, (UInt32)btStuff,
|
&btStuff->u.slave.sdpSocket, socketCallback, (UInt32)btStuff,
|
||||||
btLibSdpProtocol );
|
btLibSdpProtocol );
|
||||||
if ( err == errNone ) {
|
if ( err == errNone ) {
|
||||||
|
#if defined BT_USE_L2CAP
|
||||||
CALL_ERR( err, BtLibSdpGetPsmByUuid, btStuff->btLibRefNum,
|
CALL_ERR( err, BtLibSdpGetPsmByUuid, btStuff->btLibRefNum,
|
||||||
btStuff->u.slave.sdpSocket, &btStuff->otherAddr,
|
btStuff->u.slave.sdpSocket, &btStuff->otherAddr,
|
||||||
(BtLibSdpUuidType*)&XWORDS_UUID, 1 );
|
(BtLibSdpUuidType*)&XWORDS_UUID, 1 );
|
||||||
|
#elif defined BT_USE_RFCOMM
|
||||||
|
CALL_ERR( err, BtLibSdpGetServerChannelByUuid,
|
||||||
|
btStuff->btLibRefNum, btStuff->u.slave.sdpSocket,
|
||||||
|
&btStuff->otherAddr,
|
||||||
|
(BtLibSdpUuidType*)&XWORDS_UUID, 1 );
|
||||||
|
#endif
|
||||||
if ( err == errNone ) {
|
if ( err == errNone ) {
|
||||||
SET_STATE( btStuff, PBTST_SDP_QUERIED );
|
SET_STATE( btStuff, PBTST_SDP_QUERIED );
|
||||||
pbt_postpone( btStuff, PBT_ACT_CONNECT_L2C );
|
pbt_postpone( btStuff, PBT_ACT_CONNECT_DATA );
|
||||||
break;
|
break;
|
||||||
} else if ( err == btLibErrPending ) {
|
} else if ( err == btLibErrPending ) {
|
||||||
SET_STATE( btStuff, PBTST_SDP_QUERYING );
|
SET_STATE( btStuff, PBTST_SDP_QUERYING );
|
||||||
|
@ -681,29 +718,36 @@ pbt_do_work( PalmBTStuff* btStuff, BtCbEvtProc proc )
|
||||||
waitACL( btStuff );
|
waitACL( btStuff );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PBT_ACT_CONNECT_L2C:
|
case PBT_ACT_CONNECT_DATA:
|
||||||
/* XP_ASSERT( btStuff->picoRole == PBT_SLAVE ); */
|
/* XP_ASSERT( btStuff->picoRole == PBT_SLAVE ); */
|
||||||
if ( GET_STATE(btStuff) == PBTST_SDP_QUERIED ) {
|
if ( GET_STATE(btStuff) == PBTST_SDP_QUERIED ) {
|
||||||
pbt_close_datasocket( btStuff );
|
pbt_close_datasocket( btStuff );
|
||||||
CALL_ERR( err, BtLibSocketCreate, btLibRefNum,
|
CALL_ERR( err, BtLibSocketCreate, btLibRefNum,
|
||||||
&btStuff->dataSocket,
|
&btStuff->dataSocket,
|
||||||
socketCallback, (UInt32)btStuff,
|
socketCallback, (UInt32)btStuff, SEL_PROTO );
|
||||||
btLibL2CapProtocol );
|
|
||||||
|
|
||||||
if ( btLibErrNoError == err ) {
|
if ( btLibErrNoError == err ) {
|
||||||
BtLibSocketConnectInfoType connInfo;
|
BtLibSocketConnectInfoType connInfo;
|
||||||
|
connInfo.remoteDeviceP = &btStuff->otherAddr;
|
||||||
|
#if defined BT_USE_L2CAP
|
||||||
connInfo.data.L2Cap.remotePsm = btStuff->u.slave.remotePsm;
|
connInfo.data.L2Cap.remotePsm = btStuff->u.slave.remotePsm;
|
||||||
connInfo.data.L2Cap.localMtu = L2CAPSOCKETMTU;
|
connInfo.data.L2Cap.localMtu = L2CAPSOCKETMTU;
|
||||||
connInfo.data.L2Cap.minRemoteMtu = L2CAPSOCKETMTU;
|
connInfo.data.L2Cap.minRemoteMtu = L2CAPSOCKETMTU;
|
||||||
connInfo.remoteDeviceP = &btStuff->otherAddr;
|
#elif defined BT_USE_RFCOMM
|
||||||
|
connInfo.data.RfComm.remoteService
|
||||||
|
= btStuff->u.slave.remoteService;
|
||||||
|
connInfo.data.RfComm.maxFrameSize = BT_RF_DEFAULT_FRAMESIZE;
|
||||||
|
connInfo.data.RfComm.advancedCredit = 10;
|
||||||
|
#else
|
||||||
|
XP_ASSERT(0);
|
||||||
|
#endif
|
||||||
/* sends btLibSocketEventConnectedOutbound */
|
/* sends btLibSocketEventConnectedOutbound */
|
||||||
CALL_ERR( err, BtLibSocketConnect, btLibRefNum,
|
CALL_ERR( err, BtLibSocketConnect, btLibRefNum,
|
||||||
btStuff->dataSocket, &connInfo );
|
btStuff->dataSocket, &connInfo );
|
||||||
if ( errNone == err ) {
|
if ( errNone == err ) {
|
||||||
SET_STATE( btStuff, PBTST_L2C_CONNECTED );
|
SET_STATE( btStuff, PBTST_DATA_CONNECTED );
|
||||||
} else if ( btLibErrPending == err ) {
|
} else if ( btLibErrPending == err ) {
|
||||||
SET_STATE( btStuff, PBTST_L2C_CONNECTING );
|
SET_STATE( btStuff, PBTST_DATA_CONNECTING );
|
||||||
} else {
|
} else {
|
||||||
SET_STATE( btStuff, PBTST_NONE );
|
SET_STATE( btStuff, PBTST_NONE );
|
||||||
waitACL( btStuff );
|
waitACL( btStuff );
|
||||||
|
@ -716,7 +760,7 @@ pbt_do_work( PalmBTStuff* btStuff, BtCbEvtProc proc )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PBT_ACT_GOTDATA:
|
case PBT_ACT_GOTDATA:
|
||||||
pbt_processIncoming( btStuff, proc );
|
pbt_handoffIncoming( btStuff, proc );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PBT_ACT_TRYSEND:
|
case PBT_ACT_TRYSEND:
|
||||||
|
@ -763,12 +807,11 @@ pbt_postpone( PalmBTStuff* btStuff, PBT_ACTION act )
|
||||||
debug_logQueue( btStuff );
|
debug_logQueue( btStuff );
|
||||||
}
|
}
|
||||||
|
|
||||||
static XP_S16
|
static void
|
||||||
pbt_enque( PBT_queue* queue, const XP_U8* data, XP_S16 len )
|
getSizeIndex( PBT_queue* queue, XP_U16* index, XP_U16* totalP )
|
||||||
{
|
{
|
||||||
XP_U16 i;
|
XP_U16 i;
|
||||||
XP_U16 total = 0;
|
XP_U16 total = 0;
|
||||||
|
|
||||||
for ( i = 0; i < MAX_PACKETS; ++i ) {
|
for ( i = 0; i < MAX_PACKETS; ++i ) {
|
||||||
XP_U16 curlen = queue->lens[i];
|
XP_U16 curlen = queue->lens[i];
|
||||||
if ( !curlen ) {
|
if ( !curlen ) {
|
||||||
|
@ -776,26 +819,64 @@ pbt_enque( PBT_queue* queue, const XP_U8* data, XP_S16 len )
|
||||||
}
|
}
|
||||||
total += curlen;
|
total += curlen;
|
||||||
}
|
}
|
||||||
|
XP_LOGF( "%s=>index:%d, total: %d", __func__, i, total );
|
||||||
|
*index = i;
|
||||||
|
*totalP = total;
|
||||||
|
} /* getSizeIndex */
|
||||||
|
|
||||||
if ( (i < MAX_PACKETS) && ((total + len) < sizeof(queue->bufs)) ) {
|
static XP_S16
|
||||||
queue->lens[i] = len;
|
pbt_enqueue( PBT_queue* queue, const XP_U8* data, const XP_S16 len,
|
||||||
|
XP_Bool addLen, XP_Bool append )
|
||||||
|
{
|
||||||
|
XP_S16 result;
|
||||||
|
XP_U16 index;
|
||||||
|
XP_U16 total = 0;
|
||||||
|
XP_U16 lensiz = 0;
|
||||||
|
|
||||||
|
XP_ASSERT( len > 0 || !addLen );
|
||||||
|
|
||||||
|
if ( addLen ) {
|
||||||
|
lensiz = sizeof(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSizeIndex( queue, &index, &total );
|
||||||
|
|
||||||
|
if ( append ) {
|
||||||
|
XP_ASSERT( index > 0 );
|
||||||
|
--index;
|
||||||
|
} else {
|
||||||
|
queue->lens[index] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (index < MAX_PACKETS) && ((total + len + lensiz) < sizeof(queue->bufs)) ) {
|
||||||
|
queue->lens[index] += len + lensiz;
|
||||||
|
if ( addLen ) {
|
||||||
|
XP_U16 plen = XP_HTONS(len);
|
||||||
|
XP_LOGF( "writing plen: %x", plen );
|
||||||
|
XP_MEMCPY( &queue->bufs[total], &plen, sizeof(plen) );
|
||||||
|
total += sizeof(plen);
|
||||||
|
}
|
||||||
XP_MEMCPY( &queue->bufs[total], data, len );
|
XP_MEMCPY( &queue->bufs[total], data, len );
|
||||||
/* XP_LOGF( "%s: adding %d; total now %d (%d packets)",
|
/* XP_LOGF( "%s: adding %d; total now %d (%d packets)",
|
||||||
__FUNCTION__, */
|
__FUNCTION__, */
|
||||||
/* len, len+total, i+1 ); */
|
/* len, len+total, i+1 ); */
|
||||||
|
result = len;
|
||||||
} else {
|
} else {
|
||||||
XP_LOGF( "%s: dropping packet of len %d", __FUNCTION__, len );
|
XP_LOGF( "%s: dropping packet of len %d", __FUNCTION__, len );
|
||||||
len = -1;
|
result = -1;
|
||||||
}
|
}
|
||||||
return len;
|
dump_queue( queue, __func__ );
|
||||||
} /* pbt_enque */
|
return result;
|
||||||
|
} /* pbt_enqueue */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pbt_processIncoming( PalmBTStuff* btStuff, BtCbEvtProc proc )
|
pbt_handoffIncoming( PalmBTStuff* btStuff, BtCbEvtProc proc )
|
||||||
{
|
{
|
||||||
const XP_U8* buf;
|
const XP_U8* buf;
|
||||||
|
XP_U16 len;
|
||||||
XP_U16 len = pbt_peekQueue( &btStuff->vol.in, &buf );
|
|
||||||
|
dump_queue( &btStuff->vol.in, __func__ );
|
||||||
|
len = pbt_peekQueue( &btStuff->vol.in, &buf );
|
||||||
|
|
||||||
if ( len > 0 ) {
|
if ( len > 0 ) {
|
||||||
BtCbEvtInfo info;
|
BtCbEvtInfo info;
|
||||||
|
@ -809,13 +890,20 @@ pbt_processIncoming( PalmBTStuff* btStuff, BtCbEvtProc proc )
|
||||||
|
|
||||||
info.evt = BTCBEVT_DATA;
|
info.evt = BTCBEVT_DATA;
|
||||||
info.u.data.fromAddr = &fromAddr;
|
info.u.data.fromAddr = &fromAddr;
|
||||||
|
#ifdef BT_USE_RFCOMM
|
||||||
|
XP_LOGF( "plen=%d; len=%d", *(XP_U16*)buf, len-2 );
|
||||||
|
XP_ASSERT( *(XP_U16*)buf == len - sizeof(XP_U16) ); /* firing */
|
||||||
|
info.u.data.len = len - sizeof(XP_U16);
|
||||||
|
info.u.data.data = buf + sizeof(XP_U16);
|
||||||
|
#else
|
||||||
info.u.data.len = len;
|
info.u.data.len = len;
|
||||||
info.u.data.data = buf;
|
info.u.data.data = buf;
|
||||||
|
#endif
|
||||||
(*proc)( btStuff->globals, &info );
|
(*proc)( btStuff->globals, &info );
|
||||||
|
|
||||||
pbt_shiftQueue( &btStuff->vol.in );
|
pbt_shiftQueue( &btStuff->vol.in );
|
||||||
}
|
}
|
||||||
} /* pbt_processIncoming */
|
} /* pbt_handoffIncoming */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pbt_reset( PalmBTStuff* btStuff )
|
pbt_reset( PalmBTStuff* btStuff )
|
||||||
|
@ -952,7 +1040,7 @@ pbt_killL2C( PalmBTStuff* btStuff, BtLibSocketRef sock )
|
||||||
}
|
}
|
||||||
} /* pbt_killL2C */
|
} /* pbt_killL2C */
|
||||||
|
|
||||||
static XP_Bool
|
static void
|
||||||
pbt_checkAddress( PalmBTStuff* btStuff, const CommsAddrRec* addr )
|
pbt_checkAddress( PalmBTStuff* btStuff, const CommsAddrRec* addr )
|
||||||
{
|
{
|
||||||
XP_Bool addrOk;
|
XP_Bool addrOk;
|
||||||
|
@ -983,6 +1071,78 @@ pbt_setstate( PalmBTStuff* btStuff, PBT_STATE newState, const char* whence )
|
||||||
XP_LOGF( "setting state to %s, from %s", stateToStr(newState), whence );
|
XP_LOGF( "setting state to %s, from %s", stateToStr(newState), whence );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BT_USE_RFCOMM
|
||||||
|
|
||||||
|
static XP_U16
|
||||||
|
pbt_packetPending( PalmBTStuff* btStuff )
|
||||||
|
{
|
||||||
|
XP_U16 pending;
|
||||||
|
XP_U16 index, total;
|
||||||
|
PBT_queue* queue = &btStuff->vol.in;
|
||||||
|
|
||||||
|
/* Packet consists of two bytes of len plus len bytes of data. An
|
||||||
|
incomplete packet has len but less than len bytes of data. When we
|
||||||
|
write the len we add a packet but that's all.
|
||||||
|
|
||||||
|
Total and index get us beyond the last packet written. If index is 0,
|
||||||
|
nothing's been written so packet is pending. Otherwise we can back
|
||||||
|
index off and look at the buffer there. Buffer starts at total - lens[--index].
|
||||||
|
Len will be written there. If lens[index] is less, it's pending.
|
||||||
|
*/
|
||||||
|
getSizeIndex( queue, &index, &total );
|
||||||
|
if ( total < sizeof(XP_U16) ) {
|
||||||
|
XP_ASSERT( total == 0 );
|
||||||
|
pending = 0;
|
||||||
|
} else {
|
||||||
|
XP_U16 curLen, plen;
|
||||||
|
XP_U8* curStart;
|
||||||
|
--index;
|
||||||
|
curLen = queue->lens[index];
|
||||||
|
curStart = &queue->bufs[total-curLen];
|
||||||
|
plen = *(XP_U16*)curStart;
|
||||||
|
pending = plen - (curLen - sizeof(plen));
|
||||||
|
}
|
||||||
|
LOG_RETURNF( "%d", pending );
|
||||||
|
return pending;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pbt_assemble( PalmBTStuff* btStuff, unsigned char* data, XP_U16 len )
|
||||||
|
{
|
||||||
|
XP_U16 bytesPending = pbt_packetPending( btStuff);
|
||||||
|
LOG_FUNC();
|
||||||
|
if ( bytesPending == 0 ) {
|
||||||
|
XP_U16 plen;
|
||||||
|
/* will need to handle case where len comes in separate packets!!!! */
|
||||||
|
XP_ASSERT( len >= sizeof(plen) );
|
||||||
|
plen = *(XP_U16*)data;
|
||||||
|
data += sizeof(plen);
|
||||||
|
len -= sizeof(plen);
|
||||||
|
bytesPending = XP_NTOHS(plen);
|
||||||
|
|
||||||
|
/* Start the packet */
|
||||||
|
pbt_enqueue( &btStuff->vol.in, (XP_U8*)&bytesPending, sizeof(bytesPending),
|
||||||
|
XP_FALSE, XP_FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if len is >= bytesPending, we have a packet. Add bytesPending bytes,
|
||||||
|
then recurse with remaining bytes. If len is < bytesPending, just
|
||||||
|
consume the bytes and return. */
|
||||||
|
pbt_enqueue( &btStuff->vol.in, data, XP_MIN( len, bytesPending ),
|
||||||
|
XP_FALSE, XP_TRUE );
|
||||||
|
|
||||||
|
if ( len >= bytesPending ) {
|
||||||
|
len -= bytesPending;
|
||||||
|
data += bytesPending;
|
||||||
|
pbt_postpone( btStuff, PBT_ACT_GOTDATA );
|
||||||
|
if ( len > 0 ) {
|
||||||
|
pbt_assemble( btStuff, data, len );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dump_queue( &btStuff->vol.in, __func__ );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
socketCallback( BtLibSocketEventType* sEvent, UInt32 refCon )
|
socketCallback( BtLibSocketEventType* sEvent, UInt32 refCon )
|
||||||
{
|
{
|
||||||
|
@ -1006,26 +1166,33 @@ socketCallback( BtLibSocketEventType* sEvent, UInt32 refCon )
|
||||||
btStuff->dataSocket = sEvent->eventData.newSocket;
|
btStuff->dataSocket = sEvent->eventData.newSocket;
|
||||||
XP_LOGF( "we have a data socket!!!" );
|
XP_LOGF( "we have a data socket!!!" );
|
||||||
pbt_postpone( btStuff, PBT_ACT_TELLCONN );
|
pbt_postpone( btStuff, PBT_ACT_TELLCONN );
|
||||||
SET_STATE( btStuff, PBTST_L2C_CONNECTED );
|
SET_STATE( btStuff, PBTST_DATA_CONNECTED );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case btLibSocketEventConnectedOutbound:
|
case btLibSocketEventConnectedOutbound:
|
||||||
if ( errNone == sEvent->status ) {
|
if ( errNone == sEvent->status ) {
|
||||||
SET_STATE( btStuff, PBTST_L2C_CONNECTED );
|
SET_STATE( btStuff, PBTST_DATA_CONNECTED );
|
||||||
pbt_postpone( btStuff, PBT_ACT_TELLCONN );
|
pbt_postpone( btStuff, PBT_ACT_TELLCONN );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case btLibSocketEventData:
|
case btLibSocketEventData:
|
||||||
XP_ASSERT( sEvent->status == errNone );
|
XP_ASSERT( sEvent->status == errNone );
|
||||||
XP_ASSERT( sEvent->socket == btStuff->dataSocket );
|
XP_ASSERT( sEvent->socket == btStuff->dataSocket );
|
||||||
|
{
|
||||||
if ( 0 < pbt_enque( &btStuff->vol.in, sEvent->eventData.data.data,
|
XP_U8* data = sEvent->eventData.data.data;
|
||||||
sEvent->eventData.data.dataLen ) ) {
|
XP_U16 len = sEvent->eventData.data.dataLen;
|
||||||
pbt_postpone( btStuff, PBT_ACT_GOTDATA );
|
LOG_HEX( data, len, "btLibSocketEventData" );
|
||||||
}
|
#if defined BT_USE_RFCOMM
|
||||||
|
pbt_assemble( btStuff, data, len );
|
||||||
|
#else
|
||||||
|
if ( 0 < pbt_enqueue( &btStuff->vol.in, data, len, XP_FALSE, XP_FALSE ) ) {
|
||||||
|
pbt_postpone( btStuff, PBT_ACT_GOTDATA );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
btStuff->stats.totalRcvd += sEvent->eventData.data.dataLen;
|
btStuff->stats.totalRcvd += sEvent->eventData.data.dataLen;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case btLibSocketEventSendComplete:
|
case btLibSocketEventSendComplete:
|
||||||
|
@ -1059,14 +1226,22 @@ socketCallback( BtLibSocketEventType* sEvent, UInt32 refCon )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case btLibSocketEventSdpGetPsmByUuid:
|
case btLibSocketEventSdpGetPsmByUuid:
|
||||||
|
case btLibSocketEventSdpGetServerChannelByUuid:
|
||||||
XP_ASSERT( sEvent->socket == btStuff->u.slave.sdpSocket );
|
XP_ASSERT( sEvent->socket == btStuff->u.slave.sdpSocket );
|
||||||
CALL_ERR( err, BtLibSocketClose, btStuff->btLibRefNum, sEvent->socket );
|
CALL_ERR( err, BtLibSocketClose, btStuff->btLibRefNum, sEvent->socket );
|
||||||
XP_ASSERT( err == errNone );
|
XP_ASSERT( err == errNone );
|
||||||
btStuff->u.slave.sdpSocket = SOCK_INVAL;
|
btStuff->u.slave.sdpSocket = SOCK_INVAL;
|
||||||
if ( sEvent->status == errNone ) {
|
if ( sEvent->status == errNone ) {
|
||||||
|
#if defined BT_USE_L2CAP
|
||||||
btStuff->u.slave.remotePsm = sEvent->eventData.sdpByUuid.param.psm;
|
btStuff->u.slave.remotePsm = sEvent->eventData.sdpByUuid.param.psm;
|
||||||
|
#elif defined BT_USE_RFCOMM
|
||||||
|
btStuff->u.slave.remoteService
|
||||||
|
= sEvent->eventData.sdpByUuid.param.channel;
|
||||||
|
XP_LOGF( "got remoteService of %d",
|
||||||
|
btStuff->u.slave.remoteService );
|
||||||
|
#endif
|
||||||
SET_STATE( btStuff, PBTST_SDP_QUERIED );
|
SET_STATE( btStuff, PBTST_SDP_QUERIED );
|
||||||
pbt_postpone( btStuff, PBT_ACT_CONNECT_L2C );
|
pbt_postpone( btStuff, PBT_ACT_CONNECT_DATA );
|
||||||
} else if ( sEvent->status == btLibErrSdpQueryDisconnect ) {
|
} else if ( sEvent->status == btLibErrSdpQueryDisconnect ) {
|
||||||
/* Maybe we can just ignore this... */
|
/* Maybe we can just ignore this... */
|
||||||
XP_ASSERT( GET_STATE(btStuff) == PBTST_NONE );
|
XP_ASSERT( GET_STATE(btStuff) == PBTST_NONE );
|
||||||
|
@ -1183,8 +1358,8 @@ stateToStr(PBT_STATE st)
|
||||||
CASESTR(PBTST_SDP_QUERYING);
|
CASESTR(PBTST_SDP_QUERYING);
|
||||||
CASESTR(PBTST_SDP_QUERIED);
|
CASESTR(PBTST_SDP_QUERIED);
|
||||||
CASESTR(PBTST_ACL_CONNECTED);
|
CASESTR(PBTST_ACL_CONNECTED);
|
||||||
CASESTR(PBTST_L2C_CONNECTING);
|
CASESTR(PBTST_DATA_CONNECTING);
|
||||||
CASESTR(PBTST_L2C_CONNECTED);
|
CASESTR(PBTST_DATA_CONNECTED);
|
||||||
default:
|
default:
|
||||||
XP_ASSERT(0);
|
XP_ASSERT(0);
|
||||||
return "";
|
return "";
|
||||||
|
@ -1199,7 +1374,7 @@ actToStr(PBT_ACTION act)
|
||||||
CASESTR(PBT_ACT_SETUP_LISTEN);
|
CASESTR(PBT_ACT_SETUP_LISTEN);
|
||||||
CASESTR(PBT_ACT_CONNECT_ACL);
|
CASESTR(PBT_ACT_CONNECT_ACL);
|
||||||
CASESTR(PBT_ACT_GETSDP);
|
CASESTR(PBT_ACT_GETSDP);
|
||||||
CASESTR(PBT_ACT_CONNECT_L2C);
|
CASESTR(PBT_ACT_CONNECT_DATA);
|
||||||
CASESTR(PBT_ACT_GOTDATA);
|
CASESTR(PBT_ACT_GOTDATA);
|
||||||
CASESTR(PBT_ACT_TRYSEND);
|
CASESTR(PBT_ACT_TRYSEND);
|
||||||
CASESTR(PBT_ACT_TELLCONN);
|
CASESTR(PBT_ACT_TELLCONN);
|
||||||
|
@ -1223,8 +1398,6 @@ connEnumToStr( BtLibAccessibleModeEnum mode )
|
||||||
return "undoc_06";
|
return "undoc_06";
|
||||||
case 0x00F8: /* seen on ARM only */
|
case 0x00F8: /* seen on ARM only */
|
||||||
return "undoc_F8";
|
return "undoc_F8";
|
||||||
case 0x00E8: /* seen on ARM */
|
|
||||||
return "undoc_E8";
|
|
||||||
default:
|
default:
|
||||||
XP_ASSERT(0);
|
XP_ASSERT(0);
|
||||||
XP_LOGF( "%s: got 0x%x", __func__, mode );
|
XP_LOGF( "%s: got 0x%x", __func__, mode );
|
||||||
|
|
Loading…
Reference in a new issue