【问题标题】:How to enumerate all Bluetooth services?如何枚举所有蓝牙服务?
【发布时间】:2022-11-06 21:42:18
【问题描述】:

我想获取任何蓝牙设备的可用蓝牙服务列表。

我从 Windows API 中找到了BluetoothEnumerateInstalledServices,但它只列举了已安装的服务。这样我得到了 3 个服务的列表,而不是 4 个。

如何获取蓝牙设备上所有服务的列表?

【问题讨论】:

  • 为什么是 c# 和 c++ 标签?您打算使用 c++/CLI 吗?
  • @MickyD因为c#或c++都没有关系。我将从 c# 调用 c++ 代码。来自 c# 或 c++ 解决方案的任何答案都是有效的。

标签: c# c++ windows bluetooth


【解决方案1】:

我找到了一种方法,但它没有提供完整的必要信息:

    #pragma comment(lib, "ws2_32.lib")
    #include <winsock2.h>
    #include <Ws2bth.h>
    #pragma comment(lib, "Bthprops.lib")
    #include <BluetoothAPIs.h>
    #include <stdio.h>
    #include <iostream>

    int main(int argc, char** argv)
    {
        WSADATA data;
        if (WSAStartup(0x0202, &data) != 0)
        {
            // Выход по ошибке
            printf("WSACleanup() failed with error code %ld
", WSAGetLastError());
            return 1;
        }
        #define BUF_SIZE 10240    
        WSAQUERYSET* pQuerySet = (WSAQUERYSET*) new BYTE[BUF_SIZE];
        ZeroMemory(pQuerySet, BUF_SIZE);
        pQuerySet->dwSize = sizeof(WSAQUERYSET);
        pQuerySet->dwNameSpace = NS_BTH;

        // Запускаем поиск устройств
        HANDLE lookupHandle = 0;
        int    lookupResult = WSALookupServiceBegin(pQuerySet,
            LUP_RETURN_NAME | LUP_CONTAINERS | LUP_RETURN_ADDR | LUP_FLUSHCACHE |
            LUP_RETURN_TYPE | LUP_RETURN_BLOB | LUP_RES_SERVICE,
            &lookupHandle);
        if (lookupResult != 0)
        {
            // Ошибка при инициализации поиска
            printf("WSALookupServiceBegin() failed with error code %ld
", WSAGetLastError());
        }
        else
        {
            printf("WSALookupServiceBegin() is OK
");       
        }

        while (lookupResult == 0)
        {
            DWORD  bufferLen = BUF_SIZE;

            lookupResult = WSALookupServiceNext(lookupHandle,
                LUP_RETURN_NAME | LUP_RETURN_ADDR,
                &bufferLen,
                pQuerySet);
            if (lookupResult != 0)
                break;
    
            DWORD addressLength = 128;
            char* addressString = new char[addressLength];

            int result = WSAAddressToString(pQuerySet->lpcsaBuffer->RemoteAddr.lpSockaddr,
                pQuerySet->lpcsaBuffer->RemoteAddr.iSockaddrLength,
                NULL,
                (LPWSTR)addressString,
                &addressLength);

            if (result != 0)
            {
                printf("
          WSAAddressToString() for remote address failed with error code %ld
", WSAGetLastError());
            }
            else {
                printf("MAC: ");
                printf("%S ", addressString);
                printf("Name: ");
                wprintf(pQuerySet->lpszServiceInstanceName);
                printf("
");        

                WSAQUERYSET* pQuerySetServices = (WSAQUERYSET*) new BYTE[BUF_SIZE];
                ZeroMemory(pQuerySetServices, BUF_SIZE);
                pQuerySetServices->dwSize = sizeof(WSAQUERYSET);
                pQuerySetServices->dwNameSpace = NS_BTH;
                pQuerySetServices->dwNumberOfCsAddrs = 0;
                pQuerySetServices->lpszContext = (LPWSTR)addressString;
                pQuerySetServices->lpServiceClassId = (GUID*)&L2CAP_PROTOCOL_UUID;

                HANDLE lookupServicesHandle = 0;
                int lookupServicesResult = WSALookupServiceBegin(pQuerySetServices, LUP_RETURN_NAME | LUP_RETURN_TYPE | LUP_RES_SERVICE | LUP_RETURN_ADDR | LUP_RETURN_BLOB | LUP_RETURN_COMMENT, &lookupServicesHandle);
                if (lookupServicesResult != 0)
                {
                    printf("WSALookupServiceBegin() failed with error code %ld
", WSAGetLastError());
                }
                else
                {
                    while (lookupServicesResult == 0)
                    {
                        DWORD  bufferLen = BUF_SIZE;

                        lookupServicesResult = WSALookupServiceNext(lookupServicesHandle,
                            LUP_RETURN_ALL,
                            &bufferLen,
                            pQuerySetServices);
                        if (lookupServicesResult != 0)
                            break;

                        GUID guid = *pQuerySetServices->lpServiceClassId;
                        OLECHAR* guidString;
                        StringFromCLSID(guid, &guidString);

                        printf("    ");
                        wprintf(guidString);
                        printf(" ");
                        wprintf(pQuerySetServices->lpszServiceInstanceName);
                        printf("
");
                    }
                    WSALookupServiceEnd(lookupServicesHandle);
                }
            }
        }

        WSALookupServiceEnd(lookupHandle);
        WSACleanup();
    }

输出:

    MAC: (00:1E:B5:8C:64:49) Name: Moga Pro HID
        {00000000-0000-0000-0000-000000000000}
        {00000000-0000-0000-0000-000000000000} Android Controller Gen-2(ACC)
    MAC: (30:39:26:FE:C8:62) Name: SBH20
        {00000000-0000-0000-0000-000000000000} Hands-Free unit
        {00000000-0000-0000-0000-000000000000} Headset
        {00000000-0000-0000-0000-000000000000}
        {00000000-0000-0000-0000-000000000000}
        {00000000-0000-0000-0000-000000000000}

此方法可以获得正确的服务计数,但 GUID 始终为空,并且某些服务没有可读的名称。

【讨论】:

    猜你喜欢
    • 2014-07-25
    • 2019-06-21
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多