写在开头
最近在弄 windows API 的蓝牙,实现windows 10 的 PC电脑自动和目标蓝牙配对、连接、和收发数据。这是算是一个开始,要进行蓝牙通信的前提,需要能够获取到本地蓝牙的句柄和信息。后续会继续更新整个实现代码。由于本人也是边看API变实现,代码逻辑可能会有些混乱,欢迎留言。
实现例子在文章末尾,前面是一些用到的API记录
1 windows API 函数英文注释和翻译
1.1 bluetoothapis
1.1.1 BLUETOOTH_DEVICE_SEARCH_PARAMS
参考地址:https://docs.microsoft.com/zh-cn/windows/win32/api/BluetoothAPIs/ns-bluetoothapis-bluetooth_device_search_params
功能: specifies search criteria for Bluetooth device searches.
指定蓝牙设备搜索的搜索标准
句法:
typedef struct _BLUETOOTH_DEVICE_SEARCH_PARAMS {
DWORD dwSize; // 结构体大小,以字节为单位
BOOL fReturnAuthenticated; // 指定搜索返回 已认证 的蓝牙设备 authenticated->已认证
BOOL fReturnRemembered; // 指定搜索返回 已记住 的蓝牙设备
BOOL fReturnUnknown; // 指定搜索返回 未知 的蓝牙设备
BOOL fReturnConnected; // 指定搜索返回 已连接 的蓝牙设备
BOOL fIssueInquiry; // 指定发出新的查询
UCHAR cTimeoutMultiplier; // 直接翻译就是超时的倍数,以 1.28秒为单位,最大值为48
HANDLE hRadio; // 无线电句柄,在该无线电句柄上执行查询,如果设置为NULL,所有本地蓝牙设备都执行搜索
} BLUETOOTH_DEVICE_SEARCH_PARAMS;
1.1.2 BLUETOOTH_DEVICE_INFO_STRUCT
参考地址:https://docs.microsoft.com/zh-cn/windows/win32/api/bluetoothapis/ns-bluetoothapis-bluetooth_device_info_struct
功能: provides information about a Bluetooth device.
提供有关蓝牙的信息
句法:
typedef struct _BLUETOOTH_DEVICE_INFO {
DWORD dwSize; // 该结构体大小,以字节为单位
BLUETOOTH_ADDRESS Address; // 蓝牙设备地址
ULONG ulClassofDevice; // 设备的类型
BOOL fConnected; // 指定是否连接设备
BOOL fRemembered; // 指定该设备是否为可记住的设备。并非所有记住 的设备都通过身份验证
BOOL fAuthenticated; // 指定设备是经过身份验证,配对还是绑定。所有经过身份验证的设备都会被记住。
SYSTEMTIME stLastSeen; // 上次查看该设备的时间为 SYSTEMTIME 结构
SYSTEMTIME stLastUsed; // 上次使用该设备的时间为 SYSTEMTIME 结构
WCHAR szName[BLUETOOTH_MAX_NAME_SIZE]; // 设备名称。
} BLUETOOTH_DEVICE_INFO_STRUCT;
1.1.3 BluetoothFindFirstDevice
参考地址:https://docs.microsoft.com/zh-cn/windows/win32/api/bluetoothapis/nf-bluetoothapis-bluetoothfindfirstdevice
功能:begins the enumeration Bluetooth devices.
开始枚举蓝牙设备
//HBLUETOOTH_DEVICE_FIND 一个句柄,该函数返回一个 HANDLE
HBLUETOOTH_DEVICE_FIND BluetoothFindFirstDevice(
const BLUETOOTH_DEVICE_SEARCH_PARAMS *pbtsp, //
BLUETOOTH_DEVICE_INFO *pbtdi
);
1.1.4 BLUETOOTH_FIND_RADIO_PARAMS
参考地址:https://docs.microsoft.com/zh-cn/windows/win32/api/bluetoothapis/ns-bluetoothapis-bluetooth_find_radio_params
功能:enumerating installed Bluetooth radios.
开始枚举安装的蓝牙无线电
句法:
typedef struct _BLUETOOTH_FIND_RADIO_PARAMS {
DWORD dwSize; // 该结构的大小,以字节为单位
} BLUETOOTH_FIND_RADIO_PARAMS;
1.1.5 BluetoothFindFirstRadio
参考地址:https://docs.microsoft.com/zh-cn/windows/win32/api/bluetoothapis/nf-bluetoothapis-bluetoothfindfirstradio
功能:begins the enumeration of local Bluetooth radios.
开始枚举本地的蓝牙无线电
句法:
HBLUETOOTH_RADIO_FIND BluetoothFindFirstRadio(
const BLUETOOTH_FIND_RADIO_PARAMS *pbtfrp, // 指向 BLUETOOTH_FIND_RADIO_PARAMS 指针
HANDLE *phRadio // 指向第一个枚举的无线电句柄将返回的句柄。当不再需要时,必须通过CloseHandle关闭此句柄。
);
返回值:
创建一个HBLUETOOTH_RADIO_FIND,可以与BluetoothFindNextRadio函数一起使用,不需要次句柄时,必须通过BluetoothFindRadioClose将其关闭
1.1.6 BluetoothFindNextRadio
参考地址:https://docs.microsoft.com/zh-cn/windows/win32/api/bluetoothapis/nf-bluetoothapis-bluetoothfindnextradio
功能:功能找到下一个蓝牙无线电(本地)
句法:
BOOL BluetoothFindNextRadio(
HBLUETOOTH_RADIO_FIND hFind, // 通过调用 BluetootrhFindFirstRadio 返回的句柄
HANDLE *phRadio // 指向下一个枚举的无线电蓝牙返回的句柄
);
获取本地蓝牙的句柄和信息的例子:
#include <afxtempl.h>
#include <iostream>
#include <bthsdpdef.h>
#include <BluetoothAPIs.h>
#include "winsock2.h"
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Bthprops.lib")
using namespace std;
int main()
{
CArray<HANDLE, HANDLE&> m_arrLocal;
// 先要找到本地的蓝牙
//HBLUETOOTH_DEVICE_FIND hradio; // 本地无线电设备句柄, HANDLE 的别名
HANDLE hradio;
BLUETOOTH_FIND_RADIO_PARAMS bfrp;
bfrp.dwSize = sizeof(bfrp);
cout << "a sizeof(bfrep) = " << bfrp.dwSize << endl;
HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&bfrp, &hradio); // 该函数返回的句柄就是为了给 BluetoothFindNextRadio使用的
cout << "b sizeof(bfrep) = " << bfrp.dwSize << endl;
if (hFind) {
// 一旦找到了第一个蓝牙设备,就利用第一个蓝牙设备去找第二个蓝牙设备
// 创建一个数组,用来存储设备的信息
CArray<BLUETOOTH_RADIO_INFO, BLUETOOTH_RADIO_INFO&> m_arrlocalmessage;
BLUETOOTH_RADIO_INFO pbri={ sizeof(BLUETOOTH_RADIO_INFO) };
cout << "发现本地第一个蓝牙" << endl;
do
{
if (hradio) {
m_arrLocal.Add(hradio);
// 获取句柄 hradio 的蓝牙信息
int success = BluetoothGetRadioInfo(hradio, &pbri);
if (success == 0) {
cout << "获取本地蓝牙设备信息成功" << endl;
m_arrlocalmessage.Add(pbri);
cout << "蓝牙信息:" << endl;
cout << "dwSize = " << pbri.dwSize << endl;
cout << "address = ";
// 从 address 的 rgBytes 长度为6
stringstream ioss;
string s_temp;
for (int i = 5; i >= 0; i--) {
ioss << setiosflags(ios::uppercase) << hex << (int)pbri.address.rgBytes[i] << ":";
}
ioss >> s_temp;
cout << s_temp << endl;
wcout << "szName = " << pbri.szName << endl;
cout << "ulClassofDevice = " << pbri.ulClassofDevice << endl;
cout << "lmpSubversion = " << pbri.lmpSubversion << endl;
cout << "manufacturer = " << pbri.manufacturer << endl;
}
}
}
while (BluetoothFindNextRadio(hFind, &hradio));
// 循环退出后,句柄 hFind 就没用了,关闭掉
BluetoothFindRadioClose(hFind);
}
else {
cout << "未能发现本地蓝牙" << endl;
}
DWORD error;
error = GetLastError();
cout << error << endl;
cout << "蓝牙个数为:" << m_arrLocal.GetCount() << endl;
system("pause");
}