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

📄 sdpns.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 4 页
字号:
	c.sdp_Disconnect_Out             = bthns_Disconnect_Out;
   
	ei.sdp_StackEvent                = bthns_StackEvent;

	int iErr = SDP_EstablishDeviceContext(NULL,&ei,&c,&gpBthNS->sdp_if,&gpBthNS->hSDP);
	if (iErr != ERROR_SUCCESS) {
		IFDBG(DebugOut(DEBUG_ERROR, L"bthns_CreateDriverInstance couldn't plug into SDP, err=0x%08x\n",iErr));
		gpBthNS->Unlock();
		return iErr;
	}

	SVSUTIL_ASSERT(gpBthNS->hSDP);

    // SDP lower layer determines whether or not the lower stack is running or not.
	gpBthNS->eStage = Running;
	gpBthNS->Unlock();
	
	return ERROR_SUCCESS;
}

int bthns_CloseDriverInstance(void)  {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"BTHNS_CloseDriverInstance entered\r\n"));
	SDP_CloseDeviceContext(gpBthNS->hSDP);

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

	gpBthNS->Lock();
	if ((gpBthNS->eStage != Running) && (gpBthNS->eStage != Initializing)) {
		IFDBG(DebugOut(DEBUG_ERROR, L"SDP Close Driver Instance:: ERROR_SERVICE_NOT_ACTIVE\n"));
		gpBthNS->Unlock();
		return ERROR_SERVICE_NOT_ACTIVE;
	}
	gpBthNS->eStage   = ShuttingDown;

	while (gpBthNS->pCalls) {
		SetEvent(gpBthNS->pCalls->hEvent);
		gpBthNS->pCalls->iResult = ERROR_CANCELLED;
		gpBthNS->pCalls = gpBthNS->pCalls->pNext;
	}

	while (gpBthNS->pBthNsHandles) {
		DeleteBthNsHandle(gpBthNS->pBthNsHandles);
	}

	while (gpBthNS->GetRefCount() > 1) {
		IFDBG(DebugOut (DEBUG_SDP_TRACE, L"Waiting for ref count in bthns_CloseDriverInstance\n"));
		gpBthNS->Unlock ();
		Sleep (200);
		gpBthNS->Lock ();
	}

	if (gpBthNS->hSDP)
		SDP_CloseDeviceContext(gpBthNS->hSDP);

	if (gpBthNS->pfmdBthNsHandles)
		svsutil_ReleaseFixedNonEmpty(gpBthNS->pfmdBthNsHandles);
		
	if (gpBthNS->pfmdNSCAlls)
		svsutil_ReleaseFixedNonEmpty(gpBthNS->pfmdNSCAlls);

	gpBthNS->ReInit();
	gpBthNS->Unlock();
	return ERROR_SUCCESS;
}

int bthns_UninitializeOnce(void) {
	IFDBG(DebugOut(DEBUG_SDP_INIT | DEBUG_SDP_TRACE,L"bthns_UninitializeOnce()\r\n"));
	SVSUTIL_ASSERT(gpBthNS);

	if (! gpBthNS) {
		IFDBG(DebugOut(DEBUG_ERROR, L"bthns_UninitializeOnce:: ERROR_SERVICE_DOES_NOT_EXIST\n"));
		return ERROR_SERVICE_DOES_NOT_EXIST;
	}
	gpBthNS->Lock();

	if (gpBthNS->eStage != JustCreated) {
		IFDBG(DebugOut(DEBUG_ERROR, L"bthns_UninitializeOnce:: ERROR_DEVICE_IN_USE\n"));
		gpBthNS->Unlock();
		return ERROR_DEVICE_IN_USE;
	}

	BthNs *pBthNs = gpBthNS;
	gpBthNS = NULL;
	pBthNs->Unlock();
	delete pBthNs;

	IFDBG(DebugOut(DEBUG_SDP_INIT, L"bthns_UninitializeOnce:: ERROR_SUCCESS\n"));
	return ERROR_SUCCESS;
}


static DWORD WINAPI StackDisconnect (LPVOID pArg) {
	IFDBG(DebugOut (DEBUG_SDP_TRACE, L"StackDisconnect\n"));
	bthns_CloseDriverInstance ();
	return NULL;
}

static int bthns_StackEvent(void *pUserContext, int iEvent, void *pEventContext) {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"bthns_StackEvent:: event = %d\r\n"));

	// We only handle BTH_STACK_DISCONNECT at this layer.  We just BthNsHandle into SDP
	// in all cases and let it keep track of stack state beyond this.
	if (iEvent == BTH_STACK_DISCONNECT)
		btutil_ScheduleEvent (StackDisconnect, NULL);

	return ERROR_SUCCESS;
}

//
// WSA Interface helpers.
//
void SDPAbortCall(HANDLE h, Call *pCall) {
	DebugOut(DEBUG_SDP_TRACE,L"SDPAbortCall (0x%08x)\r\n",pCall);
	BT_LAYER_ABORT_CALL  pCallback = gpBthNS->sdp_if.sdp_AbortCall;

	__try {
		pCallback(h,pCall);
	}
	__except (1) {
		;
	}
}

int SDPConnectBlocking(Call *pCall, BD_ADDR *pba)  {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"SDPConnectBlocking (0x%04x 0x%08x)\r\n",pba->NAP,pba->SAP));
	int iRet;
	HANDLE hEvent = pCall->hEvent;
	HANDLE h      = gpBthNS->hSDP;

	SDP_Connect_In pCallback = gpBthNS->sdp_if.sdp_Connect_In;

	gpBthNS->AddRef();
	gpBthNS->Unlock();

	__try {
		iRet = pCallback(h,pCall,pba);
	}
	__except (1) {
		;
	}

	// We don't have a timeout here because on connection lower layers handles timeouts.
	if (ERROR_SUCCESS == iRet) {
		if (WAIT_TIMEOUT == WaitForSingleObject(hEvent,INFINITE)) {
			SVSUTIL_ASSERT(0);
			iRet = ERROR_OPERATION_ABORTED;
			SDPAbortCall(h,pCall);
		}
	}

	gpBthNS->Lock();
	gpBthNS->DelRef();
	return iRet;
}

int SDPDisconnect(Call *pCall, unsigned short cid) {
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"SDPDisconnectBlocking (0x%08x,0x%04x)\r\n",pCall,cid));
	int iRet;
	HANDLE h = gpBthNS->hSDP;
	HANDLE hEvent = pCall ? pCall->hEvent : 0;

	SDP_Disconnect_In pCallback = gpBthNS->sdp_if.sdp_Disconnect_In;

	gpBthNS->AddRef();
	gpBthNS->Unlock();

	__try {
		iRet = pCallback(h,pCall,cid);
	} __except(1)  {
		;
	}

	// We don't have a timeout here because on connection lower layers handles timeouts.
	if ((ERROR_SUCCESS == iRet) && hEvent) {
		if (WAIT_OBJECT_0 != WaitForSingleObject(hEvent,INFINITE)) {
			SVSUTIL_ASSERT(0);
			iRet = ERROR_OPERATION_ABORTED;
		}
	}

	gpBthNS->Lock();
	gpBthNS->DelRef();
	return iRet;
}

int ServiceSearchBlocking(Call *pCall, unsigned short cid, SdpQueryUuid* pUUIDs, unsigned short cMaxHandles)  {
	SVSUTIL_ASSERT(gpBthNS->eStage == Running);
	HANDLE hEvent = pCall->hEvent;
	HANDLE h      = gpBthNS->hSDP;
	int iRet;

	SDP_ServiceSearch_In pCallback = gpBthNS->sdp_if.sdp_ServiceSearch_In;

	gpBthNS->AddRef();
	gpBthNS->Unlock();

	__try {
		iRet = pCallback(h,pCall,cid,pUUIDs,cMaxHandles);
	} __except(1) {
		;
	}

	if (ERROR_SUCCESS == iRet) {
		if (WAIT_TIMEOUT == WaitForSingleObject(hEvent,g_dwSearchTimeout)) {
			iRet = ERROR_OPERATION_ABORTED;
			SDPAbortCall(h,pCall);
		}
	}

	gpBthNS->Lock();
	gpBthNS->DelRef();
	return iRet;
}


int AttributeSearchBlocking(Call *pCall, unsigned short cid, unsigned long recordHandle, SdpAttributeRange *pAttribRange, int numAttributes)  {
	SVSUTIL_ASSERT(gpBthNS->eStage == Running);
	HANDLE hEvent = pCall->hEvent;
	HANDLE h      = gpBthNS->hSDP;
	int iRet;

	SDP_AttributeSearch_In pCallback = gpBthNS->sdp_if.sdp_AttributeSearch_In;
	
	gpBthNS->AddRef();
	gpBthNS->Unlock();

	__try {
		iRet = pCallback(h,pCall,cid,recordHandle,pAttribRange,numAttributes);
	} __except(1) {
		;
	}

	if (ERROR_SUCCESS == iRet) {
		if (WAIT_TIMEOUT == WaitForSingleObject(hEvent,g_dwSearchTimeout)) {
			iRet = ERROR_OPERATION_ABORTED;
			SDPAbortCall(h,pCall);
		}
	}

	gpBthNS->Lock();
	gpBthNS->DelRef();
	return iRet;
}

int ServiceAttributeSearchBlocking(Call *pCall, unsigned short cid, SdpQueryUuid* pUUIDs, SdpAttributeRange *pAttribRange, int numAttributes)  {
	SVSUTIL_ASSERT(gpBthNS->eStage == Running);
	HANDLE hEvent = pCall->hEvent;
	HANDLE h      = gpBthNS->hSDP;
	int iRet;

	SDP_ServiceAttributeSearch_In pCallback = gpBthNS->sdp_if.sdp_ServiceAttributeSearch_In;

	gpBthNS->AddRef();
	gpBthNS->Unlock();

	__try {
		iRet = pCallback(h,pCall,cid,pUUIDs,pAttribRange,numAttributes);
	} __except(1) {
		;
	}

	if (ERROR_SUCCESS == iRet) {
		if (WAIT_TIMEOUT == WaitForSingleObject(hEvent,g_dwSearchTimeout)) {
			iRet = ERROR_OPERATION_ABORTED;
			SDPAbortCall(h,pCall);
		}
	}

	gpBthNS->Lock();
	gpBthNS->DelRef();
	return iRet;
}

typedef enum  {
	BTHNS_SET_SERVICE,
	BTHNS_LOOKUP_SERVICE_BEGIN,
	BTHNS_LOOKUP_SERVICE_NEXT
} BTHNS_WSA_CALL;

#define SDP_WSA_SERVICE_BEGIN_FLAGS   (LUP_RES_SERVICE | LUP_CONTAINERS)

static BOOL CheckQuerySet(LPWSAQUERYSET pQuerySet, BTHNS_WSA_CALL BthNsHandleer, DWORD dwFlags, WSAESETSERVICEOP op=RNRSERVICE_DEREGISTER)  {
	if (!pQuerySet || pQuerySet->dwSize != sizeof(WSAQUERYSETA) || pQuerySet->dwNameSpace != NS_BTH)
		return FALSE;

	switch (BthNsHandleer)  {
		case BTHNS_SET_SERVICE: {
			if (op != RNRSERVICE_REGISTER && op != RNRSERVICE_DELETE)
				return FALSE;

			if (dwFlags)
				return FALSE;

//			if (!pQuerySet->dwNumberOfCsAddrs || !pQuerySet->lpcsaBuffer)
//				return FALSE;

			PBTHNS_SETBLOB pSetBlob = (PBTHNS_SETBLOB) (pQuerySet->lpBlob ? pQuerySet->lpBlob->pBlobData : NULL);
			if (!pSetBlob || !pSetBlob->pSdpVersion || (*pSetBlob->pSdpVersion != BTH_SDP_VERSION) || !pSetBlob->pRecordHandle || ((op == RNRSERVICE_REGISTER) && !pSetBlob->ulRecordLength))
				return FALSE;
		}
		break;

		case BTHNS_LOOKUP_SERVICE_BEGIN:  {
			PBTHNS_RESTRICTIONBLOB pResBlob = (PBTHNS_RESTRICTIONBLOB) (pQuerySet->lpBlob ?  pQuerySet->lpBlob->pBlobData : NULL);
			if (dwFlags & ~SDP_WSA_SERVICE_BEGIN_FLAGS)
				return FALSE;

			if (dwFlags & LUP_CONTAINERS) {
				LPBLOB lpBlob = pQuerySet->lpBlob;
				if (lpBlob && (lpBlob->cbSize != sizeof(BTHNS_INQUIRYBLOB)))
					return FALSE;

				return TRUE; // it's OK for lpBlob to be NULL or non-NULL when doing device inquiry.
			}

			// pQuerySet->lpServiceClassId can be set on Service or ServiceAttribute requests.
			// If pResBlob is set we use it, it has more interesting info.
			if (!pQuerySet->lpServiceClassId && !pResBlob)
				return FALSE;

			if (!(dwFlags & LUP_RES_SERVICE)) {
				// lpcsaBuffer contains an AddrInfo and is supported only on WinCE, specifies remote device to query.
				// pQuerySet->lpszContext contains a string representation of a bluetooth address of remote device to query, and is for XP compat.  
				if (!pQuerySet->lpszContext && !pQuerySet->lpcsaBuffer)
					return FALSE;

				// lpszContext will be checked when we try to do conversion, just do lpcsaBuffer now.
				if (pQuerySet->lpcsaBuffer) {
					if ((!pQuerySet->lpcsaBuffer->RemoteAddr.lpSockaddr || (pQuerySet->lpcsaBuffer->RemoteAddr.iSockaddrLength != sizeof(SOCKADDR_BTH))))  {
						return FALSE;
					}

#if defined (DEBUG) || defined (_DEBUG)
					if (! __SDP_IS_ALIGNED(pQuerySet->lpcsaBuffer->RemoteAddr.lpSockaddr, 8))
						DebugOut(DEBUG_SDP_TRACE, L"SDP: Unaligned remote address in structure - FIX THE APP!!\n");
#endif
				}
			}

			if (pResBlob && !(dwFlags&LUP_CONTAINERS))  {
				switch (pResBlob->type) {
					case SDP_SERVICE_SEARCH_REQUEST:			
					break;

					case SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST:
					case SDP_SERVICE_ATTRIBUTE_REQUEST:
						if (!pResBlob->numRange ||  ((pQuerySet->lpBlob->cbSize - sizeof(BTHNS_RESTRICTIONBLOB)) % sizeof(SdpAttributeRange))  ||
						   (((pQuerySet->lpBlob->cbSize - sizeof(BTHNS_RESTRICTIONBLOB)) / sizeof(SdpAttributeRange) + 1) != pResBlob->numRange))
							return FALSE;
					break;

					default:
						return FALSE;
				}
			}
		}
		break;

		case BTHNS_LOOKUP_SERVICE_NEXT:  {
			if (!pQuerySet)
				return FALSE;
		}
		break;

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


int MapErrorCodeToWinsockErr(int iError, BOOL fFromSetService=FALSE) {
	switch (iError) {

	// either lower layer failed, SDP timed out, or BthNsLookupServiceEnd() 
	// was called on pending search thread.
	case ERROR_OPERATION_ABORTED:
	case ERROR_CONNECTION_ABORTED:
	case ERROR_SHUTDOWN_IN_PROGRESS:
	case ERROR_CANCELLED:
		return WSA_E_CANCELLED;

	case ERROR_INTERNAL_ERROR:
	case ERROR_INVALID_PARAMETER:
		return WSAEINVAL;

	case ERROR_OUTOFMEMORY:
		return WSA_NOT_ENOUGH_MEMORY;

	case ERROR_NOT_FOUND:
		return fFromSetService ? WSA_INVALID_HANDLE : WSANO_DATA;

	case ERROR_SERVICE_NOT_ACTIVE:
		return WSASERVICE_NOT_FOUND;

	case ERROR_CONNECTION_UNAVAIL:
		return WSAENOTCONN;

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

//
//  Public interface, equivalent to WSA Set/Lookup functions.
//
//  NOTE: This is preliminary, pending official data structures from NT.
//
int BthNsSetService(LPWSAQUERYSET pSet, WSAESETSERVICEOP op, DWORD dwFlags) {	
	IFDBG(DebugOut(DEBUG_SDP_TRACE,L"BthNsSetService entered\r\n"));

	if (! gpBthNS) {
		IFDBG(DebugOut(DEBUG_ERROR, L"BthNsSetService:: ERROR_SERVICE_DOES_NOT_EXIST\n"));
		SetLastError(WSASERVICE_NOT_FOUND);
		return SOCKET_ERROR;
	}
	
	gpBthNS->Lock();
	if (gpBthNS->eStage != Running) {
		IFDBG(DebugOut(DEBUG_ERROR, L"BthNsSetService:: ERROR_SERVICE_NOT_ACTIVE\n"));
		gpBthNS->Unlock();

⌨️ 快捷键说明

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