2014-09-09 3 views
3

Мне нужно иметь возможность подключить устройство с помощью кода в 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

Возможно, вам следует добавить ответ в свой отзыв. Smth так:

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); 
3

Насколько я знаю, я вижу много проблем в вашем коде:

1) вы звоните BluetoothRegisterForAuthenticationEx в ваш призыв к «pairDevice»: переменная 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); 

(см.выше комментарий ;-)

5) ваш вызов «BluetoothAuthenticateDeviceEx» будет запускать процедуру обратного вызова асинхронно ..., поэтому вам нужно «подождать» для нее ... перед выходом из функции main() ...

+0

Спасибо за ответ. Показанный код был минимальным примером, и поэтому я не заботился об очистке ручек и тому подобное. Таким образом, для # 1 не имеет значения, что hCallbackHandle выходит из области видимости, поскольку выделенный дескриптор остается действительным до тех пор, пока не вызывается CloseHandle. 2. Снова не волнует память или что-то такое, что отменить регистрацию не вызывает беспокойства. 3. То же, что и 1/2 4. Функция пуста, но она никогда не вызывается. Не забывайте, что этот код работает со всеми другими устройствами Bluetooth, за исключением того, с которым я хотел работать. – ambershark

+0

5. Я не совсем уверен, что это асинхронно.Он отлично работает с Bluetooth-гарнитурой и проигрывателем ROKU. Вызывается функция и используется основной поток, то есть синхронный. Поэтому я не думаю, что это работает так, как вы думаете. – ambershark

+0

Пункт 4 является основным моментом imho. Это необходимо для 2.1 совместимых устройств, использующих SSP вместо 2.0 pincodes ... Возможно, это проблема ... – adanteny