Winsock 2 обнаруживает устройства Bluetooth, на которых отображаются только ранее сопряженные устройства - PullRequest
0 голосов
/ 19 декабря 2018

В настоящее время я пытаюсь использовать WINSOCK 2 API для обнаружения доступных устройств Bluetooth поблизости.Я использую код, основанный на примере Microsoft, который можно найти здесь .

Я в основном использую WSALookupServiceNext для перебора всех доступных устройств.Проблема в том, что я получаю только список предыдущих сопряженных устройств Bluetooth, и я не вижу никаких других устройств.Я добавил некоторый код для печати информации об устройстве:

*********************
Winsock search started!
*********************

Device #:1
Device name:MagicBox II
Device connected: 0
Device remembered: 1
Device authenticated: 1
Remote Bluetooth device is 0x00025b3dc371, server channel = 0
Local Bluetooth device is 0x84ef18b8460a, server channel = 0
Device #:2
Device name:Mpow Flame
Device connected: 0
Device remembered: 1
Device authenticated: 1
Remote Bluetooth device is 0x501801101c68, server channel = 0
Local Bluetooth device is 0x84ef18b8460a, server channel = 0
Device #:3
Device name:WH-1000XM2
Device connected: 0
Device remembered: 1
Device authenticated: 1
Remote Bluetooth device is 0x702605aba41d, server channel = 0
Local Bluetooth device is 0x84ef18b8460a, server channel = 0
Device #:4
Device name:Magicbuds
Device connected: 0
Device remembered: 1
Device authenticated: 1
Remote Bluetooth device is 0x5017032a701b, server channel = 0
Local Bluetooth device is 0x84ef18b8460a, server channel = 0

Вот соответствующий раздел кода (я заранее вызывал WSAStartup):

void WSALookupAvailableDevices(void)
{
    WSAQUERYSET     wsaQuery{};
    LPWSAQUERYSET   pwsaResults{};
    HANDLE          hLookup{};

    CSADDR_INFO     *pAddrInfo{};
    SOCKADDR_BTH    *pBtSockRemote{}, 
                    *pBtSockLocal{};

    char    buffer[4096] = {};
    int     nDevicesFound = 1;
    DWORD   swSize = sizeof(buffer);
    DWORD   flags = LUP_RETURN_ADDR | LUP_RETURN_NAME | LUP_RES_SERVICE | LUP_CONTAINERS | LUP_RETURN_BLOB | LUP_RETURN_TYPE;

    /*Preparing the query set*/
    wsaQuery.dwNameSpace = NS_BTH;
    wsaQuery.dwSize = sizeof(WSAQUERYSET);


    if (WSALookupServiceBegin(&wsaQuery, flags, &hLookup) == SOCKET_ERROR)
    {
        wprintf(L"Shit something went wrong! error: %d!\n", WSAGetLastError());
        return;
    }

    wprintf(L"*********************\n");
    wprintf(L"Winsock search started!\n");
    wprintf(L"*********************\n\n");


    /*Preparing the queryset return buffer*/
    pwsaResults = (LPWSAQUERYSET)buffer;
    pwsaResults->dwNameSpace = NS_BTH;
    pwsaResults->dwSize = sizeof(WSAQUERYSET);

    while (WSALookupServiceNext(hLookup, flags, &swSize, pwsaResults) == NO_ERROR)
    {
        pAddrInfo       = (CSADDR_INFO*)pwsaResults->lpcsaBuffer;
        pBtSockRemote   = (SOCKADDR_BTH*)(pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr);
        pBtSockLocal    = (SOCKADDR_BTH*)(pwsaResults->lpcsaBuffer->LocalAddr.lpSockaddr);

        wprintf(L"Device #:%d\n", nDevicesFound);
        wprintf(L"Device name:%s\n", pwsaResults->lpszServiceInstanceName);
        wprintf(L"Device connected: %d\n", (pwsaResults->dwOutputFlags & BTHNS_RESULT_DEVICE_CONNECTED));
        wprintf(L"Device remembered: %d\n", (pwsaResults->dwOutputFlags & BTHNS_RESULT_DEVICE_REMEMBERED)>0);
        wprintf(L"Device authenticated: %d\n", (pwsaResults->dwOutputFlags & BTHNS_RESULT_DEVICE_AUTHENTICATED)>0);
        wprintf(L"Remote Bluetooth device is 0x%04x%08x, server channel = %d\n",
            GET_NAP(pBtSockRemote->btAddr), GET_SAP(pBtSockRemote->btAddr), pBtSockRemote->port);
        wprintf(L"Local Bluetooth device is 0x%04x%08x, server channel = %d\n",
            GET_NAP(pBtSockLocal->btAddr), GET_SAP(pBtSockLocal->btAddr), pBtSockLocal->port);

        nDevicesFound++;

    }
    WSALookupServiceEnd(hLookup);
    wprintf(L"\n");
}

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 19 декабря 2018

LUP_FLUSHCACHE - это то, что вам нужно.И да, он всегда вернет сопряженное устройство (в дополнение к обнаруженному).Я имею в виду, что если устройство, сопряженное с WSALookup, возвращает его в список, даже если оно недоступно (выключено или находится вне диапазона).

https://docs.microsoft.com/en-us/windows/desktop/bluetooth/bluetooth-and-wsalookupservicebegin-for-device-inquiry

DWORD   flags = LUP_RETURN_ADDR | LUP_RETURN_NAME | LUP_RES_SERVICE | LUP_CONTAINERS | LUP_RETURN_BLOB | LUP_RETURN_TYPE | LUP_FLUSHCACHE;

Но лучший способ обнаружитьУстройства должны использовать этот набор флагов.

DWORD   flags = LUP_RETURN_ADDR | LUP_CONTAINERS | LUP_FLUSHCACHE;

Также рекомендуется предоставить дополнительную информацию (BTH_QUERY_DEVICE), чтобы вы могли установить таймаут обнаружения и другие параметры

BTH_QUERY_DEVICE qDev;
qDev.LAP = 0;
qDev.length = bTimeout; // Timeout in seconds
BLOB Blb;
Blb.cbSize = sizeof(BTH_QUERY_DEVICE);
Blb.pBlobData = (PBYTE)&qDev;
QuerySet.lpBlob = &Blb;

https://docs.microsoft.com/th-th/windows/desktop/api/ws2bth/ns-ws2bth-_bth_query_device

После обнаружения завершения (обратите внимание, что WSALookupServiceBegin занимает некоторое время (блоки) до обнаружения завершения), вы можете использовать BluetoothGetDeviceInfo для получения расширенной информации, такой как имя устройства и другая информация.

https://docs.microsoft.com/en-us/windows/desktop/api/bluetoothapis/nf-bluetoothapis-bluetoothgetdeviceinfo

Вы должны знать, что из-за некоторых ограничений Bluetooth разрешение имен может быть выполнено только после того, как обнаружение завершено.И эта операция может занять время.Поэтому, если вы позвоните в BluetoothGetDeviceInfo сразу после того, как обнаружение завершено, вы все равно можете получить пустое имя устройства для новых обнаруженных устройств (устройств, которые не были обнаружены ранее).

Не существует простого способа решить эту проблему, кроме перехода на WinRT APIили подождите некоторое время, прежде чем читать имя устройства.Вы также можете использовать сообщение WM_DEVICECHANGE, чтобы получить уведомление о разрешении имени устройства

https://docs.microsoft.com/en-us/windows/desktop/bluetooth/bluetooth-and-wm-devicechange-messages

И есть еще одна проблема: стек MS всегда возвращает спаренные устройства во время обнаружения, даже если они недоступны.

...