📄 hci_bcsp.cpp
字号:
{
result = BCSP_STATUS_CONNECTED;
}
else
{
result = BCSP_STATUS_SYNC;
}
}
else
{
result = BCSP_STATUS_DISCONNECTED;
}
return result;
}
#ifdef STATISTICS
BOOL BcspCommunication::GetStatistics(BcspStatisticsT* bcspStatistics)
{
BOOL result = FALSE;
EnterCriticalSection(&lock);
bcspStatistics->headerCrcErrors = headerCrcErrors;
bcspStatistics->inBytes = inBytes;
bcspStatistics->inPackets = inPackets;
bcspStatistics->markerErrors = markerErrors;
bcspStatistics->outBytes = outBytes;
bcspStatistics->outPackets = outPackets;
bcspStatistics->overflowErrors = overflowErrors;
bcspStatistics->packetCrcErrors = packetCrcErrors;
bcspStatistics->packetSizeErrors = packetSizeErrors;
bcspStatistics->retransmissions = retransmissions;
bcspStatistics->retransmissionsTimeout = retransmissionsTimeout;
bcspStatistics->syncErrors = syncErrors;
bcspStatistics->receiveReady = receiveReady;
bcspStatistics->receiveTotal = receiveTotal;
result = TRUE;
LeaveCriticalSection(&lock);
return result;
}
#endif
void BcspCommunication::LinkLost()
{
EnterCriticalSection(&lock);
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::LinkLost@%s> LINK LOST"), name));
shuttingDown = TRUE;
SetEvent(writePacketEvent);
SetEvent(packetAvailable);
SetEvent(bccmdEvent);
SetEvent(terminateEvent);
LeaveCriticalSection(&lock);
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::LinkLost@%s> LINK LOST COMPLETE"), name));
}
DWORD BcspCommunication::OpenConnection(const TCHAR* portName, DWORD baudrate, DWORD maxACLBufferSize, DWORD priority, BOOL waitForSync, BOOL useSafeTimeouts)
{
COMMTIMEOUTS commTimeOuts;
DCB dcb;
DWORD result = ERROR_SUCCESS;
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::OpenConnection@%s> PORT: %s, BAUD: %u, ACL: %u, SERIALTIMEOUTCONSTANT: %u, SERIALINTERVALTIMEOUT: %u"), name, portName, baudrate, maxACLBufferSize, serialTimeoutConstant, serialIntervalTimeout));
if (serialPortHandle != INVALID_HANDLE_VALUE)
{
return ERROR_SUCCESS;
}
state = BCSP_STATE_SYNC;
sendSyncResp = FALSE;
sendConfResp = FALSE;
serialPortError = FALSE;
sendTransmitAck = FALSE;
serialPortError = FALSE;
shuttingDown = TRUE;
receivePosition = 0;
receiveInsertPosition = 0;
receiveSequence = 0;
receivePositionAcknowledge = 0;
transmitPosition = 0;
transmitPositionUnacknowledged = 0;
transmitInsertPosition = 0;
transmitWindow = 4;
transmitTimeout = (24000 * maxACLBufferSize * transmitWindow) / baudrate; // 8 bit * 1.5 (slip overhead) * 2 (room for transmit) * 1000 ms = 24000
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::OpenConnection@%s> TIMEOUT: %u"), name, transmitTimeout));
shuttingDown = FALSE;
#ifndef UNDER_CE
serialPortHandle = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0);
#else
serialPortHandle = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
#endif
if (serialPortHandle == INVALID_HANDLE_VALUE)
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO OPEN PORT"), name));
return GetLastError();
}
if (!SetupComm (serialPortHandle, serialBufferSize, serialBufferSize))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO SET BUFFERS"), name));
return GetLastError();
}
if (!GetCommState(serialPortHandle, &dcb))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO GET STATE"), name));
return GetLastError();
}
dcb.BaudRate = baudrate;
dcb.fBinary = TRUE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fNull = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE;
dcb.ByteSize = 8;
dcb.fParity = TRUE;
dcb.Parity = EVENPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.ErrorChar = (char) 0xC0;
if (!SetCommState(serialPortHandle, &dcb))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO SET STATE"), name));
return GetLastError();
}
if (useSafeTimeouts)
{
commTimeOuts.ReadIntervalTimeout = 1;
commTimeOuts.ReadTotalTimeoutMultiplier = 0;
commTimeOuts.ReadTotalTimeoutConstant = 1000;
commTimeOuts.WriteTotalTimeoutMultiplier = 0;
commTimeOuts.WriteTotalTimeoutConstant = 1000;
}
else
{
commTimeOuts.ReadIntervalTimeout = serialIntervalTimeout;
commTimeOuts.ReadTotalTimeoutMultiplier = 0;
commTimeOuts.ReadTotalTimeoutConstant = serialTimeoutConstant;
commTimeOuts.WriteTotalTimeoutMultiplier = 0;
commTimeOuts.WriteTotalTimeoutConstant = serialTimeoutConstant;
}
if (!SetCommTimeouts (serialPortHandle, &commTimeOuts))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::OpenConnection@%s> UNABLE TO SET TIMEOUTS"), name));
return GetLastError();
}
serialPortError = FALSE;
writePacketEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
packetAvailable = CreateEvent(NULL, FALSE, FALSE, NULL);
inSyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
bccmdEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
terminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
transmitHandle = CreateSemaphore(NULL, 8, 8, NULL);
writeThread = CreateThread(NULL, 0, BCSPWriteThreadExecute, this, 0, 0);
Sleep(65);
readThread = CreateThread(NULL, 0, BCSPReadThreadExecute, this, 0, 0);
Sleep(65);
CeSetThreadPriority(writeThread, priority);
CeSetThreadPriority(readThread, priority);
if (waitForSync)
{
result = WaitForSingleObject(inSyncEvent, INFINITE) == WAIT_OBJECT_0 ? ERROR_SUCCESS : ERROR_OPEN_FAILED;
}
return result;
}
DWORD BcspCommunication::ReadExecute()
{
DWORD commEvent;
DWORD bytesRead;
DWORD index;
BOOL inSync = FALSE;
BOOL inMarker = FALSE;
DWORD inPacketSize = 0;
unsigned char buffer[4096];
unsigned char inBuffer[4096];
PurgeComm(serialPortHandle, PURGE_RXCLEAR);
if (!SetCommMask(serialPortHandle, EV_RXCHAR))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> SetCommMask returned: %u"), name, GetLastError()));
serialPortError = TRUE;
return ERROR_SUCCESS;
}
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::ReadExecute@%s> STARTING READING THREAD"), name));
__try
{
while (!shuttingDown && !serialPortError)
{
if (!WaitCommEvent(serialPortHandle, &commEvent, NULL))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> WaitCommEvent returned: %u"), name, GetLastError()));
serialPortError = TRUE;
LinkLost();
break;
}
if (!SetCommMask (serialPortHandle, EV_RXCHAR))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> SetCommMask returned: %u"), name, GetLastError()));
serialPortError = TRUE;
LinkLost();
break;
}
if (!(commEvent & EV_RXCHAR))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> CommEvent != EV_RXCHAR"), name));
serialPortError = TRUE;
LinkLost();
break;
}
if (!ReadFile(serialPortHandle, &buffer, sizeof(buffer), &bytesRead, NULL))
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> ReadFile returned: %u"), name, GetLastError()));
serialPortError = TRUE;
LinkLost();
break;
}
IFDBG(DebugOut(DEBUG_BCSP_INIT, TEXT("<BcspCommunication::ReadExecute@%s> READ DATA (SIZE: %u)"), name, bytesRead));
IFSTAT(inBytes += bytesRead);
if (bytesRead)
{
for (index = 0; index < bytesRead; index++)
{
if (buffer[index] == 0xC0)
{
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::ReadExecute@%s> SYNC FOUND (inPacketSize: %u)"), name, inPacketSize));
if (inPacketSize)
{
IFSTAT(inPackets++);
if (sniffMode == 1)
{
HCIFileWritePacket(1, inBuffer, inPacketSize);
}
DecodeBCSPPacket(inBuffer, inPacketSize);
inSync = 0;
}
else
{
inSync = 1;
}
inMarker = FALSE;
inPacketSize = 0;
}
else if (buffer[index] == 0xDB)
{
inMarker = TRUE;
}
else
{
if (inSync)
{
if (inMarker)
{
if (buffer[index] == 0xDC)
{
inBuffer[inPacketSize++] = 0xC0;
}
else if (buffer[index] == 0xDD)
{
inBuffer[inPacketSize++] = 0xDB;
}
else
{
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::ReadExecute@%s> MARKER ERROR"), name));
inSync = FALSE;
IFSTAT(markerErrors++);
}
inMarker = FALSE;
}
else
{
inBuffer[inPacketSize++] = buffer[index];
}
if (inPacketSize == sizeof(inBuffer))
{
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::ReadExecute@%s> SYNC ERROR 1"), name));
inSync = FALSE;
IFSTAT(overflowErrors++);
}
}
else
{
IFSTAT(syncErrors++);
}
}
}
}
IFDBG(DebugOut(DEBUG_BCSP_RUN, TEXT("<BcspCommunication::ReadExecute@%s> SLIP DECODE COMPLETE"), name));
}
}
__except(1)
{
IFDBG(DebugOut(DEBUG_BCSP_ERROR, TEXT("<BcspCommunication::ReadExecute@%s> READ DATA EXCEPTION"), name));
}
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::ReadExecute@%s> TERMINATED (shuttingDown: %u, serialPortError: %u)"), name, shuttingDown, serialPortError));
return ERROR_SUCCESS;
}
DWORD BcspCommunication::ReadPacket(BcspChannelT* channel, unsigned char** buffer, DWORD* size)
{
BOOL found = FALSE;
BcspQueueElementT* bcspQueueElement = NULL;
unsigned char incValue = 0;
if (shuttingDown || serialPortError)
{
IFDBG(DebugOut(DEBUG_BCSP_CTRL, TEXT("<BcspCommunication::ReadPacket@%s> SHUTING DOWN OR SERIAL ERROR"), name));
CloseConnection();
return ERROR_SERVICE_NOT_ACTIVE;
}
EnterCriticalSection(&lock);
while (!shuttingDown && !found)
{
if (incomingSCOData.present)
{
bcspQueueElement = &incomingSCOData;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -