在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例C/C++语言基础 → c++ 蓝牙编程例子

c++ 蓝牙编程例子

C/C++语言基础

下载此实例
  • 开发语言:C/C++
  • 实例大小:8.19M
  • 下载次数:97
  • 浏览次数:2571
  • 发布时间:2018-11-17
  • 实例类别:C/C++语言基础
  • 发 布 人:ouyj
  • 文件格式:.rar
  • 所需积分:2
 相关标签: 蓝牙 编程

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

#include "StdAfx.h"
#include "BlueTooth.h"

CBlueTooth::CBlueTooth(void)
{
	m_Ary_RemoteBthDevInfo.SetSize ( 0, 10*sizeof(BLUETOOTH_DEVICE_INFO) );
	m_Ary_LocalRadioInfo.SetSize ( 0, 10*sizeof(t_LocalRadioInfo) );
}

CBlueTooth::~CBlueTooth(void)
{
	RemoveAll_RemoteBthDevInfo ();
	RemoveAllLocalRadio ();
}  

//
// 用 Socket 函数搜索附近的蓝牙设备,成功时返回设备数,否则返回-1
//
int CBlueTooth::WSAScanNearbyBthDev ()
{
	m_Ary_RemoteBthDevInfo.RemoveAll ();

	WSAQUERYSET wsaq;
	HANDLE hLookup;
	union
	{
		CHAR buf[5000];
		double __unused; // ensure proper alignment
	};

	LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
	DWORD dwSize = sizeof(buf);
	BOOL bHaveName;
	ZeroMemory(&wsaq, sizeof(wsaq));
	wsaq.dwSize = sizeof(wsaq);
	wsaq.dwNameSpace = NS_BTH;
	wsaq.lpcsaBuffer = NULL;
	if (ERROR_SUCCESS != WSALookupServiceBegin (&wsaq, LUP_CONTAINERS, &hLookup))
	{
		TRACE ( _T("WSALookupServiceBegin failed\n") );
		return -1;
	}

	ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
	pwsaResults->dwSize = sizeof(WSAQUERYSET);
	pwsaResults->dwNameSpace = NS_BTH;
	pwsaResults->lpBlob = NULL;
	while (ERROR_SUCCESS == WSALookupServiceNext (hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults))
	{
		ASSERT (pwsaResults->dwNumberOfCsAddrs == 1);
		BTH_ADDR b = ((SOCKADDR_BTH *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr;
		bHaveName = pwsaResults->lpszServiceInstanceName && *(pwsaResults->lpszServiceInstanceName);
		t_RemoteBthDevInfo RemoteBthDevInfo;
		if ( bHaveName )
		{
			StringCchPrintf ( RemoteBthDevInfo.szName, sizeof(RemoteBthDevInfo.szName), _T("%s"), 
				pwsaResults->lpszServiceInstanceName );
		}
		RemoteBthDevInfo.Address.ullLong = b;

		TRACE (L"%s ( %04x%08x )\n", RemoteBthDevInfo.szName, GET_NAP(b), GET_SAP(b) );
		m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
	}
	WSALookupServiceEnd(hLookup);

	return (int)m_Ary_RemoteBthDevInfo.GetSize();
}

BOOL AUTHENTICATION_CALLBACK (LPVOID pvParam, PBLUETOOTH_DEVICE_INFO pDevice)
{
	t_AUTHENTICATION_CALLBACK_Para *pAUTHENTICATION_CALLBACK_Para = (t_AUTHENTICATION_CALLBACK_Para*)pvParam;
	if ( pAUTHENTICATION_CALLBACK_Para )
	{
		pDevice->fAuthenticated = TRUE;
		DWORD result = BluetoothUpdateDeviceRecord ( pDevice );
		ASSERT ( result == ERROR_SUCCESS );
		result = BluetoothSendAuthenticationResponse ( pAUTHENTICATION_CALLBACK_Para->hRadio, pDevice, AUTHENTICATION_PASSKEY );
		if ( result == ERROR_SUCCESS )
			return TRUE;
	}
	return FALSE;
}

//
// 用蓝牙 APIs 搜索附近的蓝牙设备,成功时返回设备数,否则返回-1
//
int CBlueTooth::ScanNearbyBthDev (
		HANDLE hRadio,
		BOOL fReturnAuthenticated/* = TRUE*/,
		BOOL fReturnRemembered/* = TRUE*/,
		BOOL fReturnUnknown/* = TRUE*/,
		BOOL fReturnConnected/* = TRUE*/,
		BOOL fIssueInquiry/* = FALSE*/,
		UCHAR cTimeoutMultiplier/* = 30*/
	)
{
	RemoveAll_RemoteBthDevInfo ();
	CWaitCursor WaitCursor;

	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp;
	HBLUETOOTH_DEVICE_FIND hbf;
	ZeroMemory(&bdsp, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));

	bdsp.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
	bdsp.hRadio = hRadio;
	bdsp.fReturnAuthenticated = fReturnAuthenticated;
	bdsp.fReturnRemembered = fReturnRemembered;
	bdsp.fReturnUnknown = fReturnUnknown;
	bdsp.fReturnConnected = fReturnConnected;
	bdsp.fIssueInquiry = fIssueInquiry;
	bdsp.cTimeoutMultiplier = cTimeoutMultiplier;

	hbf = BluetoothFindFirstDevice(&bdsp, &bdi);
	if (hbf == NULL) return -1;

	while(true)
	{
		TRACE ( _T("%s ( %s )\n"), bdi.szName, FormatBthAddress(bdi.Address.rgBytes) );
		t_RemoteBthDevInfo RemoteBthDevInfo;
		RemoteBthDevInfo.hRadio = hRadio;
		RemoteBthDevInfo.Address.ullLong = bdi.Address.ullLong;
		_snwprintf_s ( RemoteBthDevInfo.szName, LENGTH(RemoteBthDevInfo.szName), _T("%s"), bdi.szName );
		// 枚举服务
		EnumerateInstalledServices ( RemoteBthDevInfo );
		// 注册配对回调函数
		RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para = new t_AUTHENTICATION_CALLBACK_Para;
		if ( RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para )
		{
			RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para->lpBlueTooth = this;
			RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para->hRadio = hRadio;
		}
		BluetoothRegisterForAuthentication ( &bdi, &RemoteBthDevInfo.hRegHandle, AUTHENTICATION_CALLBACK, RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para );

		m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
		if ( !BluetoothFindNextDevice(hbf, &bdi) )
			break;
	}
	BluetoothFindDeviceClose(hbf);

	return (int)m_Ary_RemoteBthDevInfo.GetSize();
}

//
// 用向导手工搜索附近的蓝牙设备并建立连接,得到设备的详细信息,成功时返回设备数
//
int CBlueTooth::ScanNearbyBthDev_Wizard (
		HWND	hwndParent,
		HANDLE	hRadio,
		LPWSTR  pszInfo/*=NULL*/,						//  IN  If not NULL, sets the "information" text
		BOOL    fForceAuthentication/*=FALSE*/,			//  IN  If TRUE, authenication will be forced before returning
		BOOL    fShowAuthenticated/*=FALSE*/,			//  IN  If TRUE, authenticated devices will be shown in the picker
		BOOL    fShowRemembered/*=TRUE*/,				//  IN  If TRUE, remembered devices will be shown in the picker
		BOOL    fShowUnknown/*=TRUE*/,					//  IN  If TRUE, unknown devices that are not authenticated or "remember" will be shown.
		BOOL    fAddNewDeviceWizard/*=TRUE*/,			//  IN  If TRUE, invokes the add new device wizard.
		BOOL    fSkipServicesPage/*=FALSE*/,			//  IN  If TRUE, skips the "Services" page in the wizard.
		PFN_DEVICE_CALLBACK pfnDeviceCallback/*=NULL*/,	//  IN  If non-NULL, a callback that will be called for each device. If the
														//      the callback returns TRUE, the item will be added. If the callback is
														//      is FALSE, the item will not be shown.
		LPVOID  pvParam/*=NULL*/						//  IN  Parameter to be passed to pfnDeviceCallback as the pvParam.
	)
{
	RemoveAll_RemoteBthDevInfo ();
	BLUETOOTH_SELECT_DEVICE_PARAMS btsdp = { sizeof(btsdp) };

	btsdp.hwndParent = hwndParent;
	btsdp.pszInfo = pszInfo;
	btsdp.fForceAuthentication = fForceAuthentication;
	btsdp.fShowAuthenticated = fShowAuthenticated;
	btsdp.fShowRemembered = fShowRemembered;
	btsdp.fShowUnknown = fShowUnknown;
	btsdp.fAddNewDeviceWizard = fAddNewDeviceWizard;
	btsdp.fSkipServicesPage = fSkipServicesPage;
	btsdp.pfnDeviceCallback = pfnDeviceCallback;
	btsdp.pvParam = pvParam;

	BOOL b = BluetoothSelectDevices( &btsdp );
	if ( b )
	{
		BLUETOOTH_DEVICE_INFO *pbtdi = btsdp.pDevices;
		for ( ULONG cDevice = 0; cDevice < btsdp.cNumDevices; cDevice    )
		{
			if ( pbtdi->fAuthenticated || pbtdi->fRemembered )
			{
				t_RemoteBthDevInfo RemoteBthDevInfo;
				RemoteBthDevInfo.hRadio = hRadio;
				RemoteBthDevInfo.Address = pbtdi->Address;
				_snwprintf_s ( RemoteBthDevInfo.szName, LENGTH(RemoteBthDevInfo.szName), _T("%s"), pbtdi->szName );
				EnumerateInstalledServices ( RemoteBthDevInfo );
				m_Ary_RemoteBthDevInfo.Add ( RemoteBthDevInfo );
			}
			pbtdi = (BLUETOOTH_DEVICE_INFO *) ((LPBYTE)pbtdi   pbtdi->dwSize);
		}
		BluetoothSelectDevicesFree( &btsdp );
	}

	return (int)m_Ary_RemoteBthDevInfo.GetSize();
}

//
// 根据远程蓝牙设备的地址获取详细信息
//
BOOL CBlueTooth::BluetoothGetDeviceInfo ( IN t_RemoteBthDevInfo& RemoteBthDevInfo, OUT BLUETOOTH_DEVICE_INFO *pbtdi )
{
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	bdi.Address.ullLong = RemoteBthDevInfo.Address.ullLong;
	if ( ERROR_SUCCESS != ::BluetoothGetDeviceInfo ( RemoteBthDevInfo.hRadio, &bdi ) )
		return FALSE;
	if ( pbtdi ) memcpy ( pbtdi, &bdi, sizeof(BLUETOOTH_DEVICE_INFO) );
	return TRUE;
}

BOOL CBlueTooth::BluetoothSetServiceState ( HANDLE hRadio, BLUETOOTH_DEVICE_INFO &bdi, GUID guidService, DWORD dwServiceFlags )
{
	DWORD result = ::BluetoothSetServiceState(hRadio, &bdi, &guidService, dwServiceFlags);
	if ( ERROR_SUCCESS != result && ERROR_SERVICE_DOES_NOT_EXIST != result )
	{
		TRACE ( _T("BluetoothSetServiceState failed : %s\n"), hwFormatMessage (result) );
		return FALSE;
	}
	return TRUE;
}

// 枚举已安装的服务
int CBlueTooth::EnumerateInstalledServices( t_RemoteBthDevInfo& RemoteBthDevInfo )
{
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
		return -1;

	BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, SerialPortServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
	BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, LANAccessUsingPPPServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );
	BluetoothSetServiceState ( RemoteBthDevInfo.hRadio, bdi, DialupNetworkingServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE );

	if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
		return -1;
	DWORD numServices = LENGTH(RemoteBthDevInfo.guidServices);	
	DWORD result = BluetoothEnumerateInstalledServices(RemoteBthDevInfo.hRadio,&bdi, &numServices, RemoteBthDevInfo.guidServices);
	if ( ERROR_SUCCESS == result ) return numServices;
	return -1;
}

