📄 hciuart.cxx
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Bluetooth HCI UART interface
//
//
// Module Name:
//
// hciuart.cxx
//
// Abstract:
//
// This file implements Bluetooth HCI UART interface
//
//
//------------------------------------------------------------------------------
#define BT_USE_CELOG 1
#include <windows.h>
#if ! defined (UNDER_CE)
#include <assert.h>
#define ASSERT assert
#endif
#include <bt_buffer.h>
#include <bt_hcip.h>
#include <bt_os.h>
#include <bt_debug.h>
#include <bt_tdbg.h>
#if defined (SDK_BUILD) && defined (BT_USE_CELOG)
#define CELOGSDK_FILELOG L"uart"
#define CELOGSDK_DEFINE 1
#include "../../../../../../../private/osinternal/pbtools/privdbg/celog_sdk.h"
#endif
static HANDLE hFile = INVALID_HANDLE_VALUE;
static HANDLE hWriteEvent = NULL;
static HANDLE hReadEvent = NULL;
static HCI_TransportCallback gCallback = NULL;
#define PACKET_SIZE_R (64 * 1024 + 128)
#define PACKET_SIZE_W (255 + 3)
#define DEFAULT_COM_NAME L"COM1:"
#define DEBUG_READ_BUFFER_HEADER 4
#define DEBUG_WRITE_BUFFER_HEADER 8
#define DEBUG_READ_BUFFER_TRAILER 1
#define DEBUG_WRITE_BUFFER_TRAILER 3
DECLARE_DEBUG_VARS();
#if defined (BT_USE_CELOG)
static int g_fCeLog = FALSE;
#endif
int HCI_ReadHciParameters (HCI_PARAMETERS *pParms) {
if (pParms->uiSize < sizeof (*pParms))
return FALSE;
memset (pParms, 0, sizeof(*pParms));
pParms->uiSize = sizeof(*pParms);
pParms->fInterfaceVersion = HCI_INTERFACE_VERSION_1_1;
pParms->iMaxSizeRead = PACKET_SIZE_R;
pParms->iMaxSizeWrite = PACKET_SIZE_W;
pParms->iWriteBufferHeader = 4;
pParms->iReadBufferHeader = 4;
pParms->fHardwareVersion = HCI_HARDWARE_VERSION_V_1_0_B;
pParms->uiWriteTimeout = HCI_DEFAULT_WRITE_TIMEOUT;
pParms->uiDriftFactor = HCI_DEFAULT_DRIFT;
pParms->uiFlags = 0;
HKEY hk;
if (RegOpenKeyEx (HKEY_BASE, L"Software\\Microsoft\\Bluetooth\\hci", 0, KEY_READ, &hk) == ERROR_SUCCESS) {
DWORD dwType = 0;
DWORD dwData = 0;
DWORD dwSize = sizeof(dwData);
if ((RegQueryValueEx (hk, L"ResetDelay", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
pParms->uiResetDelay = dwData;
dwData = 0;
dwSize = sizeof(dwData);
if ((RegQueryValueEx (hk, L"SpecV10a", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
pParms->fHardwareVersion = HCI_HARDWARE_VERSION_V_1_0_A;
dwData = 0;
dwSize = sizeof(dwData);
if ((RegQueryValueEx (hk, L"SpecV11", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
pParms->fHardwareVersion = HCI_HARDWARE_VERSION_V_1_1;
dwData = 0;
dwSize = sizeof(dwData);
if ((RegQueryValueEx (hk, L"WriteTimeout", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
pParms->uiWriteTimeout = dwData;
dwData = 0;
dwSize = sizeof(dwData);
if ((RegQueryValueEx (hk, L"Flags", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
pParms->uiFlags = dwData;
dwData = 0;
dwSize = sizeof(dwData);
if ((RegQueryValueEx (hk, L"Drift", NULL, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dwData)) && dwData)
pParms->uiDriftFactor = dwData;
RegCloseKey (hk);
}
#if defined (DEBUG) || defined (_DEBUG)
pParms->iReadBufferHeader = DEBUG_READ_BUFFER_HEADER;
pParms->iReadBufferTrailer = DEBUG_READ_BUFFER_TRAILER;
pParms->iWriteBufferHeader = DEBUG_WRITE_BUFFER_HEADER;
pParms->iWriteBufferTrailer = DEBUG_WRITE_BUFFER_TRAILER;
#endif
return TRUE;
}
int HCI_StartHardware (void) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"+HCI_StartHardware\n"));
if (hFile != INVALID_HANDLE_VALUE) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"-HCI_StartHardware (already started)\n"));
return TRUE;
}
if (! gCallback) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"-HCI_StartHardware (not registered)\n"));
return FALSE;
}
return ERROR_SUCCESS == gCallback (DEVICE_UP, NULL);
}
int HCI_StopHardware (void) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"+HCI_StopHardware\n"));
if (hFile == INVALID_HANDLE_VALUE) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"-HCI_StopHardware (already stopped)\n"));
return TRUE;
}
if (! gCallback) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"-HCI_StopHardware (not registered)\n"));
return FALSE;
}
return ERROR_SUCCESS == gCallback (DEVICE_DOWN, NULL);
}
int HCI_SetCallback (HCI_TransportCallback pfCallback) {
gCallback = pfCallback;
if (gCallback)
DebugInit();
else
DebugDeInit();
return ERROR_SUCCESS;
}
int HCI_OpenConnection (void) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"HCI_OpenConnection - Started\n"));
if (hFile != INVALID_HANDLE_VALUE)
return FALSE;
WCHAR szComPortName[_MAX_PATH];
wcscpy (szComPortName, DEFAULT_COM_NAME);
DWORD dwBaud = 115200;
HKEY hk;
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_BASE, L"software\\microsoft\\bluetooth\\hci", 0, KEY_READ, &hk)) {
DWORD dwType;
DWORD dwSize = sizeof(szComPortName);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"Name", NULL, &dwType, (LPBYTE)szComPortName, &dwSize)) &&
(dwType == REG_SZ) && (dwSize > 0) && (dwSize < _MAX_PATH))
;
else
wcscpy (szComPortName, DEFAULT_COM_NAME);
dwSize = sizeof(dwBaud);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"baud", NULL, &dwType, (LPBYTE)&dwBaud, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dwBaud)))
;
else
dwBaud = 115200;
RegCloseKey (hk);
}
IFDBG(DebugOut (DEBUG_HCI_INIT, L"Opening port %s (rate %d) for I/O with unit\n", szComPortName, dwBaud));
hFile = CreateFile(szComPortName,
GENERIC_READ | GENERIC_WRITE,
0, // comm devices must be opened w/exclusive-access
NULL, // no security attrs
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
#if ! defined (UNDER_CE)
FILE_FLAG_OVERLAPPED |
#endif
FILE_ATTRIBUTE_NORMAL, // overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (hFile == INVALID_HANDLE_VALUE) {
IFDBG(DebugOut (DEBUG_ERROR, L"Failed CreateFile in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
return FALSE;
}
if (! SetupComm (hFile, 20000, 20000)) {
IFDBG(DebugOut (DEBUG_ERROR, L"Failed SetupComm in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
CloseHandle (hFile);
hFile = INVALID_HANDLE_VALUE;
return FALSE;
}
// purge any information in the buffer
if ( ! PurgeComm (hFile, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR )) {
IFDBG(DebugOut (DEBUG_ERROR, L"Failed PurgeComm in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
CloseHandle (hFile);
hFile = INVALID_HANDLE_VALUE;
return FALSE;
}
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
CommTimeOuts.WriteTotalTimeoutConstant = 1000 ;
if (! SetCommTimeouts (hFile, &CommTimeOuts)) {
IFDBG(DebugOut (DEBUG_ERROR, L"Failed SetCommTimeouts in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
CloseHandle (hFile);
hFile = INVALID_HANDLE_VALUE;
return FALSE;
}
DCB dcb;
dcb.DCBlength = sizeof(dcb);
dcb.BaudRate = dwBaud;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
dcb.fOutxCtsFlow = TRUE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDsrSensitivity = FALSE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fAbortOnError = TRUE;
// dcb.wReserved = 0;
dcb.ByteSize =8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.XonChar = 0x11;
dcb.XoffChar = 0x13;
dcb.XonLim = 3000 ;
dcb.XoffLim = 9000 ;
if (! SetCommState(hFile, &dcb)) {
IFDBG(DebugOut (DEBUG_ERROR, L"Failed SetCommState in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
CloseHandle (hFile);
hFile = INVALID_HANDLE_VALUE;
return FALSE;
}
hWriteEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
hReadEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
#if defined (BT_USE_CELOG)
if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_BASE, L"software\\microsoft\\bluetooth\\debug", 0, KEY_READ, &hk)) {
DWORD dwType;
DWORD dw;
DWORD dwSize = sizeof(dw);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"celog", NULL, &dwType, (LPBYTE)&dw, &dwSize)) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -