📄 hcisc.cxx
字号:
return;
}
CloseHandle (hFile);
CloseHandle (hWriteEvent);
CloseHandle (hReadEvent);
hFile = INVALID_HANDLE_VALUE;
hWriteEvent = hReadEvent = NULL;
#if defined (BT_USE_CELOG)
if (g_fCeLog) {
BTH_CELOG_STOP_DATA sd;
GetLocalTime (&sd.st);
CELOGDATAFLAGGED(TRUE, CELID_RAW_UCHAR, &sd, sizeof(sd), 0, CELZONE_ALWAYSON, CELOG_FLAG_STOP);
#if defined (SDK_BUILD)
CELOGSDK_STOP ();
#endif
g_fCeLog = FALSE;
}
#endif
IFDBG(DebugOut (DEBUG_HCI_INIT, L"HCI_CloseConnection - Successful\n"));
return;
}
//
// SLIP coding
//
#define SLIP_END 0xc0
#define SLIP_ESC 0xdb
#define SLIP_ESC_END 0xdc
#define SLIP_ESC_ESC 0xdd
static int GetSLIPEncodedLength(const void *pvData, int len) {
const unsigned char *pData = (unsigned char *)pvData;
int slip_len = len;
for (int i = 0; i < len; ++i) {
if((pData[i] == SLIP_END) || (pData[i] == SLIP_ESC))
slip_len += 1;
}
return slip_len;
}
static void SLIPEncodeIntoBuffer (const void *pvSourceData, int sourceLen, unsigned char *pTargetData) {
const unsigned char *pSourceData = (unsigned char *)pvSourceData;
for(int i = 0; i < sourceLen; ++i) {
unsigned char byte = pSourceData[i];
switch(byte) {
case SLIP_END:
*pTargetData++ = SLIP_ESC;
*pTargetData++ = SLIP_ESC_END;
break;
case SLIP_ESC:
*pTargetData++ = SLIP_ESC;
*pTargetData++ = SLIP_ESC_ESC;
break;
default:
*pTargetData++ = pSourceData[i];
break;
}
}
}
/*
This code has been hacked to add a SLIP wrapper around each call
to WriteCommPort. It is assumed that this function is called
only from the HCI_WritePacket function.
We are doing this so the lower lever of the serial driver
can fined the packet boundry.
This driver should be and should be a packet driver not a stream driver.
Use a monolithic rather than the MDD/PDD model.
*/
BOOL WriteCommPort (unsigned char *pBuffer, unsigned int cSize) {
DWORD dwFilledSoFar = 0;
unsigned char *pSlipPacketData = NULL;
unsigned int slipPacketLength;
slipPacketLength = GetSLIPEncodedLength ((const void *)pBuffer, cSize);
pSlipPacketData = (unsigned char *)malloc (slipPacketLength + 2);
if (pSlipPacketData == NULL)
{
IFDBG(DebugOut (DEBUG_ERROR, L"Failed to allocate temporary SLIP packet buffer.\n"));
return FALSE;
}
pSlipPacketData[0] = 0xC0;
SLIPEncodeIntoBuffer(pBuffer,cSize,&pSlipPacketData[1]);
pSlipPacketData[slipPacketLength+1] = 0xC0;
slipPacketLength += 2;
while ((int)dwFilledSoFar < slipPacketLength) {
DWORD dwWrit = 0;
#if ! defined (UNDER_CE)
OVERLAPPED o;
memset (&o, 0, sizeof(o));
o.hEvent = hWriteEvent;
while (! WriteFile (hFile, &(pSlipPacketData[dwFilledSoFar]), slipPacketLength - dwFilledSoFar, &dwWrit, &o)) {
if ((GetLastError() == ERROR_IO_PENDING) &&
GetOverlappedResult (hFile, &o, C:\WINCE410\PUBLIC\COMMON\OAK\DRIVERS\BLUETOOTH\TRANSPORTS\SC&dwWrit, TRUE))
break;
if (hFile != INVALID_HANDLE_VALUE)
IFDBG(DebugOut (DEBUG_ERROR, L"Error writing COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));
if (pSlipPacketData) free(pSlipPacketData);
return FALSE;
}
#else
if ((! WriteFile (hFile, &(pSlipPacketData[dwFilledSoFar]), slipPacketLength - dwFilledSoFar, &dwWrit, NULL)) &&
(dwWrit == 0)) {
#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
if (hFile != INVALID_HANDLE_VALUE)
IFDBG(DebugOut (DEBUG_ERROR, L"Error writing COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));
#endif
if (pSlipPacketData) free(pSlipPacketData);
return FALSE;
}
#endif
#if defined (BT_USE_CELOG)
if (g_fCeLog && dwWrit) {
CELOGDATAFLAGGED(TRUE, CELID_RAW_UCHAR, &pSlipPacketData[dwFilledSoFar], (unsigned short)dwWrit, 0, CELZONE_ALWAYSON, CELOG_FLAG_RAW_OUT);
}
#endif
dwFilledSoFar += dwWrit;
}
if (pSlipPacketData) free(pSlipPacketData);
return TRUE;
}
BOOL ReadCommPort (unsigned char *pBuffer, DWORD dwLen) {
IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"ReadCommPort attempting to read %d bytes.\n", dwLen));
DWORD dwFilledSoFar = 0;
while (dwFilledSoFar < dwLen) {
OVERLAPPED o;
memset (&o, 0, sizeof(o));
o.hEvent = hReadEvent;
DWORD dwRead = 0;
#if ! defined (UNDER_CE)
while (! ReadFile (hFile, &pBuffer[dwFilledSoFar], dwLen - dwFilledSoFar, &dwRead, &o)) {
if ((GetLastError() == ERROR_IO_PENDING) &&
GetOverlappedResult (hFile, &o, &dwRead, TRUE))
break;
if (hFile != INVALID_HANDLE_VALUE)
IFDBG(DebugOut (DEBUG_ERROR, L"Error reading COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));
return FALSE;
}
#else
if ( (! ReadFile (hFile, &pBuffer[dwFilledSoFar], dwLen - dwFilledSoFar, &dwRead, NULL)) &&
(dwRead == 0)) {
#if defined (DEBUG) || defined (_DEBUG) || defined (RETAILLOG)
if (hFile != INVALID_HANDLE_VALUE)
IFDBG(DebugOut (DEBUG_ERROR, L"Error reading COM port: GetLastError = 0x%08x (%d)\n", GetLastError (), GetLastError ()));
#endif
return FALSE;
}
#endif
//#if defined (DEBUG) || defined (_DEBUG)
// IFDBG(DebugOut(DEBUG_HCI_TRANSPORT, L"ReadFile in ReadCommPort read %d bytes. Filled so far=%d\n", dwRead, dwFilledSoFar));
// DumpBuff (DEBUG_HCI_DUMP, &pBuffer[dwFilledSoFar], dwRead);
//#endif
#if defined (BT_USE_CELOG)
if (g_fCeLog && dwRead) {
CELOGDATAFLAGGED(TRUE, CELID_RAW_UCHAR, pBuffer + dwFilledSoFar, (unsigned short)dwRead, 0, CELZONE_ALWAYSON, CELOG_FLAG_RAW_IN);
}
#endif
dwFilledSoFar += dwRead;
}
return TRUE;
}
int HCI_WritePacket (HCI_TYPE eType, BD_BUFFER *pBuff) {
IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"HCI_WritePacket type 0x%02x len %d\n", eType, BufferTotal (pBuff)));
IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, BufferTotal (pBuff)));
if (((int)BufferTotal (pBuff) > PACKET_SIZE_W) || (pBuff->cStart < 4) || (pBuff->cEnd > pBuff->cSize - 1)) {
IFDBG(DebugOut (DEBUG_ERROR, L"[UART] Packet too big (%d, should be <= %d), or no space for header!\n", BufferTotal (pBuff), PACKET_SIZE_W));
return FALSE;
}
if (hFile == INVALID_HANDLE_VALUE) {
IFDBG(DebugOut (DEBUG_ERROR, L"HCI_WritePacket - not active\n"));
return FALSE;
}
int iUserSize = BufferTotal (pBuff);
pBuff->cStart -= 4;
switch (eType) {
case COMMAND_PACKET:
pBuff->pBuffer[pBuff->cStart] = 0x81;
break;
case DATA_PACKET_ACL:
pBuff->pBuffer[pBuff->cStart] = 0x82;
break;
case DATA_PACKET_SCO:
pBuff->pBuffer[pBuff->cStart] = 0x83;
break;
default:
IFDBG(DebugOut (DEBUG_ERROR, L"[UART - NOKIA] WritePacket :: Invalid code!\n"));
return FALSE;
}
pBuff->pBuffer[pBuff->cStart + 1] = 0;
pBuff->pBuffer[pBuff->cStart + 2] = iUserSize & 0xff;
pBuff->pBuffer[pBuff->cStart + 3] = (iUserSize >> 8) & 0xff;
if (BufferTotal (pBuff) & 1)
pBuff->pBuffer[pBuff->cEnd++] = 0;
if (! WriteCommPort (pBuff->pBuffer, BufferTotal (pBuff)))
return FALSE;
IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"HCI_WritePacket : DONE type 0x%02x len %d\n", eType, BufferTotal (pBuff)));
return TRUE;
}
int HCI_ReadPacket (HCI_TYPE *peType, BD_BUFFER *pBuff) {
IFDBG(DebugOut (DEBUG_HCI_TRANSPORT, L"HCI_ReadPacket\n"));
if (hFile == INVALID_HANDLE_VALUE) {
IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - not active\n"));
return FALSE;
}
pBuff->cEnd = pBuff->cSize;
pBuff->cStart = 0;
if (BufferTotal (pBuff) < 257 + 4) {
IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - failed buffer too small (%d bytes)\n", BufferTotal (pBuff)));
return FALSE;
}
for (;;) {
if (! ReadCommPort (pBuff->pBuffer, 4))
return FALSE;
int iRealBytes = pBuff->pBuffer[2] | (pBuff->pBuffer[3] << 8);
pBuff->cStart = 4;
pBuff->cEnd = pBuff->cStart + iRealBytes;
if (iRealBytes & 0x1)
pBuff->cEnd++; // Zero fill...
if (pBuff->cEnd > pBuff->cSize) {
IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - failed: buffer too small (%d bytes wanted!)\n", BufferTotal (pBuff)));
return FALSE;
}
if (! ReadCommPort (pBuff->pBuffer + pBuff->cStart, BufferTotal (pBuff)))
return FALSE;
pBuff->cEnd = pBuff->cStart + iRealBytes; // Remove trailing 0
switch (pBuff->pBuffer[0]) {
case 0x81: // Command packet
IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - unexpected packet type (command)\n"));
IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, iRealBytes));
return FALSE;
case 0x82: // ACL packet
*peType = DATA_PACKET_ACL;
IFDBG(DebugOut (DEBUG_HCI_DUMP, L"HCI_ReadPacket: ACL\n"));
break;
case 0x83: // SCO packet
*peType = DATA_PACKET_SCO;
IFDBG(DebugOut (DEBUG_HCI_DUMP, L"HCI_ReadPacket: SCO\n"));
break;
case 0x84: // HCI Event
*peType = EVENT_PACKET;
IFDBG(DebugOut (DEBUG_HCI_DUMP, L"HCI_ReadPacket: Event\n"));
break;
case 0x80: // TLP_Control
IFDBG(DebugOut (DEBUG_HCI_DUMP, L"HCI_ReadPacket: TLP_Control (ignoring)\n"));
IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, iRealBytes));
continue;
}
IFDBG(DumpBuff (DEBUG_HCI_DUMP, pBuff->pBuffer + pBuff->cStart, iRealBytes));
return TRUE;
}
IFDBG(DebugOut (DEBUG_ERROR, L"HCI_ReadPacket - unknown packet type\n"));
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -