⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bthamb.cxx

📁 Windows CE操作系统中适用的蓝牙驱动程序
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//
// 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -