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

📄 hci.cxx

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

	if (status == 0) {
		if ((features_mask[0] & 0x20) == 0)
			gpHCI->transport.uiFlags |= HCI_FLAGS_NOROLESWITCH;
	}

	InternalCommand *pArgs = (InternalCommand *)pCallContext;
	pArgs->status     = status;
	pArgs->fCompleted = TRUE;
	SetEvent (pArgs->hEvent);

	return TRUE;
}

static int InitAborted (void *pCallContext, int iError) {
	InternalCommand *pArgs = (InternalCommand *)pCallContext;
	pArgs->fCompleted = FALSE;
	SetEvent (pArgs->hEvent);

	return TRUE;
}

static void FormatPacketNoArgs(HCIPacket *pP, unsigned short usOpCode) {
	SVSUTIL_ASSERT (pP->pContents->cSize == 3);
	SVSUTIL_ASSERT (pP->pContents->cStart == 0);
	SVSUTIL_ASSERT (pP->pContents->cEnd == pP->pContents->cSize);

	IFDBG(DebugOut (DEBUG_HCI_PACKETS, L"FormatPacketNoArgs:: op %04x\n", usOpCode));

	pP->pContents->pBuffer[pP->pContents->cStart + 0] = usOpCode & 0xff;
	pP->pContents->pBuffer[pP->pContents->cStart + 1] = (usOpCode >> 8) & 0xff;
	pP->pContents->pBuffer[pP->pContents->cStart + 2] = 0;

	pP->uPacket.CommandPacket.opCode = usOpCode;
}

static void RetireInquiryData (void) {
	InquiryResultList *pInq = gpHCI->pInquiryResults;
	InquiryResultList *pParent = NULL;

	DWORD dwNow = GetTickCount ();

	while (pInq) {
		if ((DWORD)(dwNow - pInq->irb.dwTick) >= gpHCI->transport.uiDriftFactor) {
			if (! pParent)
				gpHCI->pInquiryResults = pInq->pNext;
			else
				pParent->pNext = pInq->pNext;

			delete pInq;

			if (! pParent)
				pInq = gpHCI->pInquiryResults;
			else
				pInq = pParent->pNext;
			continue;
		}

		pParent = pInq;
		pInq = pInq->pNext;
	}
}

//
//	Communicate stack event up
//
static void DispatchStackEvent (int iEvent, HCIEventContext *pEventContext) {
	HCI_CONTEXT *pContext = gpHCI->pContexts;
	while (pContext) {
		BT_LAYER_STACK_EVENT_IND pCallback = pContext->ei.hci_StackEvent;
		if (pCallback) {
			void *pUserContext = pContext->pUserContext;

			IFDBG(DebugOut (DEBUG_HCI_CALLBACK, L"Going into StackEvent notification\n"));
			gpHCI->AddRef ();
			gpHCI->Unlock ();

			__try {
				pCallback (pUserContext, iEvent, pEventContext);
			} __except (1) {
				IFDBG(DebugOut (DEBUG_ERROR, L"[HCI] DispatchStackEvent: exception in hci_StackEvent!\n"));
			}

			gpHCI->Lock ();
			gpHCI->Release ();
			IFDBG(DebugOut (DEBUG_HCI_CALLBACK, L"Came back StackEvent notification\n"));
		}

		//	Note: this is legal because we don't deref HCI and disconnect will always wait for ref to drop
		pContext = pContext->pNext;
	}
}

//
//	Communicate stack event up
//
static void NotifyMonitors (unsigned char *pBuffer, int cSize) {
	HCI_CONTEXT *pContext = gpHCI->pContexts;

	HCIEventContext e;
	e.Event.cSize = cSize;
	e.Event.pData = pBuffer;

	while ((gpHCI->eStage == Connected) && pContext) {
		BT_LAYER_STACK_EVENT_IND pCallback = pContext->ei.hci_StackEvent;
		if ((pContext->uiControl & BTH_CONTROL_ROUTE_HARDWARE) && pCallback) {
			void *pUserContext = pContext->pUserContext;

			IFDBG(DebugOut (DEBUG_HCI_CALLBACK, L"Going into StackEvent monitor notification\n"));
			gpHCI->AddRef ();
			gpHCI->Unlock ();

			__try {
				pCallback (pUserContext, BTH_STACK_HCI_HARDWARE_EVENT, &e);
			} __except (1) {
				IFDBG(DebugOut (DEBUG_ERROR, L"[HCI] NotifyMonitors: exception in hci_StackEvent!\n"));
			}

			gpHCI->Lock ();
			gpHCI->Release ();
			IFDBG(DebugOut (DEBUG_HCI_CALLBACK, L"Came back StackEvent notification\n"));
		}

		//	Note: this is legal because we don't deref HCI and disconnect will always wait for ref to drop
		pContext = pContext->pNext;
	}
}

