Мне нужно иметь возможность подключить устройство с помощью кода в C++ для Windows (в частности, win7 или newer). Я написал код, который должен работать, но это не так. Я могу объединить множество устройств, Roku, гарнитуру, динамики и т. Д., Но по какой-то причине устройство, которое мне нужно установить, не будет работать.Сопряжение устройства Bluetooth в окнах с C++
Он всегда возвращает код ошибки 0x05, который согласно bthdefs.h определяется как BTH_ERROR_AUTHENTICATION_FAILURE.
Так что странная часть здесь. Он никогда не пытается аутентифицироваться. Функция обратного вызова, которая должна быть вызвана для предоставления ключа доступа во время сопряжения, не вызывается. Я подтвердил, что он вызван с другими устройствами, такими как гарнитура.
Я пробовал использовать BluetoothAuthenticateDeviceEx() без функции обратного вызова, которая должна вывести GUI в окна, чтобы завершить сопряжение. Он появляется для моей гарнитуры и других устройств, он не появится для моего устройства.
В качестве побочного примечания я могу подключить устройство с помощью мастера Bluetooth-штекер просто отлично. Он просто отказывается работать программно.
Я не могу понять, какая разница между кодом winapi, который я использую, и с каким мастером окон работает при спаривании.
Вот простейшее тестовое приложение, которое я мог бы получить. Мое настоящее приложение использовало 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;
}
Спасибо за ответ. Показанный код был минимальным примером, и поэтому я не заботился об очистке ручек и тому подобное. Таким образом, для # 1 не имеет значения, что hCallbackHandle выходит из области видимости, поскольку выделенный дескриптор остается действительным до тех пор, пока не вызывается CloseHandle. 2. Снова не волнует память или что-то такое, что отменить регистрацию не вызывает беспокойства. 3. То же, что и 1/2 4. Функция пуста, но она никогда не вызывается. Не забывайте, что этот код работает со всеми другими устройствами Bluetooth, за исключением того, с которым я хотел работать. – ambershark
5. Я не совсем уверен, что это асинхронно.Он отлично работает с Bluetooth-гарнитурой и проигрывателем ROKU. Вызывается функция и используется основной поток, то есть синхронный. Поэтому я не думаю, что это работает так, как вы думаете. – ambershark
Пункт 4 является основным моментом imho. Это необходимо для 2.1 совместимых устройств, использующих SSP вместо 2.0 pincodes ... Возможно, это проблема ... – adanteny