1. 程式人生 > >Qt使用Windows藍芽API搜尋藍芽裝置並建立串列埠服務的方法

Qt使用Windows藍芽API搜尋藍芽裝置並建立串列埠服務的方法

如何使用windows藍芽api搜尋藍芽裝置可參考我的另外一篇文章Windows列舉搜尋遠端藍芽裝置。使用如下程式碼可以藉助windows自動安裝串列埠驅動(如果遠端藍芽裝置支援串列埠服務的話)。
BluetoothSetServiceState ( hbr, &btdi, &SerialPortServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );//開啟遠端藍芽裝置上的服務以便使用,其中hbr為BluetoothFindFirstRadio或BluetoothFindNextRadio所得的本地藍芽Radio對應的控制代碼,btdi為要設定的遠端藍芽裝置對應的BLUETOOTH_DEVICE_INFO物件

使用BluetoothAuthenticateDevice來完成自動配對,如下:

BluetoothAuthenticateDevice(phnd,hbr,&(btdi),AUTHENTICATION_PASSKEY,4);//btdi為要配對的遠端藍芽裝置的BLUETOOTH_DEVICE_INFO,AUTHENTICATION_PASSKEY為配對使用的配對碼,是一個字串陣列的指標,之後的引數是配對碼的長度。
整個Qt的程式碼如下:
#ifndef BTCOMTEST_H//btcomtest.h
#define BTCOMTEST_H
#pragma once
#include <QtGui/QMainWindow>
#include "ui_btcomtest.h"

#include <windows.h>  
#include <BluetoothAPIs.h>  
#include <conio.h>  
#include <iostream>  
#include <string>  
#include <locale>  



#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <ws2bth.h>

#include <stdio.h>
#include <bthsdpdef.h>
#pragma comment ( lib, "Irprops.lib")

#include <tchar.h>
// 配對時用得PIN碼
#define AUTHENTICATION_PASSKEY	_T("1234")
//常用操作符
#define LENGTH(x) sizeof(x)/sizeof(x[0])


#include <QList>

//#include "mybluetooth.h"

#pragma comment(lib,"Bthprops.lib")  

using namespace std;  

typedef struct _AUTHENTICATION_CALLBACK_Para
{
	LPVOID lpBlueTooth;
	HANDLE hRadio;
} t_AUTHENTICATION_CALLBACK_Para;

class btcomTest : public QMainWindow
{
	Q_OBJECT

public:
	btcomTest(QWidget *parent = 0, Qt::WFlags flags = 0);
	~btcomTest();
public slots:
	void searchBt();
	void connectRemoteDevice();

private:
	Ui::btcomTestClass ui;
	QList<BLUETOOTH_DEVICE_INFO> btDeviceList;
	HANDLE hbr;  
	/*static BOOL AUTHENTICATION_CALLBACK (LPVOID pvParam, PBLUETOOTH_DEVICE_INFO pDevice);*/
	static BOOL AUTHENTICATION_CALLBACK (PVOID pvParam, PBLUETOOTH_DEVICE_INFO pDevice);
	QString getMAC(BLUETOOTH_ADDRESS Daddress);
};

#endif // BTCOMTEST_H
#include "btcomtest.h"//btcomtest.cpp
#include <QString>
#include <QDebug>

btcomTest::btcomTest(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);
	connect(ui.searchBtn,SIGNAL(clicked()),this,SLOT(searchBt()));
	connect(ui.clearBtn,SIGNAL(clicked()),ui.btListBox,SLOT(clear()));
	connect(ui.connectBtn,SIGNAL(clicked()),this,SLOT(connectRemoteDevice()));
	hbr = NULL;  
	//qDebug()<<QString::number(171,16);
	
}

btcomTest::~btcomTest()
{
	if (hbr)
	{
		CloseHandle(hbr);
		hbr=NULL;
	}
}