//
//	Schedule packet
//
static void SchedulePacket (HCIPacket *pPacket) {
	if ((pPacket->ePacketType == DATA_PACKET_ACL) || (pPacket->ePacketType == DATA_PACKET_SCO))
		IFDBG(DebugOut (DEBUG_HCI_PACKETS, L"SchedulePacket:: [call %08x device %08x] packet 0x%08x data len %d\n", pPacket->pCallContext, pPacket->pOwner, pPacket, BufferTotal (pPacket->pContents)));
	else {
		IFDBG(DebugOut (DEBUG_HCI_PACKETS, L"SchedulePacket:: [call %08x device %08x] packet 0x%08x  op %04x\n", pPacket->pCallContext, pPacket->pOwner, pPacket, pPacket->uPacket.CommandPacket.opCode));
		SVSUTIL_ASSERT (pPacket->ePacketType == COMMAND_PACKET);

		SVSUTIL_ASSERT ((pPacket->uPacket.CommandPacket.eEvent != HCI_NO_EVENT) || (pPacket->uPacket.CommandPacket.opCode == HCI_Host_Number_Of_Completed_Packets));

		SVSUTIL_ASSERT (pPacket->pContents->cSize >= 3);
		SVSUTIL_ASSERT (pPacket->pContents->cStart == 0);
		SVSUTIL_ASSERT (pPacket->pContents->cEnd == pPacket->pContents->cSize);
		SVSUTIL_ASSERT (pPacket->pContents->pBuffer[2] + 3 == BufferTotal (pPacket->pContents));

	}

	SVSUTIL_ASSERT (gpHCI->IsLocked ());
	SVSUTIL_ASSERT (! pPacket->pNext);

	if (! gpHCI->pPackets)
		gpHCI->pPackets = pPacket;
	else {
		HCIPacket *pParent = gpHCI->pPackets;
		while (pParent->pNext)
			pParent = pParent->pNext;
		pParent->pNext = pPacket;
	}

	SetEvent (gpHCI->hQueue);
}

static int bt_custom_code_internal
(
HCI_CONTEXT		*pContext,
void			*pCallContext,
unsigned short	usOpCode,
unsigned short	cPacketSize,
unsigned char	*pPacketBody,
PacketMarker    *pMarker,
unsigned char	cEvent
) {
	SVSUTIL_ASSERT ((cEvent != HCI_NO_EVENT) || (usOpCode == HCI_Host_Number_Of_Completed_Packets));

	HCIPacket *pP = new HCIPacket  (COMMAND_PACKET, pContext, pCallContext, cPacketSize + 3);
	if (! (pP && pP->pContents)) {
		if (pP)
			delete pP;
		IFDBG(DebugOut (DEBUG_ERROR, L"bt_custom_code_internal returns ERROR_OUTOFMEMORY\n"));
		return ERROR_OUTOFMEMORY;
	}

	SVSUTIL_ASSERT (pP->pContents->cEnd == pP->pContents->cSize);
	SVSUTIL_ASSERT (pP->pContents->cStart == 0);
	SVSUTIL_ASSERT (! pP->pContents->fMustCopy);

	pP->uPacket.CommandPacket.opCode = usOpCode;
	pP->uPacket.CommandPacket.eEvent = (HCI_EVENT_CODE)cEvent;
	pP->pContents->pBuffer[0] = usOpCode & 0xff;
	pP->pContents->pBuffer[1] = (usOpCode >> 8) & 0xff;
	pP->pContents->pBuffer[2] = cPacketSize & 0xff;
	if (cPacketSize)
		memcpy (pP->pContents->pBuffer + 3, pPacketBody, cPacketSize);

	if (pMarker)
		pP->uPacket.CommandPacket.m = *pMarker;

	SchedulePacket (pP);

	return ERROR_SUCCESS;
}

static HCIPacket *FindCommandPacket (HCIPacket *pList, unsigned short usOpCode) {
	HCIPacket *pPacket = pList;
	while (pPacket) {
		if (pPacket->ePacketType == COMMAND_PACKET) {
			SVSUTIL_ASSERT (pPacket->pContents->cSize >= 3);
			SVSUTIL_ASSERT (pPacket->pContents->cStart == 0);
		SVSUTIL_ASSERT (pPacket->pContents->cEnd == pPacket->pContents->cSize);
			SVSUTIL_ASSERT (pPacket->pContents->pBuffer[2] + 3 == BufferTotal (pPacket->pContents));
		}

		if ((pPacket->ePacketType == COMMAND_PACKET) && (usOpCode == pPacket->uPacket.CommandPacket.opCode)) {
			SVSUTIL_ASSERT (pPacket->uPacket.CommandPacket.m.fMarker == BTH_MARKER_NONE);
			return pPacket;
		}

		pPacket = pPacket->pNext;
	}

	return NULL;
}

static HCIPacket *ExtractCommandPacketByEvent (HCIPacket **pList, unsigned char cEvent) {
	HCIPacket *pPacket = *pList;
	HCIPacket *pParent = NULL;
	while (pPacket) {
		if (pPacket->ePacketType == COMMAND_PACKET) {
			SVSUTIL_ASSERT (pPacket->pContents->cSize >= 3);
			SVSUTIL_ASSERT (pPacket->pContents->cStart == 0);
			SVSUTIL_ASSERT (pPacket->pContents->cEnd == pPacket->pContents->cSize);
			SVSUTIL_ASSERT (pPacket->pContents->pBuffer[2] + 3 == BufferTotal (pPacket->pContents));
		}

		if ((pPacket->ePacketType == COMMAND_PACKET) && (pPacket->uPacket.CommandPacket.eEvent == cEvent)) {
			if (pParent)
				pParent->pNext = pPacket->pNext;
			else {
				SVSUTIL_ASSERT (pPacket == *pList);
				*pList = (*pList)->pNext;
			}
			return pPacket;
		}

		pParent = pPacket;
		pPacket = pPacket->pNext;
	}

	return NULL;
}

static HCIPacket *ExtractCommandPacket (HCIPacket **pList, unsigned short usOpCode, int fIgnoreMarker = FALSE) {
	HCIPacket *pPacket = *pList;
	HCIPacket *pParent = NULL;
	while (pPacket) {
		if (pPacket->ePacketType == COMMAND_PACKET) {
			SVSUTIL_ASSERT (pPacket->pContents->cSize >= 3);
			SVSUTIL_ASSERT (pPacket->pContents->cStart == 0);
			SVSUTIL_ASSERT (pPacket->pContents->cEnd == pPacket->pContents->cSize);
			SVSUTIL_ASSERT (pPacket->pContents->pBuffer[2] + 3 == BufferTotal (pPacket->pContents));
		}

		if ((pPacket->ePacketType == COMMAND_PACKET) && (usOpCode == pPacket->uPacket.CommandPacket.opCode)) {
			SVSUTIL_ASSERT (fIgnoreMarker || (pPacket->uPacket.CommandPacket.m.fMarker == BTH_MARKER_NONE));
			if (pParent)
				pParent->pNext = pPacket->pNext;
			else {
				SVSUTIL_ASSERT (pPacket == *pList);
				*pList = (*pList)->pNext;
			}
			return pPacket;
		}

		pParent = pPacket;
		pPacket = pPacket->pNext;
	}

	return NULL;
}

static HCIPacket *FindCommandPacket (HCIPacket *pList, unsigned short usOpCode, unsigned connection_handle) {
	HCIPacket *pPacket = pList;
	HCIPacket *pParent = NULL;
	while (pPacket) {
		if (pPacket->ePacketType == COMMAND_PACKET) {
			SVSUTIL_ASSERT (pPacket->pContents->cSize >= 3);
			SVSUTIL_ASSERT (pPacket->pContents->cStart == 0);
			SVSUTIL_ASSERT (pPacket->pContents->cEnd == pPacket->pContents->cSize);
			SVSUTIL_ASSERT (pPacket->pContents->pBuffer[2] + 3 == BufferTotal (pPacket->pContents));
		}


		if ((pPacket->ePacketType == COMMAND_PACKET) && (usOpCode == pPacket->uPacket.CommandPacket.opCode)) {
			SVSUTIL_ASSERT (pPacket->uPacket.CommandPacket.m.fMarker == BTH_MARKER_CONNECTION);
			if (pPacket->uPacket.CommandPacket.m.connection_handle == connection_handle)
				return pPacket;
		}

		pParent = pPacket;
		pPacket = pPacket->pNext;
	}

	return NULL;
}


static HCIPacket *ExtractCommandPacket (HCIPacket **pList, unsigned short usOpCode, unsigned short connection_handle) {
	HCIPacket *pPacket = *pList;
	HCIPacket *pParent = NULL;
	while (pPacket) {
		if (pPacket->ePacketType == COMMAND_PACKET) {
			SVSUTIL_ASSERT (pPacket->pContents->cSize >= 3);
			SVSUTIL_ASSERT (pPacket->pContents->cStart == 0);
			SVSUTIL_ASSERT (pPacket->pContents->cEnd == pPacket->pContents->cSize);
			SVSUTIL_ASSERT (pPacket->pContents->pBuffer[2] + 3 == BufferTotal (pPacket->pContents));
		}

		if ((pPacket->ePacketType == COMMAND_PACKET) && (usOpCode == pPacket->uPacket.CommandPacket.opCode)) {
			SVSUTIL_ASSERT (pPacket->uPacket.CommandPacket.m.fMarker == BTH_MARKER_CONNECTION);
			if (pPacket->uPacket.CommandPacket.m.connection_handle == connection_handle) {
				if (pParent)
					pParent->pNext = pPacket->pNext;
				else {
					SVSUTIL_ASSERT (pPacket == *pList);
					*pList = (*pList)->pNext;
				}
				return pPacket;
			}
		}

		pParent = pPacket;
		pPacket = pPacket->pNext;
	}

	return NULL;
}

