⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdpbase.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:

	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 + -