void btcomTest::searchBt()
{
	ui.btListBox->clear();
	btDeviceList.clear();

	
	HBLUETOOTH_RADIO_FIND hbf = NULL;  
	HBLUETOOTH_DEVICE_FIND hbdf = NULL;  
	BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(BLUETOOTH_FIND_RADIO_PARAMS) };  
	BLUETOOTH_RADIO_INFO bri = { sizeof(BLUETOOTH_RADIO_INFO)};  
	BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = { sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS) };  
	BLUETOOTH_DEVICE_INFO btdi = { sizeof(BLUETOOTH_DEVICE_INFO) };  
	hbf=BluetoothFindFirstRadio(&btfrp, &hbr);  
	bool brfind = hbf != NULL;  
	if (brfind&&BluetoothGetRadioInfo(hbr, &bri) == ERROR_SUCCESS)  
	{
		qDebug()<<"LocalName:"<<bri.szName;
		btsp.hRadio = hbr;  
		btsp.fReturnAuthenticated = FALSE;		
		btsp.fReturnConnected = FALSE;  
		btsp.fReturnRemembered = FALSE;  
		btsp.fReturnUnknown = TRUE;  
		btsp.fIssueInquiry=TRUE;
		btsp.cTimeoutMultiplier = 5;  
		hbdf=BluetoothFindFirstDevice(&btsp, &btdi);  
		bool bfind = hbdf != NULL;  
		while (bfind)  
		{  
			QString btInfo=QString::fromWCharArray(btdi.szName)+"  "+getMAC(btdi.Address);
			//QString btInfo=QString::fromWCharArray(btdi.szName)+":"+QString::number(btdi.Address.ullLong,16);
			qDebug()<<btInfo;
			if (btInfo.contains("Alpha"))
			{
				btDeviceList.append(btdi);
				ui.btListBox->addItem(btInfo);
			}
			bfind=BluetoothFindNextDevice(hbdf, &btdi);  
		}
		BluetoothFindDeviceClose(hbdf);

	}
	BluetoothFindRadioClose(hbf);  
	
}

void btcomTest::connectRemoteDevice()
{
	BLUETOOTH_DEVICE_INFO btdi=btDeviceList.at(ui.btListBox->currentRow());
	qDebug("hbr:%x BtName:",btdi.Address.ullLong);
	qDebug()<<QString::fromWCharArray(btdi.szName);
	BluetoothSetServiceState ( hbr, &btdi, &SerialPortServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );

	//t_AUTHENTICATION_CALLBACK_Para *pCallback=new t_AUTHENTICATION_CALLBACK_Para;
	//pCallback->hRadio=hbr;
	//pCallback->lpBlueTooth=NULL;
	//HBLUETOOTH_AUTHENTICATION_REGISTRATION phRegHandle;
	////BluetoothAuthenticateDevice ( NULL, hbr, &btdi, AUTHENTICATION_PASSKEY, (ULONG)wcslen(AUTHENTICATION_PASSKEY) );
	//PFN_AUTHENTICATION_CALLBACK a=(PFN_AUTHENTICATION_CALLBACK)AUTHENTICATION_CALLBACK;
	//BluetoothRegisterForAuthentication (&btdi,&phRegHandle,a,hbr);


	if (!btdi.fAuthenticated)
	{
		BluetoothSetServiceState ( hbr, &(btdi), &SerialPortServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
		BluetoothAuthenticateDevice(this->winId(),hbr,&(btdi),AUTHENTICATION_PASSKEY,4);
		BluetoothUpdateDeviceRecord(&(btdi));
		bool resultConnect=btdi.fAuthenticated;
		while (resultConnect!=true)
		{
			BluetoothAuthenticateDevice(winId(),hbr,&(btdi),AUTHENTICATION_PASSKEY,4);
			BluetoothUpdateDeviceRecord(&(btdi));
			resultConnect=btdi.fAuthenticated;
		}
	}
}

BOOL btcomTest::AUTHENTICATION_CALLBACK( PVOID pvParam, PBLUETOOTH_DEVICE_INFO pDevice )
{
	HANDLE mRadio=(HANDLE) pvParam;
	if (mRadio)
	{
		DWORD result= BluetoothUpdateDeviceRecord ( pDevice );
		result=ERROR_SUCCESS;
		result=BluetoothSendAuthenticationResponse ( mRadio, pDevice, AUTHENTICATION_PASSKEY );
		if (result==ERROR_SUCCESS)
		{
			return TRUE;
		}
	}
	return FALSE;
}

QString btcomTest::getMAC( BLUETOOTH_ADDRESS Daddress )
{
	//QString addr= QString::number(Daddress.rgBytes[5],16)+":"+QString::number(Daddress.rgBytes[4],16)+":"+QString::number(Daddress.rgBytes[3],16)+":"+QString::number(Daddress.rgBytes[2],16)+":"+QString::number(Daddress.rgBytes[1],16)+":"+QString::number(Daddress.rgBytes[0],16);
	//QString addr=QString("%1:%2:%3:%4:%5:%6").arg(Daddress.rgBytes[5],2,16).arg(Daddress.rgBytes[4],2,16).arg(Daddress.rgBytes[3],2,16).arg(Daddress.rgBytes[2],2,16).arg(Daddress.rgBytes[1],2,16).arg(Daddress.rgBytes[0],2,16);
	QString addr;
	addr=addr.sprintf("%02x:%02x:%02x:%02x:%02x:%02x",Daddress.rgBytes[5],Daddress.rgBytes[4],Daddress.rgBytes[3],Daddress.rgBytes[2],Daddress.rgBytes[1],Daddress.rgBytes[0]);
	return addr;
}