📄 sdpbase.cxx
字号:
if (status != ERROR_SUCCESS) {
pClientBuf = NULL;
ulClientBuf = 0;
}
pOwner->AddRef();
gpSDP->Unlock();
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"About to enter sdp_AttributeSearch_Out, pContext=0x%08x\r\n",pContext));
__try {
pCallback(pContext,status,pClientBuf,ulClientBuf);
}
__except (1) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_Out excepted, exception code = 0x%08x\r\n",GetExceptionCode()));
}
gpSDP->Lock();
pOwner->DelRef();
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Finished with sdp_AttributeSearch_Out\r\n"));
}
void NotifyServiceAttributeSearch(SDP_CONTEXT *pOwner, void *pContext, unsigned long status, unsigned char *pClientBuf, unsigned long ulClientBuf) {
SVSUTIL_ASSERT (VerifyContext(pOwner));
SDP_ServiceAttributeSearch_Out pCallback = pOwner->c.sdp_ServiceAttributeSearch_Out;
if (status != ERROR_SUCCESS) {
pClientBuf = NULL;
ulClientBuf = 0;
}
pOwner->AddRef();
gpSDP->Unlock();
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"About to enter sdp_ServiceAttributeSearch_Out, pContext=0x%08x\r\n",pContext));
__try {
pCallback(pContext,status,pClientBuf,ulClientBuf);
}
__except (1) {
IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceAttributeSearch_Out excepted, exception code = 0x%08x\r\n",GetExceptionCode()));
}
gpSDP->Lock();
pOwner->DelRef();
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Finished with sdp_ServiceAttributeSearch_Out\r\n"));
}
void NotifySdpClientOfCompletion(Call *pCall, unsigned long status) {
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"NotifySdpClientOfCompletion(0x%08x,0x%08x)\r\n",pCall,status));
SVSUTIL_ASSERT(gpSDP->IsLocked());
SVSUTIL_ASSERT(VerifyCall(pCall));
void *pContext = pCall->pCallContext;
SDP_CONTEXT *pOwner = pCall->pOwner;
unsigned char *pClientBuf = (pCall->pSdpConnection && status == ERROR_SUCCESS) ? pCall->pSdpConnection->pClientBuf : NULL;
unsigned long cClientBuf = (pCall->pSdpConnection && status == ERROR_SUCCESS) ? pCall->pSdpConnection->cClientBuf : 0;
unsigned short cReturnedHandles = (pCall->pSdpConnection && status == ERROR_SUCCESS) ? pCall->pSdpConnection->u.Client.ServiceSearch.totalRecordCount : 0;
unsigned short cid = (pCall->pLink && status == ERROR_SUCCESS) ? pCall->pLink->cid : 0;
unsigned int fWhat = pCall->fWhat;
#if defined (DEBUG) || defined (_DEBUG)
if ((status == ERROR_SUCCESS) && (fWhat == CALL_SDP_CONNECT))
SVSUTIL_ASSERT( VerifyLink(pCall->pLink));
SVSUTIL_ASSERT(!pCall->pSdpConnection || (pCall->pSdpConnection != gpSpdConnectionLocal && !pCall->pSdpConnection->fClientNotified));
if (pCall->pSdpConnection)
pCall->pSdpConnection->fClientNotified = TRUE;
#endif
DeleteCall(pCall);
switch (fWhat) {
case CALL_SDP_ACCEPT:
case CALL_SDP_SERVER_WORKER:
break; // no-op, call was generated internally.
case CALL_SDP_CONNECT:
NotifyConnect(pOwner,pContext,status,cid);
break;
case CALL_SDP_DISCONNECT:
NotifyDisconnect(pOwner,pContext,status);
break;
case CALL_SDP_SERVICE_SEARCH:
NotifyServiceSearch(pOwner,pContext,status,cReturnedHandles,pClientBuf);
break;
case CALL_SDP_ATTRIBUTE_SEARCH:
NotifyAttributeSearch(pOwner,pContext,status,pClientBuf,cClientBuf);
break;
case CALL_SDP_SERVICE_ATTRIBUTE_SEARCH:
NotifyServiceAttributeSearch(pOwner,pContext,status,pClientBuf,cClientBuf);
break;
default:
SVSUTIL_ASSERT(0);
}
}
static void ResetSdpConnection(SdpConnection *pSdpConn) {
if (pSdpConn == gpSpdConnectionLocal || pSdpConn->IsClient()) {
pSdpConn->CompleteClientRequest(0,ERROR_SUCCESS);
}
else {
pSdpConn->CleanUpServerSearchResults();
}
pSdpConn->ConnInformation = 0;
pSdpConn->pClientBuf = NULL;
pSdpConn->cClientBuf = 0;
#if defined (DEBUG) || defined (_DEBUG)
// If this ASSERT is hit it means we didn't notify client of completion,
// meaning that there's a hanging call and that we'll end up leaking the memory.
if ((pSdpConn != gpSpdConnectionLocal) && pSdpConn->IsClient() && (!pSdpConn->fClientNotified))
SVSUTIL_ASSERT(0);
pSdpConn->fClientNotified = FALSE;
#endif
}
static void DeleteSdpConnection(SdpConnection *pSdpConn) {
ResetSdpConnection(pSdpConn);
svsutil_FreeFixed(pSdpConn, gpSDP->pfmdSdpConnections);
}
void RemoveAllPendingCallsFromQueue(Link *pLink, unsigned long status);
// This call just frees up link and removes it from list, assumes upper layer has already disconnected.
static void DeleteLink(Link *pLink) {
SVSUTIL_ASSERT(gpSDP->IsLocked());
RemoveAllPendingCallsFromQueue(pLink,ERROR_CONNECTION_UNAVAIL);
// Possible another thread has deleted link in interim.
if (! VerifyLink(pLink))
return;
if (pLink == gpSDP->pLinks)
gpSDP->pLinks = pLink->pNext;
else {
Link *pParent = gpSDP->pLinks;
while (pParent && (pParent->pNext != pLink))
pParent = pParent->pNext;
if (pParent)
pParent->pNext = pLink->pNext;
}
svsutil_FreeFixed(pLink, gpSDP->pfmdLinks);
}
static void DeleteCall (Call *pCall) {
SVSUTIL_ASSERT(gpSDP->IsLocked());
SVSUTIL_ASSERT(VerifyCall(pCall));
IFDBG(DebugOut (DEBUG_SDP_TRACE,L"DeleteCall (0x%08x)\r\n",pCall));
unsigned int fWhat = pCall->fWhat;
Link *pLink = pCall->pLink;
if (pCall->fWhat & CALL_SDP_SEARCH_WORKER && VerifyLink(pCall->pLink))
RemoveCallFromSendQueue(pLink,pCall);
if (pCall == gpSDP->pCalls)
gpSDP->pCalls = pCall->pNext;
else {
Call *pParent = gpSDP->pCalls;
while (pParent && (pParent->pNext != pCall))
pParent = pParent->pNext;
if (pParent)
pParent->pNext = pCall->pNext;
}
if (pCall->pSdpConnection)
DeleteSdpConnection(pCall->pSdpConnection);
svsutil_FreeFixed(pCall, gpSDP->pfmdCalls);
}
void RemoveAllPendingCallsFromQueue(Link *pLink, unsigned long status=0) {
while (VerifyLink(pLink) && pLink->pCallQueue) {
SVSUTIL_ASSERT(pLink->pCallQueue->pCall->fWhat & CALL_SDP_SEARCH_WORKER);
NotifySdpClientOfCompletion(pLink->pCallQueue->pCall,status);
}
}
static Link *FindLink (unsigned short cid) {
Link *p = gpSDP->pLinks;
while (p && (p->cid != cid))
p = p->pNext;
return p;
}
static Link *FindLink(BD_ADDR *pba, BOOL fClient) {
Link *pTrav = gpSDP->pLinks;
while (pTrav) {
if (pTrav->b == *pba) {
if ( (fClient && !pTrav->fIncoming) || (!fClient && pTrav->fIncoming))
return pTrav;
}
pTrav = pTrav->pNext;
}
return pTrav;
}
static Call *FindCall(Link *pLink, unsigned long fWhat=0xFFFFFFFF) {
Call *pTrav;
for (pTrav = gpSDP->pCalls; pTrav; pTrav = pTrav->pNext) {
if ((pTrav->pLink == pLink) && (pTrav->fWhat & fWhat))
return pTrav;
}
return NULL;
}
#if defined (DEBUG) || defined (_DEBUG)
static Call *FindAcceptConnectCall(Link *pLink) {
Call *pTrav;
for (pTrav = gpSDP->pCalls; pTrav; pTrav = pTrav->pNext) {
if ((pTrav->pLink == pLink) && (pTrav->fWhat & CALL_SDP_ACCEPT_CONNECT))
return pTrav;
}
return NULL;
}
#endif // DEBUG
static void CleanupSDPState(void) {
if (gpSDP->pfmdSdpConnections)
svsutil_ReleaseFixedNonEmpty(gpSDP->pfmdSdpConnections);
if (gpSDP->pfmdLinks)
svsutil_ReleaseFixedNonEmpty(gpSDP->pfmdLinks);
if (gpSDP->pfmdCalls)
svsutil_ReleaseFixedNonEmpty(gpSDP->pfmdCalls);
if (gpSDP->pfmdCallQueue)
svsutil_ReleaseFixedNonEmpty(gpSDP->pfmdCallQueue);
if (gpSDP->pfmdBuffers)
svsutil_ReleaseFixedNonEmpty(gpSDP->pfmdBuffers);
gpSDP->ReInit();
}
static void GetConnectionState (void) {
SVSUTIL_ASSERT(gpSDP->eStage == Connected || gpSDP->eStage == Disconnected);
__try {
int fConnected = FALSE;
int dwRet = 0;
gpSDP->l2cap_if.l2ca_ioctl (gpSDP->hL2CAP, BTH_STACK_IOCTL_GET_CONNECTED, 0, NULL, sizeof(fConnected), (char *)&fConnected, &dwRet);
if ((dwRet == sizeof(fConnected)) && fConnected)
gpSDP->eStage = Connected;
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[SDP]: exception in hci_ioctl BTH_STACK_IOCTL_GET_CONNECTED\n"));
}
}
static void DispatchStackEvent (int iEvent) {
SDP_CONTEXT *pContext = gpSDP->pContexts;
while (pContext && gpSDP->IsStackRunning()) {
BT_LAYER_STACK_EVENT_IND pCallback = pContext->ei.sdp_StackEvent;
if (pCallback) {
void *pUserContext = pContext->pUserContext;
IFDBG(DebugOut (DEBUG_SDP_CALLBACK, L"Going into StackEvent notification\n"));
pContext->AddRef ();
gpSDP->Unlock ();
__try {
pCallback (pUserContext, iEvent, NULL);
} __except (1) {
IFDBG(DebugOut (DEBUG_ERROR, L"[SDP] SDP_connect_transport: exception in SDP_StackEvent!\n"));
}
gpSDP->Lock ();
pContext->DelRef ();
IFDBG(DebugOut (DEBUG_SDP_CALLBACK, L"SDP: Came back StackEvent notification\n"));
}
pContext = pContext->pNext;
}
}
static DWORD WINAPI StackDisconnect(LPVOID lpVoid) {
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"SDP: StackDisconnect()\r\n"));
sdp_CloseDriverInstance();
return ERROR_SUCCESS;
}
static DWORD WINAPI StackDown (LPVOID pArg) {
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"SDP: Disconnect stack\n"));
for ( ; ; ) {
if (! gpSDP) {
IFDBG(DebugOut (DEBUG_ERROR, L"SDP: StackDown : ERROR_SERVICE_DOES_NOT_EXIST\n"));
return ERROR_SERVICE_DOES_NOT_EXIST;
}
gpSDP->Lock ();
if (gpSDP->eStage != Connected) {
IFDBG(DebugOut (DEBUG_ERROR, L"SDP: StackDown : ERROR_SERVICE_NOT_ACTIVE\n"));
gpSDP->Unlock ();
return ERROR_SERVICE_NOT_ACTIVE;
}
if (gpSDP->GetRefCount () == 1)
break;
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"SDP: Waiting for ref count in StackDown\n"));
gpSDP->Unlock ();
Sleep (100);
}
SVSUTIL_ASSERT(gpSDP->IsLocked()); // break out of above for loop with lock held.
gpSDP->AddRef ();
gpSDP->eStage = Disconnected;
while (gpSDP->pCalls && gpSDP->IsStackRunning())
NotifySdpClientOfCompletion (gpSDP->pCalls, ERROR_SHUTDOWN_IN_PROGRESS);
while (gpSDP->pLinks && gpSDP->IsStackRunning()) {
SVSUTIL_ASSERT(gpSDP->pLinks->pCallQueue == NULL);
SdpDisconnect(gpSDP->pLinks,NULL);
}
DispatchStackEvent (BTH_STACK_DOWN);
gpSDP->DelRef ();
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"SDP: -StackDown\n"));
gpSDP->Unlock ();
return ERROR_SUCCESS;
}
static DWORD WINAPI StackUp (LPVOID pArg) {
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"Connect stack\n"));
for ( ; ; ) {
if (! gpSDP) {
IFDBG(DebugOut (DEBUG_ERROR, L"StackUp : ERROR_SERVICE_DOES_NOT_EXIST\n"));
return ERROR_SERVICE_DOES_NOT_EXIST;
}
gpSDP->Lock ();
if (gpSDP->eStage != Disconnected) {
IFDBG(DebugOut (DEBUG_ERROR, L"StackUp : ERROR_SERVICE_NOT_ACTIVE\n"));
gpSDP->Unlock ();
return ERROR_SERVICE_NOT_ACTIVE;
}
if (gpSDP->GetRefCount () == 1)
break;
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"Waiting for ref count in StackUp\n"));
gpSDP->Unlock ();
Sleep (100);
}
GetConnectionState ();
if (gpSDP->eStage == Connected) {
gpSDP->AddRef ();
DispatchStackEvent (BTH_STACK_UP);
gpSDP->DelRef ();
}
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"-StackUp\n"));
gpSDP->Unlock ();
return ERROR_SUCCESS;
}
static DWORD WINAPI StackReset (LPVOID pArg) {
IFDBG(DebugOut (DEBUG_SDP_TRACE, L"SDP: Reset stack\n"));
StackDown (NULL);
StackUp (NULL);
return NULL;
}
static int SendData(Call *pCall, unsigned char *pData, int cData) {
SVSUTIL_ASSERT(gpSDP->eStage == Connected);
IFDBG(DebugOut(DEBUG_SDP_TRACE,L"SendData(0x%08x,0x%08x,%d)\r\n",pCall,pData,cData));
IFDBG(DumpBuff(DEBUG_SDP_PACKETS,pData,cData));
int iRet = ERROR_INTERNAL_ERROR;
BD_BUFFER *pBuf;
L2CA_DataDown_In pCallBack = gpSDP->l2cap_if.l2ca_DataDown_In;
HANDLE hL2CAP = gpSDP->hL2CAP;
unsigned short usCID = pCall->pLink->cid;
if (NULL == (pBuf = BufferAlloc(cData + gpSDP->cDataHeaders + gpSDP->cDataTrailers)))
return ERROR_OUTOFMEMORY;
pBuf->cStart = gpSDP->cDataHeaders;
memcpy(pBuf->pBuffer + pBuf->cStart,pData,cData);
pBuf->cEnd = pBuf->cStart + cData;
SVSUTIL_ASSERT(pBuf->cEnd + gpSDP->cDataTrailers == pBuf->cSize);
SVSUTIL_ASSERT(cData == pBuf->cSize - gpSDP->cDataHeaders - gpSDP->cDataTrailers);
SVSUTIL_ASSERT(cData <= pCall->pLink->outMTU);
SVSUTIL_ASSERT(!pCall->pLink->fCallCanceled);
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Going into l2ca_DataDown_In\r\n"));
gpSDP->AddRef();
gpSDP->Unlock();
__try {
iRet = gpSDP->l2cap_if.l2ca_DataDown_In(hL2CAP,(void*)pCall,usCID,pBuf);
} __except(1) {
IFDBG(DebugOut(DEBUG_ERROR,L"Exception in l2cap_DataDown_In\r\n"));
}
gpSDP->Lock();
gpSDP->DelRef();
IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Came from l2ca_DataDown_In\r\n"));
return iRet;
}
static int ProcessNextCall(Link *pLink) {
int iErr = ERROR_SUCCESS;
if (!pLink->pCallQueue) {
IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"ProcessNextCall: No pending calls in wait queue for pLink->cid=0x%04x\r\n",pLink->cid));
return ERROR_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -