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

📄 sdpbase.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:
unsigned long SdpConnection::SendOrQueueRequest()  {
	Call      *pCall   = (Call *) pCallContext;
	Link      *pLink   = pCall->pLink;
	int       iErr     = STATUS_PENDING;
	CallQueue *pCallQueue;

	SVSUTIL_ASSERT(gpSDP->IsLocked());
	SVSUTIL_ASSERT(VerifyCall(pCall,CALL_SDP_SEARCH));
	SVSUTIL_ASSERT(VerifyLink(pLink));	

	if (! (pCallQueue = AddItemToCallQueue(pLink,pCall)))  {
		return ERROR_OUTOFMEMORY;
	}

	if (pCallQueue == pLink->pCallQueue && !pLink->fCallCanceled)
		iErr = SendInitialRequestToServer();

	return iErr;
}


NTSTATUS 
SdpConnection::Write(
    void *pBuffer,
    unsigned long length
    )
{
	SVSUTIL_ASSERT(gpSDP->IsLocked());
	
	Call *pCall = (Call *) pCallContext;
	SVSUTIL_ASSERT(VerifyCall(pCall,CALL_SDP_SEARCH_WORKER));
	SVSUTIL_ASSERT(VerifyLink(pCall->pLink));

#if defined (DEBUG) || defined (_DEBUG)
	// call we're about to service better be first on send queue.
	if (pCall->fWhat & CALL_SDP_SEARCH)
		SVSUTIL_ASSERT(pCall->pLink->pCallQueue->pCall == pCall);
#endif

	return SendData(pCall,(unsigned char*)pBuffer,length);
}

BOOL SdpConnection::IsClient() {
	return ! ((Call*) pCallContext)->pLink->fIncoming;
}

BOOL SdpConnection::IsServer() {
	return ((Call*) pCallContext)->pLink->fIncoming;
}

// Code that relies on CSemaphore locking mechanism is from NT port, and is always wrapped
// in the SDP CritSec.  Put ASSERTS in to be sure
BOOLEAN CSemaphore::ReleaseSem(KPRIORITY Increment,LONG Adjustment, BOOLEAN bWait)  { 
	SVSUTIL_ASSERT(gpSDP && gpSDP->IsLocked());
	return TRUE; 
}

void CSemaphore::AcquireSem()  { 
	SVSUTIL_ASSERT(gpSDP && gpSDP->IsLocked());
}

// Required to map status codes returned by NT SDP layer
static int MapStatusToErrorCode(int status)  {
	switch (status) {
		case ERROR_SUCCESS:
			return ERROR_SUCCESS;

		case ERROR_INVALID_PARAMETER:
		case STATUS_UNSUCCESSFUL:
		case STATUS_INVALID_PARAMETER:
		case STATUS_DEVICE_PROTOCOL_ERROR:
		case STATUS_INVALID_NETWORK_RESPONSE:
			return ERROR_INVALID_PARAMETER;

		case ERROR_NOT_FOUND:
		case STATUS_NOT_FOUND:
			return ERROR_NOT_FOUND;

		case ERROR_OUTOFMEMORY:
		case STATUS_INSUFFICIENT_RESOURCES:
			return ERROR_OUTOFMEMORY;

		default:
			SVSUTIL_ASSERT(0);
	}
	return status;
}


//******************************************************************
// SDP Interface
//******************************************************************

// AddRecord and RemoveRecord run totally locally, no need
// to have them be Asyncronous.  Since they run locally we only need to make
// sure SDP stack is running since we don't use lower L2CAP layers in these calls.
static int sdp_AddRecord(HANDLE hDeviceContext, UCHAR *pStream, unsigned long streamSize, HANDLE *pRecordHandle) {
	int iRet;
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_AddRecord(0x%08x,0x%08x,%d)\r\n",hDeviceContext,pStream,streamSize));
	                         
	if (! gpSDP) {
		IFDBG(DebugOut(DEBUG_WARN,L"sdp_AddRecord returns ERROR_SERVICE_NOT_ACTIVE\r\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpSDP->Lock();
	if (!gpSDP->IsStackRunning()) {
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
	if (!VerifyContext((SDP_CONTEXT*) hDeviceContext) || !pStream || streamSize == 0 || !pRecordHandle)
		iRet = ERROR_INVALID_PARAMETER;
	else {
#if defined (UNDER_CE)
        // if *pRecordHandle is non NULL, then treat it as an update and not add record.
		iRet = *pRecordHandle ? pSdpDB->UpdateRecord(pStream,streamSize,*pRecordHandle) : pSdpDB->AddRecord(pStream,streamSize,pRecordHandle);
		if (iRet != ERROR_SUCCESS)
   			*pRecordHandle = 0;
#else  // WINCE_EMULATION
        iRet = pSdpDB->AddRecord(pStream,streamSize,pRecordHandle);
#endif // UNDER_CE

	}
	gpSDP->Unlock();

#if defined (UNDER_CE)
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdpAddRecord returns 0x%08x, *pRecordHandle=0x%08x\r\n",iRet,*pRecordHandle));
#endif
	return MapStatusToErrorCode(iRet);
}

static int sdp_RemoveRecord(HANDLE hDeviceContext, HANDLE hRecordHandle)  {
	int iRet;
	unsigned long iRemovedRecord;
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_RemoveRecord(0x%08x,0x%08x)\r\n",hDeviceContext,hRecordHandle));

	if (! gpSDP) {
		IFDBG(DebugOut(DEBUG_WARN,L"sdp_RemoveRecord ERROR_SERVICE_NOT_ACTIVE\r\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	
	gpSDP->Lock();
	if (!gpSDP->IsStackRunning()) {
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	if (!VerifyContext((SDP_CONTEXT*) hDeviceContext))
		iRet = ERROR_INVALID_PARAMETER;
	else
		iRet = pSdpDB->RemoveRecord(hRecordHandle,&iRemovedRecord);
	gpSDP->Unlock();

	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdpRemoveRecord returns 0x%08x\r\n",iRet));
	return MapStatusToErrorCode(iRet);
}

static int SdpDisconnect(Link *pLink, Call *pCall)  {
	SVSUTIL_ASSERT( VerifyLink(pLink));

	HANDLE hL2CAP = gpSDP->hL2CAP;
	L2CA_Disconnect_In pCallback = gpSDP->l2cap_if.l2ca_Disconnect_In;
	unsigned short cid = pLink->cid;
	int iRes = ERROR_INTERNAL_ERROR;

	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Entering l2ca_Disconnect_In, cid = 0x%04x\r\n",pLink->cid));
	gpSDP->AddRef();
	gpSDP->Unlock();
	__try {
		iRes = pCallback (hL2CAP, pCall, cid);
	} __except (1) {
		IFDBG(DebugOut(DEBUG_ERROR,L"Exception in l2ca_Disconnect_In\r\n"));
	}
	gpSDP->Lock();
	gpSDP->DelRef();
	IFDBG(DebugOut(DEBUG_SDP_CALLBACK,L"Finished with l2ca_Disconnect_In\r\n");)	

	DeleteLink(pLink);
	return iRes;
}

static int sdp_Connect_In(HANDLE hDeviceContext, void *pCallContext, BD_ADDR *pba)  {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Connect_In(0x%08x,0x%08x,0x%08x 0x%04)\r\n",
	                          hDeviceContext,pCallContext,pba->NAP,pba->SAP));

	if (! gpSDP) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpSDP->Lock();
	if (gpSDP->eStage != Connected) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	SDP_CONTEXT *pContext = VerifyContext((SDP_CONTEXT*) hDeviceContext);
	if (!pContext || !pba)  {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_In: ERROR_INVALID_PARAMETER\r\n"));
		gpSDP->Unlock();
		return ERROR_INVALID_PARAMETER;
	}

	Link *pLink = FindLink(pba,TRUE);
	if (pLink)  {
		IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_Connect_In: already connected\r\n"));
		pLink->AddRef();

		if (pLink->fStage == UP)  {
			NotifyConnect(pContext,pCallContext,ERROR_SUCCESS,pLink->cid);
			gpSDP->Unlock();
			return ERROR_SUCCESS;
		}
		// if link hasn't been established we alloc the call but don't try to fire up connection.
	}

	Call *pCall = AllocCall(CALL_SDP_CONNECT,pLink,pContext,pCallContext);
	if (!pCall)  {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Connect_In:  ERROR_OUTOFMEMORY\r\n"));
		if (pLink)
			pLink->DelRef();
		gpSDP->Unlock();
		return ERROR_OUTOFMEMORY;
	}
	int iRes = ERROR_SUCCESS;

	if (!pLink)  {
		iRes = SdpCreateConnection(pCall,pba);
		if (iRes != ERROR_SUCCESS)  {
			// Since we gave up CritSec in SdpCreateConnection need to make sure call is still around.
			if (VerifyCall(pCall))
				DeleteCall(pCall);
		}
	}

	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Connect_In: iRes = 0x%08x\r\n",iRes));
	gpSDP->Unlock();
	return iRes;
}


static int sdp_Disconnect_In(HANDLE hDeviceContext, void *pCallContext, unsigned short cid)  {
	int iRes = ERROR_SUCCESS;
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Disconnect_In(0x%08x,0x%08x,0x%04x)\r\n",
	                          hDeviceContext,pCallContext,cid));

	if (! gpSDP) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Disconnect_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpSDP->Lock();
	if (gpSDP->eStage != Connected) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Disconnect_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	SDP_CONTEXT *pOwner = VerifyContext((SDP_CONTEXT*) hDeviceContext);
	Link *pLink = pOwner ? FindLink(cid) : NULL;

	if (!pOwner || !pLink) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_Disconnect_In: ERROR_INVALID_PARAMETER\r\n"));
		gpSDP->Unlock();
		return ERROR_INVALID_PARAMETER;
	}
	SVSUTIL_ASSERT(!pLink->fIncoming);

	pLink->DelRef();
	if (pLink->GetRefCount() > 0)  {
		IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_Disconnect_In: cid 0x%04x has extra references\r\n",cid));
		NotifyDisconnect(pOwner,pCallContext,ERROR_SUCCESS);
	}
	else {
		IFDBG(DebugOut(DEBUG_SDP_PACKETS,L"sdp_Disconnect_In: cid 0x%04x has last ref removed, deleting\r\n",cid));
		Call *pCall = AllocCall(CALL_SDP_DISCONNECT,NULL, pOwner, pCallContext);

		// If are OOM we still do disconnect, but won't be able to call sdp_Disconnect_Out.
		iRes = SdpDisconnect(pLink,pCall);
		if (iRes != ERROR_SUCCESS && pCall && VerifyCall(pCall))
			DeleteCall(pCall);

		if (!pCall)
			iRes = ERROR_OUTOFMEMORY;
	}

	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_Disconnect_In: 0x%08x\r\n",iRes));
	gpSDP->Unlock();
	return iRes;
}

static int sdp_ServiceSearch_In(HANDLE hDeviceContext, void *pCallContext, unsigned short cid,
                                SdpQueryUuid* pUUIDs, unsigned short cMaxHandles)  {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_ServiceSearch_In(0x%08x,0x%08x,0x%08x,%d)\r\n",
	                         hDeviceContext,pCallContext,pUUIDs,cMaxHandles));

	if (! gpSDP) { 
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}	

	gpSDP->Lock();
	if (gpSDP->eStage != Connected) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	SDP_CONTEXT *pContext = VerifyContext((SDP_CONTEXT*) hDeviceContext);
	Link        *pLink    = (pContext && cid) ? FindLink(cid) : NULL;

	// for VerifyCall to be legit, as soon as we take down link we must invalidate the call (or use a flag to do this,
	// let mem be freed by caller function).  Also currently this allows calls to be queued even if not connected,
	// need to make sure this case is handled both on connection and if connection fails.
	if (!pContext || (cid && (!pLink || pLink->fStage != UP))) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_INVALID_PARAMETER\r\n"));
		gpSDP->Unlock();
		return ERROR_INVALID_PARAMETER;
	}

	Call             *pCall    = NULL;
	SdpConnection    *pSdpConn = NULL;
	SdpServiceSearch searchInfo;
	
	if (cid)  {
		pCall = AllocCall(CALL_SDP_SERVICE_SEARCH, pLink, pContext,pCallContext);
		if (!pCall)  {
			IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_OUTOFMEMORY\r\n"));
			gpSDP->Unlock();
			return ERROR_OUTOFMEMORY;
		}
		pSdpConn = AllocSdpConnection(pCall);
	}
	else {
		pSdpConn = GetLocalSDPConn();
		if (!pSdpConn) {
			IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: ERROR_OUTOFMEMORY\r\n"));
			gpSDP->Unlock();
			return ERROR_OUTOFMEMORY;
		}
	}

	searchInfo.uuids       = pUUIDs;
	searchInfo.cMaxHandles = cMaxHandles;

	int iRes = SdpInterface::ServiceSearch(pSdpConn,&searchInfo,(cid == 0));
	if (iRes == STATUS_PENDING) {
		SVSUTIL_ASSERT(cid);
		iRes = ERROR_SUCCESS;
	}

	if (!cid)  {
		unsigned short cReturnedHandles;
		if (iRes == ERROR_SUCCESS)
			cReturnedHandles = pSdpConn->u.Client.ServiceSearch.totalRecordCount;
		else
			cReturnedHandles = 0;

		NotifyServiceSearch(pContext,pCallContext,iRes,cReturnedHandles,pSdpConn->pClientBuf);
		ResetSdpConnection(pSdpConn);
	}
	else if (iRes != ERROR_SUCCESS) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_ServiceSearch_In: SdpInterface::ServiceSearch fails, 0x%08x\r\n",iRes));
#if defined (DEBUG) || defined (_DEBUG)
		pCall->pSdpConnection->fClientNotified = TRUE;
#endif
		DeleteCall(pCall);
	}

	gpSDP->Unlock();
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_ServiceSearch_In: 0x%08x\r\n",iRes));
	return MapStatusToErrorCode(iRes);
}

static int sdp_AttributeSearch_In(HANDLE hDeviceContext, void *pCallContext, unsigned short cid, unsigned long recordHandle, SdpAttributeRange *pAttribRange, int numAttributes)  {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"sdp_AttributeSearch_In(0x%08x,0x%08x,0x%08x,0x%08x,0x%04x,0x%08x,%d )\r\n",
	                                                hDeviceContext,pCallContext,recordHandle,cid,pAttribRange,numAttributes));

	if (! gpSDP) { 
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		return ERROR_SERVICE_NOT_ACTIVE;
	}	

	gpSDP->Lock();
	if (gpSDP->eStage != Connected) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_SERVICE_NOT_ACTIVE\r\n"));
		gpSDP->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}

	SDP_CONTEXT *pContext = VerifyContext((SDP_CONTEXT*) hDeviceContext);
	Link        *pLink = (pContext && cid) ? FindLink(cid) : NULL;	

	if (!pContext || (cid && (!pLink || pLink->fStage != UP))) {
		IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_INVALID_PARAMETER\r\n"));
		gpSDP->Unlock();
		return ERROR_INVALID_PARAMETER;
	}

	Call          *pCall    = NULL;
	SdpConnection *pSdpConn = NULL;
	SdpAttributeSearch searchInfo;
	
	if (cid)  {
		pCall = AllocCall(CALL_SDP_ATTRIBUTE_SEARCH, pLink, pContext,pCallContext);
		if (!pCall)  {
			IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_OUTOFMEMORY\r\n"));
			gpSDP->Unlock();
			return ERROR_OUTOFMEMORY;
		}
		pSdpConn = AllocSdpConnection(pCall);
	}
	else {
		pSdpConn = GetLocalSDPConn();
		if (!pSdpConn) {
			IFDBG(DebugOut(DEBUG_ERROR,L"sdp_AttributeSearch_In: ERROR_OUTOFMEMORY\r\n"));
			gpSDP->Unlock();
			return ERROR_OUTOFMEMORY;
		}
	}

	searchInfo.range         = pAttribRange;
	searchInfo.numAttrib

⌨️ 快捷键说明

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