📄 hci.cxx
字号:
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 + -