static HCIPacket *FindCommandPacket (HCIPacket *pList, unsigned short usOpCode, BD_ADDR *pba) {
	HCIPacket *pPacket = pList;
	HCIPacket *pParent = NULL;
	while (pPacket) {
		if (pPacket->ePacketType == COMMAND_PACKET) {
			SVSUTIL_ASSERT (pPacket->pContents->cSize >= 3);
			SVSUTIL_ASSERT (pPacket->pContents->cStart == 0);
			SVSUTIL_ASSERT (pPacket->pContents->cEnd == pPacket->pContents->cSize);
			SVSUTIL_ASSERT (pPacket->pContents->pBuffer[2] + 3 == BufferTotal (pPacket->pContents));
		}

		if ((pPacket->ePacketType == COMMAND_PACKET) && (usOpCode == pPacket->uPacket.CommandPacket.opCode)) {
			SVSUTIL_ASSERT (pPacket->uPacket.CommandPacket.m.fMarker == BTH_MARKER_ADDRESS);
			if (pPacket->uPacket.CommandPacket.m.ba == *pba)
				return pPacket;
		}

		pParent = pPacket;
		pPacket = pPacket->pNext;
	}

	return NULL;
}

static HCIPacket *ExtractCommandPacket (HCIPacket **pList, unsigned short usOpCode, BD_ADDR *pba) {
	HCIPacket *pPacket = *pList;
	HCIPacket *pParent = NULL;
	while (pPacket) {
		if (pPacket->ePacketType == COMMAND_PACKET) {
			SVSUTIL_ASSERT (pPacket->pContents->cSize >= 3);
			SVSUTIL_ASSERT (pPacket->pContents->cStart == 0);
			SVSUTIL_ASSERT (pPacket->pContents->cEnd == pPacket->pContents->cSize);
			SVSUTIL_ASSERT (pPacket->pContents->pBuffer[2] + 3 == BufferTotal (pPacket->pContents));
		}

		if ((pPacket->ePacketType == COMMAND_PACKET) && (usOpCode == pPacket->uPacket.CommandPacket.opCode)) {
			SVSUTIL_ASSERT (pPacket->uPacket.CommandPacket.m.fMarker == BTH_MARKER_ADDRESS);
			if (pPacket->uPacket.CommandPacket.m.ba == *pba) {
				if (pParent)
					pParent->pNext = pPacket->pNext;
				else {
					SVSUTIL_ASSERT (pPacket == *pList);
					*pList = (*pList)->pNext;
				}
				return pPacket;
			}
		}

		pParent = pPacket;
		pPacket = pPacket->pNext;
	}

	return NULL;
}

static BasebandConnection *FindConnection (unsigned short h) {
	BasebandConnection *pC = gpHCI->pConnections;

	while (pC && pC->connection_handle != h)
		pC = pC->pNext;

	return pC;
}

static BasebandConnection *FindConnection (BD_ADDR *pba) {
	BasebandConnection *pC = gpHCI->pConnections;

	while (pC && pC->ba != *pba)
		pC = pC->pNext;

	return pC;
}

static HCI_CONTEXT *VerifyContext (HCI_CONTEXT *pOwner) {
	HCI_CONTEXT *pRunner = gpHCI->pContexts;
	while (pRunner && (pRunner != pOwner))
		pRunner = pRunner->pNext;

	return pRunner;
}

//
//	Retire packet
//
static int RetireCall (HCIPacket *pPacket, HCI_CONTEXT *pDeviceContext, void *pCallContext, int iError) {
	SVSUTIL_ASSERT (gpHCI && gpHCI->IsLocked ());

	IFDBG(DebugOut (DEBUG_HCI_PACKETS, L"RetireCall:: [call %08x device %08x] packet %08x\n", pCallContext, pDeviceContext, pPacket));

#if defined (DEBUG) || defined (_DEBUG)
	if (pPacket) {
		HCIPacket *pRunner = gpHCI->pPackets;
		while (pRunner) {
			SVSUTIL_ASSERT (pRunner != pPacket);
			pRunner = pRunner->pNext;
		}

		pRunner = gpHCI->pPacketsSent;

⌨️ 快捷键说明

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