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

📄 btd.cxx

📁 三星2440原版bsp
💻 CXX
📖 第 1 页 / 共 5 页
字号:
		int cHciHeaders = 0;
		int cHciTrailers = 0;		
		int cLinkType = 0;
		int cControl = BTH_CONTROL_DEVICEONLY | BTH_CONTROL_ROUTE_SECURITY | BTH_CONTROL_ROUTE_HARDWARE;
		
		if (RouteSCOControl()) {
			// If SCO audio routing is supported in hardware, we need
			// to get ConnectionRequest messages for SCO connections
			cControl |= BTH_CONTROL_ROUTE_BY_LINKTYPE;
			cLinkType = BTH_LINK_TYPE_SCO;
		}

		if (ERROR_SUCCESS != HCI_EstablishDeviceContext (this, cControl, NULL, 0, cLinkType, &hei, &hc, &hci_if, &cHciHeaders, &cHciTrailers, &hHCI))
			return;

		fIsRunning = TRUE;

		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: new BTSHELL successful\n"));
	}

	~BTSHELL (void) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: delete BTSHELL\n"));
		if (hL2CAP)
			L2CAP_CloseDeviceContext (hL2CAP);

		if (hHCI)
			HCI_CloseDeviceContext (hHCI);

		if (pfmdCalls)
			svsutil_ReleaseFixedNonEmpty (pfmdCalls);

		if (pfmdSecurity)
			svsutil_ReleaseFixedNonEmpty (pfmdSecurity);

		if (pfmdLinks)
			svsutil_ReleaseFixedNonEmpty (pfmdLinks);

		if (hAddrEvent)
			CloseHandle(hAddrEvent);

		for (int i = 0 ; i < BTD_EVENT_NUMBER ; ++i)
			CloseHandle (hNamedEvents[i]);
	}
};

typedef void (*PFN_SYSTEM_TIMER_RESET) (void);

static BTSHELL *gpState = NULL;
static HANDLE ghBthApiEvent = NULL;
static PFN_SYSTEM_TIMER_RESET gfnSystemTimerReset = NULL;

//
//	Auxiliary code
//
static PINRequest *GetNewPINRequest (void) {
	PINRequest *pResult = gpState->pFree;
	if (pResult)
		gpState->pFree = pResult->pNext;

	return pResult;
}

static void FreeRequest (PINRequest *pPinReq) {	// This unlocks...
#if defined (DEBUG) || defined (_DEBUG)
	for (int i = 0 ; i < MAX_PENDING_PIN_REQUESTS ; ++i) {
		if (pPinReq == &gpState->pin_reqs[i])
			break;
	}

	SVSUTIL_ASSERT (i != MAX_PENDING_PIN_REQUESTS);

	PINRequest *p = gpState->pFree;
	while (p) {
		SVSUTIL_ASSERT (p != pPinReq);
		p = p->pNext;
	}

	p = gpState->pRequested;
	while (p) {
		SVSUTIL_ASSERT (p != pPinReq);
		p = p->pNext;
	}

	p = gpState->pInService;
	while (p) {
		SVSUTIL_ASSERT (p != pPinReq);
		p = p->pNext;
	}
#endif

	pPinReq->pNext = gpState->pFree;
	gpState->pFree = pPinReq;

	if (pPinReq->fConnectionLocked)
		LockL2CAPConnection (&pPinReq->ba, FALSE);	// This unlocks the state
}

static void CleanUpSecurityUIHandler (void) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: security handler does not exist any more - cleaning up!\n"));

	gpState->hSecurityUIEvent = NULL;
	gpState->hSecurityUIProc = NULL;
	gpState->dwSecurityProcPermissions = 0;

	gpState->dwPINRequestStoreTimeout = 0;
	gpState->dwPINRequestProcessTimeout = 0;
}

static void FinishTimeout (LPVOID pArg, PINRequest **pChain) {
	PINRequest *pParent = NULL;
	PINRequest *pThis = *pChain;

	while (pThis && pThis != pArg)
		pThis = pThis->pNext;


	if (! pThis) {
		gpState->Unlock ();
		return;
	}

	if (pParent)
		pParent->pNext = pThis->pNext;
	else
		*pChain = pThis->pNext;

	BD_ADDR ba = pThis->ba;

	HANDLE h = gpState->hHCI;

	HCI_PINCodeRequestNegativeReply_In pCallbackNo = gpState->hci_if.hci_PINCodeRequestNegativeReply_In;

	FreeRequest (pThis);

	gpState->Unlock ();

	__try {
		pCallbackNo (h, NULL, &ba);
	} __except (1) {
		IFDBG(DebugOut (DEBUG_ERROR, L"[SHELL] Exception in hci_PINCodeRequest[Negative]Reply\n"));
	}
}

static DWORD WINAPI StorePINTimeout (LPVOID pArg) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"StorePINTimeout\n"));

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if (! gpState->fIsRunning) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	FinishTimeout (pArg, &gpState->pRequested);	// This unlocks

	return 0;
}

static DWORD WINAPI ServicePINTimeout (LPVOID pArg) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"ServicePINTimeout\n"));

	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if (! gpState->fIsRunning) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	FinishTimeout (pArg, &gpState->pInService);	// This unlocks

	return 0;
}

static int AddNewPINRequest (BD_ADDR *pba) {
	if (! gpState->hSecurityUIEvent) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell AddNewPINRequest: security handler not installed!\n"));
		return FALSE;
	}

	DWORD dwPerms = SetProcPermissions (gpState->dwSecurityProcPermissions);
	BOOL bRes = SetEvent (gpState->hSecurityUIEvent);
	SetProcPermissions (dwPerms);

	if (! bRes) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell AddNewPINRequest: security handler failed\n"));

		CleanUpSecurityUIHandler ();
		return FALSE;
	}

	PINRequest *pPRE = gpState->pRequested;
	while (pPRE) {
		if (pPRE->ba == *pba)
			break;

		pPRE = pPRE->pNext;
	}

	if (! pPRE) {
		pPRE = gpState->pInService;
		while (pPRE) {
			if (pPRE->ba == *pba)
				break;

			pPRE = pPRE->pNext;
		}
	}

	if (pPRE) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell AddNewPINRequest: %04x%08x already in process\n", pba->NAP, pba->SAP));
		return FALSE;
	}

	pPRE = GetNewPINRequest ();

	if (! pPRE) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell AddNewPINRequest: - no free slots for PIN requests!\n"));
		return FALSE;
	}

	memset (pPRE, 0, sizeof(*pPRE));

	pPRE->ba = *pba;
	pPRE->pNext = gpState->pRequested;
	gpState->pRequested = pPRE;
	pPRE->dwTimeOutCookie = btutil_ScheduleEvent (StorePINTimeout, pPRE, gpState->dwPINRequestStoreTimeout);

	pPRE->fConnectionLocked = LockL2CAPConnection (pba, TRUE);

	return TRUE;
}

static void UnscheduleAllPINReqests (void) {
	PINRequest *p = gpState->pRequested;
	while (p) {
		btutil_UnScheduleEvent (p->dwTimeOutCookie);
		p->dwTimeOutCookie = 0;
		p = p->pNext;
	}

	p = gpState->pInService;
	while (p) {
		btutil_UnScheduleEvent (p->dwTimeOutCookie);
		p->dwTimeOutCookie = 0;
		p = p->pNext;
	}
}


static BTSHELL *CreateNewState (void) {
	return new BTSHELL;
}

static InquiryBuffer *CreateNewInquiryBuffer (void) {
	return new InquiryBuffer;
}

static SCall *AllocCall (int fWhat) {
	SCall *pCall = (SCall *)svsutil_GetFixed (gpState->pfmdCalls);
	if (! pCall)
		return NULL;
	
	memset (pCall, 0, sizeof(*pCall));

	pCall->hProcOwner = GetOwnerProcess ();
	pCall->fWhat = fWhat;
	
	pCall->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
	if (NULL == pCall->hEvent) {
		svsutil_FreeFixed (pCall, gpState->pfmdCalls);
		return NULL;
	}

	pCall->pNext = gpState->pCalls;
	gpState->pCalls = pCall;
		
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: Allocated call 0x%08x what = 0x%02x\n", pCall, fWhat));

	return pCall;
}

