📄 hci_bcsp.cpp
字号:
sniffCrc = ((sniffCrc & 0x3333) << 2) | ((sniffCrc & 0xcccc) >> 2);
sniffCrc = ((sniffCrc & 0x5555) << 1) | ((sniffCrc & 0xaaaa) >> 1);
tempBufferSniff[index++] = (sniffCrc >> 8) & 0xFF;
tempBufferSniff[index++] = sniffCrc & 0xFF;
}
HCIFileWritePacket(0, tempBufferSniff, totalLength);
LocalFree(tempBufferSniff);
}
}
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WriteExecute@%s> State: %u"), name, state));
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WriteExecute@%s> PACKET OUT (TIME: %u, TYPE: %u, CHL: %u, SEQ: %u, ACK: %u, SIZE: %u, WINDOW: %u, TIP: %u, TP: %u, IN QUEUE: %u)"),
name, GetTickCount(), bcspHeader->protocolType, bcspHeader->protocolID, bcspHeader->seq, bcspHeader->ack,
bcspHeader->payloadLength, transmitWindow, transmitInsertPosition, transmitPosition,
(8 + transmitInsertPosition - transmitPosition) & 0x07));
outBuffer[outPacketSize++] = 0xC0;
for (index = 0; index < totalLength; index++)
{
unsigned char c;
#ifdef BCSP_TEST_MODE
if (enableTestMode)
{
if (rand() < properbility.packetSizeErrorProperbility)
{
break;
}
}
#endif
if (index < 4)
{
c = bchsPacket[index];
if (useCrc)
{
crc = (crc >> 8) ^ crc_table[(crc & 255) ^ c];
}
}
else if (index < (4 + (DWORD) bcspHeader->payloadLength))
{
c = bchsPayload[index - 4];
if (useCrc)
{
crc = (crc >> 8) ^ crc_table[(crc & 255) ^ c];
}
}
else if (index == (4 + (DWORD) bcspHeader->payloadLength))
{
crc = ((crc & 0x00ff) << 8) | (crc >> 8);
crc = ((crc & 0x0f0f) << 4) | ((crc & 0xf0f0) >> 4);
crc = ((crc & 0x3333) << 2) | ((crc & 0xcccc) >> 2);
crc = ((crc & 0x5555) << 1) | ((crc & 0xaaaa) >> 1);
c = (crc >> 8) & 0xFF;
}
else
{
c = crc & 0xFF;
#ifdef BCSP_TEST_MODE
if (enableTestMode)
{
if (rand() < properbility.packetCrcErrorProperbility)
{
c += 10;
}
}
#endif
}
#ifdef BCSP_TEST_MODE
if (enableTestMode)
{
int r;
if (c == 0xC0)
{
if ((r = rand()) < properbility.markerErrorProperbility)
{
if (rand() < (RAND_MAX >> 1))
{
outBuffer[outPacketSize++] = 0xDA;
outBuffer[outPacketSize++] = 0xDC;
}
else
{
outBuffer[outPacketSize++] = 0xDB;
outBuffer[outPacketSize++] = 0xDF;
}
}
else
{
outBuffer[outPacketSize++] = 0xDB;
outBuffer[outPacketSize++] = 0xDC;
}
}
else if (c == 0xDB)
{
if ((r = rand()) < properbility.markerErrorProperbility)
{
if (rand() < (RAND_MAX >> 1))
{
outBuffer[outPacketSize++] = 0xDA;
outBuffer[outPacketSize++] = 0xDD;
}
else
{
outBuffer[outPacketSize++] = 0xDB;
outBuffer[outPacketSize++] = 0xDF;
}
}
else
{
outBuffer[outPacketSize++] = 0xDB;
outBuffer[outPacketSize++] = 0xDD;
}
}
else
{
outBuffer[outPacketSize++] = c;
}
}
else
#endif
if (c == 0xC0)
{
outBuffer[outPacketSize++] = 0xDB;
outBuffer[outPacketSize++] = 0xDC;
}
else if (c == 0xDB)
{
outBuffer[outPacketSize++] = 0xDB;
outBuffer[outPacketSize++] = 0xDD;
}
else
{
outBuffer[outPacketSize++] = c;
}
}
outBuffer[outPacketSize++] = 0xC0;
LeaveCriticalSection(&lock);
while (totalWritten < outPacketSize)
{
written = 0;
#ifndef UNDER_CE
if (!WriteFile(serialPortHandle, &outBuffer[totalWritten], outPacketSize - totalWritten, &written, &overlapped))
{
if (GetLastError() != ERROR_IO_PENDING || !GetOverlappedResult(serialPortHandle, &overlapped, &written, TRUE))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::WriteExecute@%s> GetOverlappedResult returned: %u"), name, GetLastError()));
serialPortError = TRUE;
break;
}
}
#else
if (!WriteFile(serialPortHandle, &outBuffer[totalWritten], outPacketSize - totalWritten, &written, 0))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::WriteExecute@%s> WriteFile returned: %u"), name, GetLastError()));
serialPortError = TRUE;
break;
}
#endif
totalWritten += written;
}
EnterCriticalSection(&lock);
if (totalWritten < outPacketSize || serialPortError)
{
serialPortError = TRUE;
LinkLost();
break;
}
IFSTAT(outBytes += totalWritten);
IFSTAT(outPackets++);
}
if (state == BCSP_STATE_RUNNING && transmitPositionUnacknowledged != transmitPosition)
{
DWORD currentTime = GetTickCount();
if ((currentTime - transmitQueue[transmitPositionUnacknowledged].transmittedTime) < transmitTimeout)
{
currentTimeout = (transmitTimeout + transmitQueue[transmitPositionUnacknowledged].transmittedTime - currentTime);
}
else
{
currentTimeout = 0;
}
}
else
{
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WriteExecute@%s> STOPPED???"), name));
}
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WriteExecute@%s> PACKET SEND INFO (TransmitWindow: %u, CurrentTimeout: %u, Packet Sent: %s)"), name, transmitWindow, currentTimeout, bcspHeader ? TEXT("true") : TEXT("false")));
LeaveCriticalSection(&lock);
result = WaitForSingleObject(writePacketEvent, currentTimeout);
EnterCriticalSection(&lock);
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WriteExecute@%s> WAIT RETURNED"), name));
if (transmitWindow > 4)
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::WriteExecute@%s> TRANSMITWINDOW: %u"), name, transmitWindow));
}
if (result == WAIT_TIMEOUT)
{
if (transmitWindow < 4)
{
unsigned int index;
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WriteExecute@%s> RETRY (TransmitWindow: %u, TransmitPosition: %u, TransmitPositionUnacknowledged: %u)"), name, transmitWindow, transmitPosition, transmitPositionUnacknowledged));
for (index = 0; index < 8; index++)
{
if (transmitQueue[index].sent)
{
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WriteExecute@%s> %u MARKED SENT"), name, index));
IFSTAT(retransmissionsTimeout++);
}
transmitQueue[index].sent = FALSE;
}
transmitWindow = 4;
transmitPosition = transmitPositionUnacknowledged;
if (++transmitQueue[transmitPosition].retries == 20)
{
LinkLost();
}
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WriteExecute@%s> RETRY COMPLETE (TransmitWindow: %u, TransmitPosition: %u, TransmitPositionUnacknowledged: %u)"), name, transmitWindow, transmitPosition, transmitPositionUnacknowledged));
}
}
else if (result != WAIT_OBJECT_0)
{
serialPortError = TRUE;
LinkLost();
break;
}
}
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::WriteExecute@%s> TERMINATED"), name));
LeaveCriticalSection(&lock);
return serialPortError ? ERROR_INVALID_PARAMETER : ERROR_SUCCESS;
}
DWORD BcspCommunication::WritePacket(BcspChannelT channel, unsigned char* buffer, DWORD size)
{
DWORD result = ERROR_NOT_ENOUGH_MEMORY;
if (shuttingDown || serialPortError)
{
CloseConnection();
return ERROR_SERVICE_NOT_ACTIVE;
}
if (channel == BCSP_CHANNEL_SCO)
{
EnterCriticalSection(&lock);
free(outgoingSCOData.buffer);
outgoingSCOData.buffer = malloc(size);
if (outgoingSCOData.buffer)
{
outgoingSCOData.present = TRUE;
outgoingSCOData.size = (unsigned short) size;
memcpy(outgoingSCOData.buffer, buffer, size);
SetEvent(writePacketEvent);
result = ERROR_SUCCESS;
}
}
else
{
HANDLE handles[] = { transmitHandle, terminateEvent };
if (sniffMode == 2)
{
if (channel == BCSP_CHANNEL_HCI)
{
HCIFileWritePacket(2, buffer, size);
}
else if (channel == BCSP_CHANNEL_ACL)
{
HCIFileWritePacket(0, buffer, size);
}
}
switch (WaitForMultipleObjects(2, handles, FALSE, INFINITE))
{
case WAIT_OBJECT_0 + 0:
{
break;
}
case WAIT_OBJECT_0 + 1:
{
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::WritePacket@%s> SHUTTING DOWN"), name));
return ERROR_SERVICE_NOT_ACTIVE;
}
default:
{
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::WritePacket@%s> UNKNOWN ERROR"), name));
return GetLastError();
}
}
if (shuttingDown || serialPortError)
{
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::WritePacket@%s> SHUTTING DOWN"), name));
return ERROR_SERVICE_NOT_ACTIVE;
}
EnterCriticalSection(&lock);
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::WritePacket@%s> PACKET WRITE INFO (WritePossible: %u, TransmitInsertPosition: %u, Present: %u)"), name, writePossible, transmitInsertPosition, transmitQueue[transmitInsertPosition].present));
if (!writePossible)
{
writePossible = TRUE;
result = ERROR_SERVICE_DISABLED;
}
else if (!transmitQueue[transmitInsertPosition].present)
{
ZeroMemory(&transmitQueue[transmitInsertPosition], sizeof(BcspQueueElementT));
transmitQueue[transmitInsertPosition].buffer = malloc(size);
if (transmitQueue[transmitInsertPosition].buffer)
{
transmitQueue[transmitInsertPosition].present = TRUE;
transmitQueue[transmitInsertPosition].sent = FALSE;
transmitQueue[transmitInsertPosition].channel = channel;
transmitQueue[transmitInsertPosition].size = (unsigned short) size;
memcpy(transmitQueue[transmitInsertPosition].buffer, buffer, size);
SetEvent(writePacketEvent);
transmitInsertPosition = (++transmitInsertPosition) & 0x07;
result = ERROR_SUCCESS;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -