?? bthamb.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:
//
// bthamb.cxx
//
// Abstract:
//
// This file implements Bluetooth HCI UART interface
//
//
//------------------------------------------------------------------------------
#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>
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"COM2:"
#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();
// AmbiCom specific code for Ericsson module
#if 1
unsigned char HCC_RESET[] = {01, 03, 0x0c, 00};
#define EricssonBaudRatePos 4
unsigned char HCC_ERICSSON_SET_BAUD_RATE[] = {0x01, 0x09, 0xfc, 0x01, 0x02};
unsigned char HCC_READ_BT_ADDR[] = {0x01, 0x09, 0x01, 0x00};
static BOOL WriteCommPort (unsigned char *pBuffer, unsigned int cSize);
BOOL SendHCC(HANDLE commPort, unsigned char* pHCC, DWORD size)
{
DWORD nWritten = 0;
if(WriteFile(commPort, pHCC, size, &nWritten, 0))
return TRUE;
IFDBG(DebugOut (DEBUG_ERROR, L"BthAmb:SendHCC-WriteFile Fail. GetLastError = 0x%08x\n", GetLastError ()));
return FALSE;
}
#define HEAD_LEN 7
BOOL ReadHCE(HANDLE commPort)
{
DWORD nRead = 0;
unsigned char received[10];
ZeroMemory(received, sizeof(received));
if(ReadFile(commPort, received, HEAD_LEN, &nRead, 0) && nRead)
{
return TRUE;
}
IFDBG(DebugOut (DEBUG_ERROR, L"BthAmb:ReadHCE-ReadFile Fail. GetLastError = 0x%08x\n", GetLastError ()));
return FALSE;
}
BOOL UART_SetBaudRate(HANDLE commPort, DWORD dwBaudRate)
{
DWORD dwWinSDKBaudRate;
DCB dcb;
Sleep(1000);
ZeroMemory(&dcb, sizeof(dcb));
if(!GetCommState(commPort, &dcb))
{
IFDBG(DebugOut (DEBUG_ERROR, L"BthAmb:UART_SetBaudRate-GetCommState Fail. GetLastError = 0x%08x\n", GetLastError ()));
}
if(SendHCC(commPort, HCC_RESET, sizeof(HCC_RESET)))
{
Sleep(100);
if(!ReadHCE(commPort))
{
return FALSE;
}
PurgeComm(commPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
}
Sleep(100);
switch(dwBaudRate)
{
case 57600: //14400 * 4 = 57600
HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 3;
break;
case 115200: //28800 * 4 = 115200
HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 2;
break;
case 230400: //57600 * 4 = 230400
HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 1;
break;
case 460800: //115200 * 4 = 460800
HCC_ERICSSON_SET_BAUD_RATE[EricssonBaudRatePos] = 0;
break;
default:
{
#if 0
TCHAR err[128];
_stprintf(err, _T("Invalid Baud Rate : %d !"), dwBaudRate);
MessageBox(NULL,err, 0, 0);
#else
IFDBG(DebugOut (DEBUG_ERROR, L"Invalid Baud Rate : %d\n", dwBaudRate));
#endif
return FALSE;
}
}
dwWinSDKBaudRate = dwBaudRate > 115200 * 4 ? 115200 : dwBaudRate / 4;
if(SendHCC(commPort, HCC_ERICSSON_SET_BAUD_RATE, sizeof(HCC_ERICSSON_SET_BAUD_RATE)))
{
Sleep(100);
if(ReadHCE(commPort))
{
PurgeComm(commPort, PURGE_TXCLEAR | PURGE_RXCLEAR);
//GetCommState(commPort, &dcb);
dcb.BaudRate = dwWinSDKBaudRate;
if(SetCommState(commPort, &dcb))
{
//MessageBox(NULL, _T("HCC_ERICSSON_SET_BAUD_RATE OK!"), 0, 0);
//Sleep(500);
return TRUE;
}
else
IFDBG(DebugOut (DEBUG_ERROR, L"BthAmb:Failed SetCommState in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
}
else
IFDBG(DebugOut (DEBUG_ERROR, L"BthAmb:HCC_ERICSSON_SET_BAUD_RATE return event fail\n"));
//MessageBox(NULL, _T("HCC_ERICSSON_SET_BAUD_RATE return event fail!"), 0, 0);
}
else
IFDBG(DebugOut (DEBUG_ERROR, L"BthAmb:Send HCC_ERICSSON_SET_BAUD_RATE fail\n"));
//MessageBox(NULL, _T("Send HCC_ERICSSON_SET_BAUD_RATE fail!"), 0, 0);
return FALSE;
}
#endif //_ERICSSON
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->uiFlags = HCI_FLAGS_NORESET | HCI_FLAGS_NOROLESWITCH;
#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"BthAmb:+HCI_StartHardware\n"));
if (hFile != INVALID_HANDLE_VALUE) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthAmb:-HCI_StartHardware (already started)\n"));
return TRUE;
}
if (! gCallback) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthAmb:-HCI_StartHardware (not registered)\n"));
return FALSE;
}
return ERROR_SUCCESS == gCallback (DEVICE_UP, NULL);
}
int HCI_StopHardware (void) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthAmb:+HCI_StopHardware\n"));
if (hFile == INVALID_HANDLE_VALUE) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthAmb:-HCI_StopHardware (already stopped)\n"));
return TRUE;
}
if (! gCallback) {
IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthAmb:-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"BthAmb:HCI_OpenConnection - Started\n"));
if (hFile != INVALID_HANDLE_VALUE)
return FALSE;
WCHAR szComPortName[_MAX_PATH];
DWORD dwBaud = 0;
#if 1
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);
IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthAmb:Failed to read COM port from registry, use default port %s", szComPortName));
}
dwSize = sizeof(dwBaud);
if ((ERROR_SUCCESS == RegQueryValueEx (hk, L"baud", NULL, &dwType, (LPBYTE)&dwBaud, &dwSize)) &&
(dwType == REG_DWORD) && (dwSize == sizeof(dwBaud)))
;
else
{
dwBaud = 115200;
IFDBG(DebugOut (DEBUG_HCI_INIT, L"BthAmb:Failed to read baud rate from registry, use default baud rate %d", dwBaud));
}
RegCloseKey (hk);
IFDBG(DebugOut (DEBUG_HCI_INIT, L"Opening port %s (rate %d) for I/O with unit\n", szComPortName, dwBaud));
}
#endif
// _tcscpy(szComPortName, _T("COM2:"));
// dwBaud = 115200;
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"BthAmb:Failed CreateFile in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
CloseHandle (hFile);
hFile = INVALID_HANDLE_VALUE;
return FALSE;
}
if (! SetupComm (hFile, 20000, 20000)) {
IFDBG(DebugOut (DEBUG_ERROR, L"BthAmb: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"BthAmb: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"BthAmb:Failed SetCommTimeouts in UART HCI Interface. GetLastError = 0x%08x\n", GetLastError ()));
CloseHandle (hFile);
hFile = INVALID_HANDLE_VALUE;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -