📄 tdi.cxx
字号:
void reset (void) {
paolist = NULL;
pcolist = NULL;
psolist = NULL;
pnlist = NULL;
hRFCOMM = NULL;
memset (&rfcomm_if, 0, sizeof(rfcomm_if));
hSDP = NULL;
memset (&sdp_if, 0, sizeof(sdp_if));
hHCI = NULL;
memset(&hci_if, 0, sizeof(hci_if));
fIsConnected = fIsInitialized = FALSE;
cDeviceHeader = cDeviceTrailer = 0;
memset (&btAddr, 0, sizeof(btAddr));
}
RFCOMM_TDI (void) {
pfmdAO = NULL;
pfmdCO = NULL;
pfmdSO = NULL;
pfmdSEND = NULL;
pfmdRECV = NULL;
pfmdPL = NULL;
pfmdPN = NULL;
reset ();
}
~RFCOMM_TDI(void) {
if (pfmdAO)
svsutil_ReleaseFixedEmpty (pfmdAO);
if (pfmdCO)
svsutil_ReleaseFixedEmpty (pfmdCO);
if (pfmdSO)
svsutil_ReleaseFixedEmpty (pfmdSO);
if (pfmdSEND)
svsutil_ReleaseFixedEmpty (pfmdSEND);
if (pfmdRECV)
svsutil_ReleaseFixedEmpty (pfmdRECV);
if (pfmdPL)
svsutil_ReleaseFixedEmpty (pfmdPL);
if (pfmdPN)
svsutil_ReleaseFixedEmpty (pfmdPN);
}
int Init (void);
};
void sdp_UnLoadWSANameSpaceProvider(void);
void sdp_LoadWSANameSpaceProvider(void);
//
// Globals
//
static RFCOMM_TDI *gpTDIR = NULL;
//
// Utility functions
//
static int ExtractPN (HANDLE hConnection, int *pmtu, int *pfcreditflow, int *picreditsgranted) {
RFCOMM_PN_OBJECT *pPNO = gpTDIR->pnlist;
RFCOMM_PN_OBJECT *pParent = NULL;
while (pPNO && (pPNO->hConnection != hConnection)) {
pParent = pPNO;
pPNO = pPNO->pNext;
}
if (! pPNO)
return FALSE;
if (pmtu)
*pmtu = pPNO->imtu;
if (pfcreditflow)
*pfcreditflow = pPNO->fCreditFlow;
if (picreditsgranted)
*picreditsgranted = pPNO->iCredits;
if (pParent)
pParent->pNext = pPNO->pNext;
else
gpTDIR->pnlist = pPNO->pNext;
delete pPNO;
return TRUE;
}
static RFCOMM_SOCKET_OBJECT *GetSocketObject (HANDLE h) {
RFCOMM_SOCKET_OBJECT *pSock = gpTDIR->psolist;
while (pSock && (pSock != h))
pSock = pSock->pNext;
return pSock;
}
static RFCOMM_SOCKET_OBJECT *GetSocketByHandle (HANDLE h) {
RFCOMM_SOCKET_OBJECT *pSock = gpTDIR->psolist;
while (pSock && (pSock->hSocketHandle != h))
pSock = pSock->pNext;
return pSock;
}
static RFCOMM_ADDRESS_OBJECT *GetAddressObject (HANDLE h) {
RFCOMM_ADDRESS_OBJECT *pA = gpTDIR->paolist;
while (pA && (pA != h))
pA = pA->pNext;
return pA;
}
static RFCOMM_CONNECTION_OBJECT *GetConnectionObject (HANDLE h) {
RFCOMM_CONNECTION_OBJECT *pC = gpTDIR->pcolist;
while (pC && (pC != h))
pC = pC->pNext;
return pC;
}
static RFCOMM_SEND_OBJECT *GetSendObject (HANDLE h) {
HANDLE hConnectObj = NULL;
__try {
hConnectObj = (HANDLE)((RFCOMM_SEND_OBJECT *)h)->pConnect;
} __except (1) {
IFDBG(DebugOut (DEBUG_WARN, L"RFCOMM_SEND_OBJECT faulted: returning FALSE\n"));
return NULL;
}
RFCOMM_CONNECTION_OBJECT *pC = GetConnectionObject (hConnectObj);
if (! pC)
return NULL;
RFCOMM_SEND_OBJECT *pSendO = pC->pSendList;
while (pSendO && (pSendO != h))
pSendO = pSendO->pNext;
return pSendO;
}
static RFCOMM_PACKET_OBJECT *GetPacketObject (HANDLE h) {
if (! h) {
IFDBG(DebugOut (DEBUG_WARN, L"GetPacketObject failed: NULL context\n"));
return NULL;
}
HANDLE hConnectObj = NULL;
__try {
hConnectObj = (HANDLE)((RFCOMM_PACKET_OBJECT *)h)->pConn;
} __except (1) {
IFDBG(DebugOut (DEBUG_WARN, L"GetPacketObject faulted: returning FALSE\n"));
return NULL;
}
RFCOMM_CONNECTION_OBJECT *pC = GetConnectionObject (hConnectObj);
if (! pC)
return NULL;
RFCOMM_PACKET_OBJECT *pP = pC->pPacketList;
while (pP && (pP != h))
pP = pP->pNext;
return pP;
}
static RFCOMM_CONNECTION_OBJECT *GetConnectionByHandle (HANDLE h) {
RFCOMM_CONNECTION_OBJECT *pC = gpTDIR->pcolist;
while (pC && (pC->hConnect != h))
pC = pC->pNext;
return pC;
}
static RFCOMM_CONNECTION_OBJECT *GetConnectionByContext (void *pCtx) {
RFCOMM_CONNECTION_OBJECT *pC = gpTDIR->pcolist;
while (pC && (pC->pConnectionContext != pCtx))
pC = pC->pNext;
return pC;
}
static void GetConnectionState (void) {
gpTDIR->fIsConnected = FALSE;
__try {
int fConnected = FALSE;
int dwRet = 0;
gpTDIR->hci_if.hci_ioctl (gpTDIR->hHCI, BTH_STACK_IOCTL_GET_CONNECTED, 0, NULL, sizeof(fConnected), (char *)&fConnected, &dwRet);
if ((dwRet == sizeof(fConnected)) && fConnected)
gpTDIR->fIsConnected = TRUE;
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] GetConnectionState : exception in hci_ioctl BTH_STACK_IOCTL_GET_CONNECTED\n"));
}
}
static int CloseAddressObject (RFCOMM_ADDRESS_OBJECT *pao) {
IFDBG(DebugOut (DEBUG_TDI_TRACE, L"CloseAddressObject 0x%08x\n", pao));
RFCOMM_ADDRESS_OBJECT *pA = gpTDIR->paolist;
RFCOMM_ADDRESS_OBJECT *pP = NULL;
while (pA && (pA != pao)) {
pP = pA;
pA = pA->pNext;
}
if (! pA)
return ERROR_NOT_FOUND;
if (pP)
pP->pNext = pA->pNext;
else
gpTDIR->paolist = pA->pNext;
unsigned char cPort = pA->ch;
int fAssigned = pA->fAssigned;
delete pA;
// unbind the socket...
RFCOMM_SOCKET_OBJECT *pso = gpTDIR->psolist;
while (pso) {
if (pso->pao == pao)
pso->pao = NULL;
pso = pso->pNext;
}
// disassociate connections
RFCOMM_CONNECTION_OBJECT *pco = gpTDIR->pcolist;
while (pco) {
if (pco->pAddr == pA) {
SVSUTIL_ASSERT (0);
pco->pAddr = NULL;
}
pco = pco->pNext;
}
if (gpTDIR->fIsInitialized && fAssigned) {
HANDLE h = gpTDIR->hRFCOMM;
BT_LAYER_IO_CONTROL pCallback = gpTDIR->rfcomm_if.rfcomm_ioctl;
gpTDIR->AddRef ();
gpTDIR->Unlock ();
__try {
pCallback (h, BTH_STACK_IOCTL_FREE_PORT, sizeof(cPort), (char *)&cPort, 0, NULL, NULL);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[TDIR] CloseAddressObject Exception in BTH_STACK_IOCTL_FREE_PORT\n"));
}
gpTDIR->Lock ();
gpTDIR->DelRef ();
}
return ERROR_SUCCESS;
}
static int DisassociateConnection (RFCOMM_CONNECTION_OBJECT *pC) {
if (pC->pAddr) {
pC->pAddr->DelRef ();
RFCOMM_ADDRESS_OBJECT *pAddr = pC->pAddr;
pC->pAddr = NULL;
if (pAddr->GetRefCount () == 1)
CloseAddressObject (pAddr);
}
return ERROR_SUCCESS;
}
static void TransferOptions (RFCOMM_CONNECTION_OBJECT *pConn, OPT *pOpts) {
if (pOpts->uiConfigMask & OPT_CONFIG_MTU)
pConn->imax_mtu = pOpts->imax_mtu;
if (pOpts->uiConfigMask & OPT_CONFIG_MTU_MIN)
pConn->imin_mtu = pOpts->imin_mtu;
if (pOpts->uiConfigMask & OPT_CONFIG_MAX_SEND)
pConn->imax_send = pOpts->imax_send;
if (pOpts->uiConfigMask & OPT_CONFIG_MAX_RECV)
pConn->imax_recv = pOpts->imax_recv;
if (pOpts->uiConfigMask & OPT_CONFIG_XOFF)
pConn->xoff_lim = pOpts->xoff_lim;
if (pOpts->uiConfigMask & OPT_CONFIG_XON)
pConn->xon_lim = pOpts->xon_lim;
if (pOpts->uiConfigMask & OPT_CONFIG_AUTH)
pConn->fAuthenticate = pOpts->fAuthenticate;
if (pOpts->uiConfigMask & OPT_CONFIG_CRYPT)
pConn->fEncrypt = pOpts->fEncrypt;
if (pOpts->uiConfigMask & OPT_CONFIG_MTU)
pConn->mtu = pOpts->mtu;
if (pOpts->uiConfigMask & OPT_CONFIG_PIN) {
pConn->cPinLength = pOpts->cPinLength;
memcpy (pConn->caPinData, pOpts->caPinData, sizeof(pConn->caPinData));
}
SVSUTIL_ASSERT ((pConn->cPinLength >= 0) && (pConn->cPinLength <= PIN_SIZE));
}
static void ResetConnection (RFCOMM_CONNECTION_OBJECT *pConn, int fClearCredits) {
pConn->fc_local = pConn->fc_remote = pConn->fc_aggregate = FALSE;
pConn->brin = pConn->v24in = pConn->rlsin = 0;
pConn->irecvd = pConn->isent = 0;
pConn->fCloseHaveRecv = FALSE;
pConn->fCloseHaveSend = FALSE;
pConn->cbDataIndicated = FALSE;
pConn->fSending = FALSE;
pConn->fNoDisconnect = FALSE;
if (fClearCredits) {
pConn->fc_credit = FALSE;
pConn->iHaveCredits = 0;
pConn->iGaveCredits = 0;
#if defined (DEBUG_CREDIT_FLOW)
pConn->iPacketsSent = 0;
pConn->iPacketsRecv = 0;
pConn->iCreditsSent = 0;
pConn->iCreditsRecv = 0;
#endif
}
}
static int DisconnectConnection (RFCOMM_CONNECTION_OBJECT *pConn, HANDLE hConn, void *pCtx) {
IFDBG(DebugOut (DEBUG_TDI_PACKETS, L"DisconnectConnection (0x%08x, 0x%08x, 0x%08x)\n", pConn, hConn, pCtx));
if (pConn) {
hConn = pConn->hConnect;
pConn->hConnect = NULL;
}
int iRes = ERROR_SUCCESS;
if (gpTDIR->fIsConnected && hConn) {
IFDBG(DebugOut (DEBUG_TDI_TRACE, L"DisconnectConnection : physically closing 0x%08x\n", hConn));
HANDLE h = gpTDIR->hRFCOMM;
RFCOMM_Disconnect_In pCallback = gpTDIR->rfcomm_if.rfcomm_Disconnect_In;
gpTDIR->AddRef ();
gpTDIR->Unlock ();
__try {
iRes = pCallback (h, pCtx, hConn);
} __except (1) {
iRes = ERROR_INTERNAL_ERROR;
IFDBG(DebugOut (DEBUG_ERROR, L"[TDI] DisconnectConnection : exception in rfcomm_Disconnect_In\n"));
}
gpTDIR->Lock ();
gpTDIR->DelRef ();
}
return iRes;
}
static int CloseConnectionObject (RFCOMM_CONNECTION_OBJECT *pco) {
IFDBG(DebugOut (DEBUG_TDI_PACKETS, L"CloseConnectionObject 0x%08x\n", pco));
RFCOMM_CONNECTION_OBJECT *pC = gpTDIR->pcolist;
RFCOMM_CONNECTION_OBJECT *pP = NULL;
while (pC && (pC != pco)) {
pP = pC;
pC = pC->pNext;
}
if (! pC)
return ERROR_NOT_FOUND;
if (pP)
pP->pNext = pC->pNext;
else
gpTDIR->pcolist = pC->pNext;
HANDLE hConn = pC->hConnect;
SVSUTIL_ASSERT (pC->pPacketList == NULL);
SVSUTIL_ASSERT (pC->pSendList == NULL);
SVSUTIL_ASSERT (pC->pRecvList == NULL);
SVSUTIL_ASSERT (pC->pAddr == NULL);
bt_addr bt = pC->BTAddr.btAddr;
int cPinLength = pC->cPinLength;
DisassociateConnection (pC);
delete pC;
DisconnectConnection (NULL, hConn, NULL);
if (cPinLength != 0) {
gpTDIR->AddRef ();
gpTDIR->Unlock ();
__try {
BthRevokePIN (&bt);
} __except (1) {
}
gpTDIR->Lock ();
gpTDIR->DelRef ();
}
return ERROR_SUCCESS;
}
static int CloseSocketObject (RFCOMM_SOCKET_OBJECT *pso) {
IFDBG(DebugOut (DEBUG_TDI_TRACE, L"CloseSocketObject 0x%08x\n", pso));
RFCOMM_SOCKET_OBJECT *pS = gpTDIR->psolist;
RFCOMM_SOCKET_OBJECT *pP = NULL;
while (pS && (pS != pso)) {
pP = pS;
pS = pS->pNext;
}
if (! pS)
return ERROR_NOT_FOUND;
if (pP)
pP->pNext = pS->pNext;
else
gpTDIR->psolist = pS->pNext;
delete pS;
return ERROR_SUCCESS;
}
static void SignalConnectionCompleteUp (RFCOMM_CONNECTION_OBJECT *pC, int iError) {
IFDBG(DebugOut (DEBUG_TDI_TRACE, L"SignalConnectionCompleteUp 0x%08x : %d\n", pC, iError));
if (iError != TDI_SUCCESS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -