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

📄 sdpbase.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:
	while (VerifyLink(pLink) && pLink->pCallQueue)  {
		Call *pCall = pLink->pCallQueue->pCall;

		IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"ProcessNextCall: About to process call 0x%08x\r\n",pLink->pCallQueue->pCall));
		if (ERROR_SUCCESS != (iErr = pCall->pSdpConnection->SendInitialRequestToServer())) {
			if (VerifyCall(pCall))
				NotifySdpClientOfCompletion(pCall,iErr);
			continue;				
		}
		return ERROR_SUCCESS;
	}
	return iErr;
}


void CreateCallForServer(Link *pLink) {
	Call *pNewCall = AllocCall(CALL_SDP_SERVER_WORKER,pLink,NULL,NULL);
	SdpConnection *pSdpConn = pNewCall ? AllocSdpConnection(pNewCall) : NULL;

	if (!pNewCall || !pSdpConn || !AddItemToCallQueue(pLink,pNewCall)) {
		if (pNewCall)
			DeleteCall(pNewCall);

		if (VerifyLink(pLink))
			SdpDisconnect(pLink,NULL);
	}
}


//******************************************************************
// L2Cap Interface Layer.
//******************************************************************

static int sdp_DataUpInd(void *pUserContext, unsigned short cid, BD_BUFFER *pBuffer) {
	int           iSize;
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_DataUpInd(0x%08x,0x%04x,0x%08x)\r\n",pUserContext,cid,pBuffer));

	if (! gpSDP) {
		if (! pBuffer->fMustCopy) 
			pBuffer->pFree(pBuffer);
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpSDP->Lock();
	if (gpSDP->eStage != Connected) {
		if (! pBuffer->fMustCopy) 
			pBuffer->pFree(pBuffer);

		IFDBG(DebugOut(DEBUG_WARN,L"sdp_DataUpInd:: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	iSize = BufferTotal(pBuffer);
	BufferGetChunk(pBuffer,iSize,gpSdpReadBuffer);
	IFDBG(DumpBuff(DEBUG_SDP_PACKETS, gpSdpReadBuffer, iSize));

	if (! pBuffer->fMustCopy)
		pBuffer->pFree(pBuffer);

	Link *pLink = FindLink(cid);
	if (! pLink) {
		IFDBG(DebugOut(DEBUG_WARN,L"sdp_DataUpInd:: cid 0x%04x not found\r\n",cid));
		gpSDP->Unlock();
		return ERROR_NOT_FOUND;
	}

	Call *pCall = NULL;
	if (!pLink->fCallCanceled && pLink->pCallQueue)
		pCall = pLink->pCallQueue->pCall;

	if (! pCall) {
		// This will occur if the call has been canceled by the client.
		SVSUTIL_ASSERT(!pLink->fIncoming);
		IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_DataUpInd:: pCall 0x%08x not found\r\n",pCall));

		// Send off next request in call queue if there is one.
		pLink->fCallCanceled = 0;
		ProcessNextCall(pLink);

		gpSDP->Unlock();
		return ERROR_NOT_FOUND;
	}
	SVSUTIL_ASSERT(pCall->fWhat & CALL_SDP_SEARCH_WORKER);
	
	SdpConnection *pSdpConn = pCall->pSdpConnection;
	unsigned long status    = pSdpConn->ReadWorkItemWorker(gpSdpReadBuffer,iSize);

	if (!pLink->fIncoming && status != STATUS_PENDING) {
		NotifySdpClientOfCompletion(pCall,MapStatusToErrorCode(status));
		if (VerifyLink(pLink))
			ProcessNextCall(pLink);
	}
	else if (pLink->fIncoming && status != ERROR_SUCCESS) {
		ResetSdpConnection(pCall->pSdpConnection);
	}

	gpSDP->Unlock();
	return ERROR_SUCCESS;
}

static int sdp_DisconnectInd(void *pUserContext, unsigned short cid, int iErr) {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_DisconnectInd(0x%08x,0x%04x)\r\n",pUserContext,cid));

	if (! gpSDP)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpSDP->Lock();
	if (gpSDP->eStage != Connected) {
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	Link *pLink = FindLink(cid);
	if (!pLink)  {
		IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_DisconnectInd: cid=0x%04x doesn't have corresponding SDP connection\r\n",cid));
		gpSDP->Unlock();
		return ERROR_NOT_FOUND;
	}

	// The call associated with creating the link should've been deleted already.
	DeleteLink(pLink);

	gpSDP->Unlock();
	return ERROR_SUCCESS;
}

static int sdp_lStackEvent(void *pUserContext, int iEvent, void *pEventContext) {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_lStackEvent(0x%08x,%d,0x%08x)\r\n",pUserContext,iEvent,pEventContext));

	switch (iEvent) {
	case BTH_STACK_NONE:
	case BTH_STACK_HOST_BUFFER:
		IFDBG(DebugOut (DEBUG_ERROR, L"Unexpected event - none or host buffer. Doing nothing\n"));
		break;

	case BTH_STACK_RESET:
		IFDBG(DebugOut (DEBUG_SDP_INIT, L"SDP : Stack reset\n"));
		btutil_ScheduleEvent (StackReset, NULL);
		break;

	case BTH_STACK_DOWN:
		IFDBG(DebugOut (DEBUG_SDP_INIT, L"SDP : Stack down\n"));
		btutil_ScheduleEvent (StackDown, NULL);
		break;

	case BTH_STACK_UP:
		IFDBG(DebugOut (DEBUG_SDP_INIT, L"SDP : Stack up\n"));
		btutil_ScheduleEvent (StackUp, NULL);
		break;

	case BTH_STACK_DISCONNECT:
		IFDBG(DebugOut (DEBUG_SDP_INIT, L"SDP : Stack disconnect\n"));
		btutil_ScheduleEvent (StackDisconnect, NULL);
		break;

	case BTH_STACK_FLOW_ON:
		IFDBG(DebugOut (DEBUG_SDP_INIT, L"SDP: Somebody turned flow on. Not supported. Disconnecting\n"));
		btutil_ScheduleEvent (StackDown, NULL);
		break;

	case BTH_STACK_FLOW_OFF:
		IFDBG(DebugOut (DEBUG_SDP_INIT, L"SDP : HCI Flow back off. Turning stack back on.\n"));
		btutil_ScheduleEvent (StackUp, NULL);
		break;

	default:
		IFDBG(DebugOut (DEBUG_ERROR, L"SDP: unknown stack event. Disconnecting out of paranoia.\n"));
		btutil_ScheduleEvent (StackDown, NULL);
	}

	return ERROR_SUCCESS;
}

static int sdp_lCallAborted(void *pCallContext, int iError) {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_lCallAborted(0x%08x,%d)\r\n",pCallContext,iError));

	if (! gpSDP)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpSDP->Lock();

	if (!gpSDP->IsStackRunning()) {
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	Call *pCall = VerifyCall((Call *)pCallContext);
	if (! pCall) {
		gpSDP->Unlock();
		return ERROR_NOT_FOUND;
	}

	if (pCall->fWhat & CALL_SDP_SEARCH)  {
		SVSUTIL_ASSERT(VerifyLink (pCall->pLink));
		Link *pLink = pCall->pLink;

		// If the call is currently pending then when we get a response it'll be
		// to this call (and item that'll be on head of queue at response time).
		if (pLink->pCallQueue && pLink->pCallQueue->pCall==pCall)  {
			IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"Call (0x%08x) aborted is outstanding on link (0x%08x), further sends will pend it's response\r\n",pCall,pLink));
			pLink->fCallCanceled = 1;
		}
	}

	// During connection it's possible mutliple calls are pointing to same link.  Remove all of them.
	if (pCall->fWhat == CALL_SDP_CONNECT)  {
		Call *pTrav = gpSDP->pCalls;
		Link *pLink = pCall->pLink;  // save in case memory goes away during NotifySdpClientOfCompletion release of CritSec.

		while (pTrav)  {
			if ((pTrav != pCall) && (pTrav->pLink == pLink))  {
				SVSUTIL_ASSERT(pTrav->fWhat == CALL_SDP_CONNECT);
				NotifySdpClientOfCompletion(pTrav,iError);
				// since we gave up CritSec in above call list may have changed, start @ beginning.
				pTrav = gpSDP->pCalls;
				continue;
			}
			pTrav = pTrav->pNext;
		}
	}

	if (VerifyCall(pCall)) {
		if ((pCall->fWhat & CALL_SDP_ACCEPT_CONNECT) && VerifyLink(pCall->pLink))
			SdpDisconnect(pCall->pLink,NULL);

		if (VerifyCall(pCall))
			NotifySdpClientOfCompletion(pCall,iError);
	}
	
	gpSDP->Unlock();
	return ERROR_SUCCESS;
}

static int sdp_ConfigInd(void *pUserContext, unsigned char id, unsigned short cid, unsigned short usOutMTU, unsigned short usInFlushTO, struct btFLOWSPEC *pInFlow, int cOptNum, struct btCONFIGEXTENSION **ppExtendedOptions) {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_ConfigInd(0x%08x,%c,%d,%d,%d)\r\n",pUserContext,id,cid,usOutMTU,usInFlushTO));
	if (! gpSDP)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpSDP->Lock();

	if (gpSDP->eStage != Connected) {
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	Link *pLink = FindLink(cid);
	Call *pCall = pLink ? FindCall(pLink) : NULL;
	if (! pCall)  {
		IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_ConfigInd: can't find link 0x%04x, returns ERROR_NOT_FOUND\r\n",cid));
		gpSDP->Unlock();
		return ERROR_NOT_FOUND;
	}

	SVSUTIL_ASSERT(pLink == pCall->pLink);
	SVSUTIL_ASSERT(pCall->fWhat & CALL_SDP_ACCEPT_CONNECT);

	int fAccept = FALSE;

	if ((usInFlushTO == 0xffff) && (!pInFlow || (pInFlow->service_type == 0x01)) && btutil_VerifyExtendedL2CAPOptions (cOptNum, ppExtendedOptions)) {
		pCall->pLink->fStage |= CONFIG_IND_DONE;
		pCall->pLink->outMTU = usOutMTU ? usOutMTU : L2CAP_MTU;
		fAccept = TRUE;

		if (pLink->fStage == UP) {
			IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_ConfigInd:: connection complete for pCall=0x%08x\r\n",pCall));
		}
	}

	HANDLE hL2CAP = gpSDP->hL2CAP;
	L2CA_ConfigResponse_In pCallback = gpSDP->l2cap_if.l2ca_ConfigResponse_In;

	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Going into l2ca_ConfigResponse_In\r\n"));
	gpSDP->AddRef();
	gpSDP->Unlock();

	__try {
		pCallback(hL2CAP, pCall, id, cid, fAccept ? 0 : 2, 0, 0xffff, NULL, 0, NULL);
	} __except (1) {
		IFDBG(DebugOut(DEBUG_ERROR,L"Exception in l2ca_ConfigResponse_In\r\n"));
	}

	gpSDP->Lock();
	gpSDP->DelRef();

	if (gpSDP->eStage == Connected && VerifyLink (pLink) && (pLink->fStage == UP)) {
		// There maybe multiple calls waiting for connection with this link.  Run through all of them.
		// We delete the call in NotifySdpClientOfCompletion for client case.
		if (NULL != (pCall = FindCall(pLink,CALL_SDP_ACCEPT_CONNECT))) {
			SVSUTIL_ASSERT((pCall->pLink == pLink) && VerifyCall(pCall));
			if (pLink->fIncoming)  {
				CreateCallForServer(pLink);
				DeleteCall(pCall);
			}
			else {
				NotifySdpClientOfCompletion(pCall,ERROR_SUCCESS);
			}
		}
	}
	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Came from l2ca_ConfigResponse_In\r\n"));
	gpSDP->Unlock();
	return ERROR_SUCCESS;
}

static int sdp_ConfigReq_Out(void *pCallContext, unsigned short usResult, unsigned short usInMTU, unsigned short usOutFlushTO, struct btFLOWSPEC *pOutFlow, int cOptNum, struct btCONFIGEXTENSION **ppExtendedOptions) {
	IFDBG(DebugOut (DEBUG_SDP_TRACE,L"sdp_ConfigReq_Out(0x%08x,%d,%d,%d)\r\n",pCallContext,usResult,usInMTU,usOutFlushTO));
	if (! gpSDP)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpSDP->Lock();

	if (gpSDP->eStage != Connected) {
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	Call *pCall = VerifyCall((Call *)pCallContext,CALL_SDP_ACCEPT_CONNECT);
	if (! pCall)  {
		gpSDP->Unlock();
		return ERROR_NOT_FOUND;
	}

	Link *pLink = pCall->pLink;	
	SVSUTIL_ASSERT(VerifyLink(pLink));

	if (usResult == 0) {
		SVSUTIL_ASSERT(! (pLink->fStage & CONFIG_REQ_DONE));
		SVSUTIL_ASSERT(pLink->fStage & CONNECTED);
		SVSUTIL_ASSERT(pLink->cid);
		SVSUTIL_ASSERT(pLink->psm);

		pLink->fStage |= CONFIG_REQ_DONE;

		if (pLink->fStage == UP) {
			IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_ConfigInd:: connection complete for pCall=0x%08x\r\n",pCall));

			// There maybe multiple calls waiting for connection with this link.  Run through all of them.
			while (NULL != (pCall = FindCall(pLink,CALL_SDP_ACCEPT_CONNECT))) {
				SVSUTIL_ASSERT(pCall->pLink == pLink && VerifyCall(pCall));
				if (pLink->fIncoming) {
					CreateCallForServer(pLink);
					DeleteCall(pCall);
				}
				else {
					NotifySdpClientOfCompletion(pCall,ERROR_SUCCESS);
				}
			}
		}
		gpSDP->Unlock();
		return ERROR_SUCCESS;
	}

	gpSDP->Unlock();
	sdp_lCallAborted(pCallContext, ERROR_CONNECTION_ABORTED);

	return ERROR_SUCCESS;
}

static int sdp_ConnectInd(void *pUserContext, BD_ADDR *pba, unsigned short cid, unsigned char id, unsigned short psm) {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_ConnectInd(0x%08x,0x%04x 0x%08x,%d,%c,%d)\r\n",pUserContext,pba->NAP,pba->SAP,cid,id,psm));

	if (! gpSDP)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpSDP->Lock();
	if (gpSDP->eStage != Connected) {
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	unsigned short	result;
	unsigned short	status = 0;
	unsigned short	mtu = 0;

	if (psm != PSM_SDP)  {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ConnectInd received connect for psm = %d (not SDP PSM)\r\n",psm));
		SVSUTIL_ASSERT(0);  // hitting this means that L2CAP has given us a request for a caller on a PSM that SDP did not specify.
		gpSDP->Unlock();
		return ERROR_INVALID_PARAMETER;
	}

	Call *pCall = AllocCall(CALL_SDP_ACCEPT,NULL,NULL,NULL);
	Link *pLink = pCall ? AllocLink() : NULL;

	if (pLink) {
		pCall->pLink = pLink;
		pLink->b = *pba;
		pLink->cid = cid;
		pLink->fStage = CONNECTED;
		pLink->inMTU = DEFAULT_IN_MTU_SIZE;
		pLink->outMTU = 0;
		pLink->psm = psm;
		pLink->fIncoming = TRUE;
		pLink->pNext = gpSDP->pLinks;
		gpSDP->pLinks = pLink;
		
		result = 0;
		mtu = pLink->inMTU;
	} else {
		if (pCall)
			DeleteCall(pCall);
		result = 4;
	}

	HANDLE hL2CAP = gpSDP->hL2CAP;
	L2CA_ConnectResponse_In pCallbackConnect = gpSDP->l2cap_if.l2ca_ConnectResponse_In;
	L2CA_ConfigReq_In pCallbackConfig = gpSDP->l2cap_if.l2ca_ConfigReq_In;

	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Calling into l2ca_ConnectResponse_In\r\n"));
	gpSDP->AddRef();
	gpSDP->Unlock();

	__try {
		pCallbackConnect(hL2CAP, NULL, pba, id, cid, result, status);
	} __except (1) {
		IFDBG(DebugOut(DEBUG_ERROR,L"Exception in l2ca_ConfigReq_In\r\n"));
	}

	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Came from l2ca_ConnectResponse_In\r\n"));

	if (result == 0) {
		int iRes = ERROR_INTERNAL_ERROR;
		IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Calling into l2ca_ConfigReq_In\r\n"));
		
		__try {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -