【问题标题】:Winsock 2 discovering Bluetooth devices only showing previously paired devicesWinsock 2 发现蓝牙设备只显示以前配对的设备
【发布时间】:2019-05-19 11:30:37
【问题描述】:

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

我主要使用 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");
}

提前感谢您的帮助!

【问题讨论】:

  • 如果您将flags 的用法更改为将 LUP_CONTAINERS 传递给WSALookupServiceBegin(),并从@987654328 中省略LUP_CONTAINERS,您是否也会遇到同样的问题@?
  • 是的,在更改 WSALookupServiceBegin()' flags to LUP_CONTAINERS` 并为 WSALookupServiceNext() 省略它之后,问题仍然存在。
  • 在您提供 LUP_FLUSHCACHE 标志之前并不重要,该标志表示驱动程序正在执行可爱发现。任何其他标志只会更改返回的信息集。是的,您不需要 LUP_RES_SERVICE(它从远程设备查询服务)。最好稍后再读取设备名称,因为 MS 堆栈会在发现完成后稍后解析设备名称。对于名称,最好使用 WM_DEVICECHANGE 消息来确保您获得设备的名称。但是,这取决于要求,但对于刚找到的新设备,名称将在 99% 中显示为空。

标签: bluetooth device winsock


【解决方案1】:

LUP_FLUSCHACHE 是您所需要的。是的,它总是会返回配对的设备(除了发现的)。我的意思是,如果设备配对 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 stack 在发现过程中总是返回配对的设备,即使它们不可用。

【讨论】:

  • LUP_FLUSHCACHE 确实回答了您的问题。 (docs.microsoft.com/en-us/windows/desktop/bluetooth/…) 看来您没有阅读答案,只是在查找已知单词。
  • 所以我将WSALookupServiceBegin()flags 更改为仅LUP_CONTAINERS,并将LUP_FLUSHCACHE 添加到WSALookupServiceNext()flags。除了已经配对的设备之外,我仍然没有看到任何设备的问题。
  • 看来您没有点击链接。有很多有用的信息。尤其是关于旗帜。您需要 LUP_CONTAINERS - 查询设备,LUP_FLUSHCACHE - 执行发现而不是返回刚刚配对的其他标志之一以获取有关设备的信息:LUP_RETURN_ADDR 或 LUP_RETURN_BLOB
  • 当然,必须为执行调用信息的 WSALookupServiceBegin 设置 LUP_FLUSHCACHE 标志。 WSALookupServiceNext 只遍历已经调用的列表,实际上在内部什么都不做。所以只有 LUP_CONTAINERS 你得到了只有配对设备的列表/
  • 好的,所以我用不同的蓝牙设备(三星平板电脑)进行了测试,它现在出现了,但前提是我明确设置它对附近的设备可见。这总是需要吗?我假设如果我例如打开我手机的BT,我就可以看到它,而无需进入设置和更改可见性。
猜你喜欢
  • 1970-01-01
  • 2012-04-19
  • 2016-09-26
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 2017-03-17
  • 2011-05-12
  • 1970-01-01
相关资源
最近更新 更多