amb*_*ark 6 c++ windows winapi bluetooth
我需要能够使用C++ for Windows中的代码配对设备(特别是win7或更新版本).我编写了应该可以工作的代码,但事实并非如此.我可以配对很多设备,Roku,耳机,扬声器等,但由于某种原因,我需要配对的设备无法正常工作.
它总是返回错误代码0x05,根据bthdefs.h定义为BTH_ERROR_AUTHENTICATION_FAILURE.
所以这里奇怪的部分.它永远不会尝试进行身份验证.在调用期间应调用以提供密钥的回调函数不会被调用.我已经确认它会被其他设备(如耳机)调用.
我已经尝试使用BluetoothAuthenticateDeviceEx()而没有回调函数,它应该在Windows中弹出GUI来完成配对.它弹出我的耳机和其他设备,它不会弹出我的设备.
作为旁注,我可以使用Window的蓝牙向导配对设备就好了.它只是拒绝以编程方式工作.
我无法弄清楚我正在使用的winapi代码和windows'向导在配对期间正在做什么之间的区别.
这是我能得到的最简单的测试应用程序.我真正的应用程序使用Qt和mingw来构建.此应用程序使用MSVC 2012和纯Windows代码来从问题中删除任何混淆.我的所有代码都有与错误代码5相同的问题.
#include <windows.h>
#include "bthdef.h"
#include "BluetoothAPIs.h"
#include <tchar.h>
#include <string>
#include <iostream>
#include <vector>
#pragma comment(lib, "bthprops.lib")
using namespace std;
vector<BLUETOOTH_DEVICE_INFO> scanDevices()
{
vector<BLUETOOTH_DEVICE_INFO> res;
BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp;
BLUETOOTH_DEVICE_INFO bdi;
HBLUETOOTH_DEVICE_FIND hbf;
ZeroMemory(&bdsp, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));
// set options for how we want to load our list of BT devices
bdsp.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
bdsp.fReturnAuthenticated = TRUE;
bdsp.fReturnRemembered = TRUE;
bdsp.fReturnUnknown = TRUE;
bdsp.fReturnConnected = TRUE;
bdsp.fIssueInquiry = TRUE;
bdsp.cTimeoutMultiplier = 4;
bdsp.hRadio = NULL;
bdi.dwSize = sizeof(bdi);
// enumerate our bluetooth devices
hbf = BluetoothFindFirstDevice(&bdsp, &bdi);
if (hbf)
{
do
{
res.push_back(bdi);
} while (BluetoothFindNextDevice(hbf, &bdi));
// close our device enumerator
BluetoothFindDeviceClose(hbf);
}
return res;
}
BOOL CALLBACK bluetoothAuthCallback(LPVOID param, PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS params)
{
cout << "callback happened" << endl;
return TRUE;
}
void pairDevice(BLUETOOTH_DEVICE_INFO device)
{
wstring ws = device.szName;
cout << "Pairing device " << string(ws.begin(), ws.end()) << endl;
// register callback
cout << "Registering callback" << endl;
HBLUETOOTH_AUTHENTICATION_REGISTRATION hCallbackHandle = 0;
DWORD result = BluetoothRegisterForAuthenticationEx(&device, &hCallbackHandle, (PFN_AUTHENTICATION_CALLBACK_EX)&bluetoothAuthCallback, NULL);
if (result != ERROR_SUCCESS)
{
cout << "Failed to register callback" << endl;
return;
}
// authenticate
result = BluetoothAuthenticateDeviceEx(NULL, NULL, &device, NULL, MITMProtectionNotRequired);
//DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &device, NULL, MITMProtectionRequired);
//DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &device, NULL, MITMProtectionNotRequiredBonding);
//DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &device, NULL, MITMProtectionRequiredBonding);
//DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &device, NULL, MITMProtectionNotRequiredGeneralBonding);
//DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &device, NULL, MITMProtectionRequiredGeneralBonding);
//DWORD result = BluetoothAuthenticateDeviceEx(NULL, NULL, &device, NULL, MITMProtectionNotDefined);
switch (result)
{
case ERROR_SUCCESS:
cout << "pair device success" << endl;
break;
case ERROR_CANCELLED:
cout << "pair device failed, user cancelled" << endl;
break;
case ERROR_INVALID_PARAMETER:
cout << "pair device failed, invalid parameter" << endl;
break;
case ERROR_NO_MORE_ITEMS:
cout << "pair device failed, device appears paired already" << endl;
break;
default:
cout << "pair device failed, unknown error, code " << (unsigned int)result << endl;
break;
}
}
int _tmain(int argc, _TCHAR *argv[])
{
cout << "Scanning bluetooth devices..." << endl;
cout.flush();
// scan devices
vector<BLUETOOTH_DEVICE_INFO> devices = scanDevices();
cout << "Got " << devices.size() << " devices" << endl;
// list all devices
int pdIndex = -1;
int foundDev = -1;
vector<BLUETOOTH_DEVICE_INFO>::const_iterator devci;
for (devci=devices.begin();devci!=devices.end();devci++)
{
pdIndex++;
wstring ws = (*devci).szName;
cout << "Device: " << string(ws.begin(), ws.end()) << endl;
// see if we find our device (case sensitive)
if (ws.find(L"smp") != string::npos)
foundDev = pdIndex;
}
// pick our ismp device
if (foundDev == -1)
{
cout << "Could not find a device to pair" << endl;
return 1;
}
BLUETOOTH_DEVICE_INFO pd = devices[foundDev];
wstring ws = pd.szName;
cout << "Found device to pair, " << string(ws.begin(), ws.end()) << endl;
// attempt to pair device
pairDevice(pd);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
小智 5
据我所知,我可以在你的代码中看到很多问题:
1)你在调用'pairDevice'时调用了BluetoothRegisterForAuthenticationEx:hCallbackHandle变量只会在调用期间存在, 所以你必须在 'pairDevice' 之前注册
2)之后您没有调用BluetoothUnregister
3)您没有删除hCallbackHandle句柄
4)你的'bluetoothAuthCallback'是空的:你必须做类似的事情
BLUETOOTH_AUTHENTICATE_RESPONSE response;
::ZeroMemory(&response,sizeof(BLUETOOTH_AUTHENTICATE_RESPONSE));
response.authMethod = cbparams->authenticationMethod;
response.bthAddressRemote = cbparams->deviceInfo.Address;
response.negativeResponse = FALSE;
DWORD error=::BluetoothSendAuthenticationResponseEx(nullptr, &response);
Run Code Online (Sandbox Code Playgroud)
(见上述评论;-)
5)你对'BluetoothAuthenticateDeviceEx'的调用会异步触发回调例程......所以你必须'等待'它才能离开main()函数...
小智 2
也许您应该将响应添加到身份验证回调中。像这样:
BLUETOOTH_DEVICE_INFO aw = params->deviceInfo;
HANDLE lRadio = NULL;
BLUETOOTH_AUTHENTICATE_RESPONSE bar2Send;
::ZeroMemory(&bar2Send, sizeof(BLUETOOTH_AUTHENTICATE_RESPONSE));
bar2Send.bthAddressRemote = params->deviceInfo.Address;
bar2Send.authMethod = params->authenticationMethod;
DWORD result = BluetoothSendAuthenticationResponseEx(lRadio, &bar2Send);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8323 次 |
| 最近记录: |