Winsock 2发现仅显示先前已配对设备的蓝牙设备

时间:2018-12-19 01:21:01

标签: bluetooth device winsock

我目前正在尝试使用WINSOCK 2 API,以发现附近的可用蓝牙设备。我使用的代码基于here上的Microsoft示例。

我主要是使用WSALookupServiceNext来遍历可用设备。问题是我只得到以前配对的蓝牙设备的列表,而看不到其他任何设备。我添加了一些代码以打印设备信息:

*********************
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 :(得分:0)

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

您应该知道,由于某些蓝牙限制,只能在发现完成后才能执行名称解析。并且此操作可能需要时间。因此,如果您在发现完成后立即调用BluetoothGetDeviceInfo,您仍可以为新发现的设备(以前未发现的设备)获得空设备名称。

除了切换到WinRT API或等待一段时间才能读取设备名称外,没有简单的方法来解决此问题。您还可以使用WM_DEVICECHANGE消息获取有关设备名称解析的通知

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

还有一个问题:MS堆栈在发现期间始终返回配对的设备,即使它们不可用。