// 显示序号为 nIndex 的蓝牙设备属性框
BOOL CBlueTooth::ShowPropertySheet(int nIndex, HWND hwdParent/*=NULL*/)
{
	if ( nIndex < 0 || nIndex >=m_Ary_RemoteBthDevInfo.GetSize() )
		return FALSE;

	t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt ( nIndex );
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
		return FALSE;

	return BluetoothDisplayDeviceProperties ( hwdParent, &bdi );
}

// 请求与远程蓝牙设备配对
BOOL CBlueTooth::RequestAuthenticateDevice(int nIndex, HWND hwdParent/*=NULL*/, DWORD *presult/*=NULL*/)
{
	if ( nIndex < 0 || nIndex >=m_Ary_RemoteBthDevInfo.GetSize() )
		return FALSE;

	t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt ( nIndex );
	BLUETOOTH_DEVICE_INFO bdi = { sizeof(BLUETOOTH_DEVICE_INFO) };
	if ( !BluetoothGetDeviceInfo ( RemoteBthDevInfo, &bdi ) )
		return FALSE;

	if ( bdi.fAuthenticated ) return TRUE;	// 已经配对了
	bdi.fAuthenticated = TRUE;
	VERIFY ( ERROR_SUCCESS == BluetoothUpdateDeviceRecord ( &bdi ) );
	DWORD result = BluetoothAuthenticateDevice ( hwdParent, RemoteBthDevInfo.hRadio, &bdi, AUTHENTICATION_PASSKEY, (ULONG)wcslen(AUTHENTICATION_PASSKEY) );
	if ( presult ) *presult = result;
	if ( result == ERROR_SUCCESS ) return TRUE;

	return FALSE;
}

CString CBlueTooth::FormatBthAddress(BYTE *BthAddress)
{
	ASSERT ( BthAddress );
	BLUETOOTH_ADDRESS Address;
	ASSERT_ADDRESS ( BthAddress, LENGTH(Address.rgBytes)*sizeof(TCHAR) );
	CString csBthAddress;
	for ( int i=0; i<LENGTH(Address.rgBytes); i   )
	{
		CString csNode;
		csNode.Format ( _T("%.2x"), BthAddress[LENGTH(Address.rgBytes)-i-1] );
		if ( !csBthAddress.IsEmpty() ) csBthAddress  = ":";
		csBthAddress  = csNode;
	}
	return csBthAddress;
}

// 枚举本地蓝牙设备,返回本地蓝牙设备数
int CBlueTooth::EnumerateLocalRadios(void)
{
	m_Ary_LocalRadioInfo.RemoveAll ();

	HANDLE hRadio = NULL;
	BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) };

	HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio( &btfrp, &hRadio );
	if ( NULL != hFind )
	{
		do
		{
			if ( hRadio )
			{
				t_LocalRadioInfo LocalRadioInfo;
				LocalRadioInfo.hRadio = hRadio;
				if ( ERROR_SUCCESS == BluetoothGetRadioInfo ( hRadio, &LocalRadioInfo.RadioInfo ) )
				{
					// 千万注意:以下代码让蓝牙虚拟传出串口能正常工作,我是花了一个通宵的时间才找到这个原因的。
					if (FALSE == BluetoothEnableDiscovery(hRadio, TRUE))
					{
						TRACE(_T("%s\n"), hwFormatMessage(GetLastError()));
					}
					if (FALSE == BluetoothEnableIncomingConnections(hRadio, TRUE))
					{
						TRACE(_T("%s\n"), hwFormatMessage(GetLastError()));
					}

					m_Ary_LocalRadioInfo.Add ( LocalRadioInfo );
				}
			}

		} while( BluetoothFindNextRadio( hFind, &hRadio ) );
		BluetoothFindRadioClose( hFind );
		return (int)m_Ary_LocalRadioInfo.GetSize ();
	}

	return 0;
}

void CBlueTooth::RemoveAllLocalRadio(void)
{
	for ( int i=0; i<m_Ary_LocalRadioInfo.GetSize(); i   )
	{
		t_LocalRadioInfo &LocalRadioInfo = m_Ary_LocalRadioInfo.GetAt(i);
		if ( LocalRadioInfo.hRadio )
			CloseHandle ( LocalRadioInfo.hRadio );
	}
	m_Ary_LocalRadioInfo.RemoveAll ();
}

void CBlueTooth::RemoveAll_RemoteBthDevInfo(void)
{
	for ( int i=0; i<m_Ary_RemoteBthDevInfo.GetSize(); i   )
	{
		t_RemoteBthDevInfo &RemoteBthDevInfo = m_Ary_RemoteBthDevInfo.GetAt(i);
		if ( RemoteBthDevInfo.hRegHandle )
			BluetoothUnregisterAuthentication ( RemoteBthDevInfo.hRegHandle );

		if ( RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para )
			delete RemoteBthDevInfo.pAUTHENTICATION_CALLBACK_Para;

	}
	m_Ary_RemoteBthDevInfo.RemoveAll ();
}

int CBlueTooth::Test(void)
{
	
	return 0;
}

标签: 蓝牙 编程

实例下载地址

c++ 蓝牙编程例子

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 b2964552 发表于: 2019-10-25 09:11 27
下载了编译不了,缺少了PSDK安装包

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有1条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警