static void DeleteCall (SCall *pCall) {
	if (pCall == gpState->pCalls)
		gpState->pCalls = pCall->pNext;
	else {
		SCall *pParent = gpState->pCalls;
		while (pParent && (pParent->pNext != pCall))
			pParent = pParent->pNext;

		if (! pParent) {
			IFDBG(DebugOut (DEBUG_ERROR, L"Shell: call not in list in DeleteCall!\n"));

			return;
		}

		pParent->pNext = pCall->pNext;
	}

	CloseHandle (pCall->hEvent);

	svsutil_FreeFixed (pCall, gpState->pfmdCalls);
}

static SCall *VerifyCall (SCall *pCall) {
	SCall *p = gpState->pCalls;
	while (p && (p != pCall))
		p = p->pNext;

#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
	if (! p)
		IFDBG(DebugOut (DEBUG_ERROR, L"Shell: call verify failed!\n"));
#endif

	return p;
}

static SCall *FindCall (unsigned int fOp) {
	SCall *p = gpState->pCalls;
	while (p && (p->fWhat != fOp))
		p = p->pNext;

#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
	if (! p)
		IFDBG(DebugOut (DEBUG_ERROR, L"Shell: call find failed!\n"));
#endif

	return p;
}

static DWORD WINAPI StackDisconnect (LPVOID lpVoid) {
	IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"Shell: DisconnectStack\n"));

	btshell_CloseDriverInstance ();

	return ERROR_SUCCESS;
}

static DWORD WINAPI StackDown (LPVOID lpVoid) {
	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if ((! gpState->fIsRunning) || (! gpState->fConnected)) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpState->fConnected = FALSE;

	memset (&gpState->b, 0, sizeof(gpState->b));

	UnscheduleAllPINReqests ();

	gpState->ClearPinRequests ();

	SCall *pC = gpState->pCalls;
	while (pC) {
		if (! pC->fComplete) {
			pC->fComplete = TRUE;
			pC->iResult = ERROR_CONNECTION_UNAVAIL;
			SetEvent (pC->hEvent);
		} else {
			if (pC->iResult == ERROR_SUCCESS)
				pC->iResult = ERROR_CONNECTION_UNAVAIL;
		}

		pC = pC->pNext;
	}

	while (gpState->pLinks) {
		IFDBG(DebugOut (DEBUG_SHELL_TRACE, L"StackDown : Deleting link 0x%04x\n", gpState->pLinks->h));

		Link *pNext = gpState->pLinks->pNext;
		svsutil_FreeFixed (gpState->pLinks, gpState->pfmdLinks);
		gpState->pLinks = pNext;
	}

	SetEvent (gpState->hNamedEvents[BTD_EVENT_HARDWARE_CHANGED]);
	ResetEvent (gpState->hNamedEvents[BTD_EVENT_HARDWARE_CHANGED]);

	gpState->Unlock ();
	return ERROR_SUCCESS;
}

static DWORD WINAPI StackUp (LPVOID lpVoid) {
	if (! gpState)
		return ERROR_SERVICE_NOT_ACTIVE;

	gpState->Lock ();
	if ((! gpState->fIsRunning) || gpState->fConnected) {
		gpState->Unlock ();

		return ERROR_SERVICE_NOT_ACTIVE;
	}

	gpState->fConnected = TRUE;
    ResetEvent (gpState->hAddrEvent);
    
	SCall *pCall = AllocCall (CALL_HCI_READ_BD_ADDR);
	if (! pCall) {
		gpState->Unlock ();
		return ERROR_OUTOFMEMORY;
	}

	pCall->hProcOwner = NULL;

	HANDLE hEvent = pCall->hEvent;
	HCI_ReadBDADDR_In pCallback = gpState->hci_if.hci_ReadBDADDR_In;
	HANDLE hHCI = gpState->hHCI;
	gpState->AddRef ();
	gpState->Unlock ();
	int iRes = ERROR_INTERNAL_ERROR;
	__try {
		iRes = pCallback (hHCI, pCall);
	} __except (1) {
	}

	if (iRes == ERROR_SUCCESS)
		WaitForSingleObject (hEvent, 5000);

	gpState->Lock ();
	gpState->DelRef ();

    SetEvent (gpState->hAddrEvent);
 
	if (! gpState->fIsRunning) {
		gpState->Unlock ();
		return ERROR_CANCELLED;

⌨️ 快捷键说明

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