1

如何找到具有特定设备名称的蓝牙设备的端口名称?

我有这段代码,它枚举了所有蓝牙设备,但没有给我它们的端口名称:

HBLUETOOTH_DEVICE_FIND founded_device;

BLUETOOTH_DEVICE_INFO device_info;
device_info.dwSize = sizeof(device_info);

BLUETOOTH_DEVICE_SEARCH_PARAMS search_criteria;
search_criteria.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
search_criteria.fReturnAuthenticated = TRUE;
search_criteria.fReturnRemembered = FALSE;
search_criteria.fReturnConnected = FALSE;
search_criteria.fReturnUnknown = FALSE;
search_criteria.fIssueInquiry = FALSE;
search_criteria.cTimeoutMultiplier = 0;

founded_device = BluetoothFindFirstDevice(&search_criteria, &device_info);

if(founded_device == NULL)
    return -1;

do {
    wstring ws = device_info.szName;
    cout << string(ws.begin(), ws.end()) << endl;

} while (BluetoothFindNextDevice(founded_device, &device_info));

然后我有这段代码,它枚举了所有端口名称,但没有给我设备名称:

DWORD bytesNeeded = 0;
DWORD portCount = 0;

BOOL ret = EnumPorts(nullptr, 2, nullptr, 0, &bytesNeeded, &portCount);

BYTE *ports = new BYTE[bytesNeeded];

if(EnumPorts(nullptr, 2, (LPBYTE)ports, bytesNeeded, &bytesNeeded, &portCount))
{
    PORT_INFO_2 *portInfo = (PORT_INFO_2*)ports;

    for(DWORD i = 0; i < portCount; ++i)
        cout << portInfo[i].pPortName << endl;
}

delete [] ports;

我需要在我的应用程序启动时自动连接到特定设备,所以我需要在第一段代码中获取蓝牙设备的端口名称以便我可以连接到它,或者检查第二段代码中的每个端口名代码以在连接之前确保它是正确的设备。

我该怎么做?

4

2 回答 2

1

我记得过去曾为此苦苦挣扎。我发现的唯一解决方案是使用套接字使用其地址与蓝牙设备进行通信,然后使用send()recv()方法与设备进行通信。

// assuming you have the BT device address in blueToothDeviceAddr;
char blueToothDeviceAddr[18];

SOCKET sock;
SOCKADDR_BTH sa = { 0,0,0,0 };
int sa_len = sizeof(sa);

// initialize windows sockets
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
if( WSAStartup( wVersionRequested, &wsaData ) != 0 ) 
{
    ExitProcess(100);
}

// parse the specified Bluetooth address

if( SOCKET_ERROR == WSAStringToAddress( blueToothDeviceAddr, AF_BTH, 
    NULL, (LPSOCKADDR) &sa, &sa_len ) ) 
{
        ExitProcess(101);
}

// query it for the right port

// create the socket
sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if( SOCKET_ERROR == sock ) 
{
    ExitProcess(102);
}

// fill in the rest of the SOCKADDR_BTH struct
GUID pService = (GUID)SerialPortServiceClass_UUID;
SOCKADDR_BTH outSA;
sa.port = SDPGetPort(blueToothDeviceAddr, (LPGUID) &pService,&outSA);
if( sa.port == 0 ) 
{
    ExitProcess(103);
}

// in case you have a pass code you need to register for authetication callback 
// look the web for this part

// connect to the device
if( SOCKET_ERROR == connect( sock, (LPSOCKADDR) &outSA, sa_len ) ) 
{
    int lastError = GetLastError();
    ExitProcess(105);
}
于 2013-10-16T03:02:05.627 回答
1

在键: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\BTHENUM 下,您可以找到一个子键,其中包含包含设备地址的键列表。

在最后一个键下,您可以找到一个名为Device Parameters的子键,它最终具有PortName值。

代码是用 C++ 编写的,带有 MFC 库,并在 Windows XP、7 和 10 下进行了测试。希望对您有所帮助!

// Returns the outgoing COM port of a bluetooth device given by address
int GetBluetoothCOM( CString sAddr )
{
    int iPort = 0;

    HKEY hKey_1;
    DWORD KeyNdx_1 = 0;
    DWORD MaxKeyLen_1;
    char KeyNam_1[ MAX_PATH + 1 ];
    LONG RetVal_1;

    sAddr.MakeUpper();
    sAddr.Replace( ":", "" );
    sAddr.Replace( " ", "" );

    // Enumerate keys under: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\BTHENUM
    RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Enum\\BTHENUM", NULL, KEY_READ | KEY_ENUMERATE_SUB_KEYS, &hKey_1 );

    while( true )
    {
        MaxKeyLen_1 = MAX_PATH;
        RetVal_1 = RegEnumKeyEx( hKey_1, KeyNdx_1, KeyNam_1, &MaxKeyLen_1, NULL, NULL, NULL, NULL );

        if( RetVal_1 == ERROR_NO_MORE_ITEMS )
        {
            break;
        }

        if( RetVal_1 == ERROR_SUCCESS )
        {
            HKEY hKey_2;
            DWORD KeyNdx_2 = 0;
            DWORD MaxKeyLen_2;
            char KeyNam_2[ MAX_PATH + 1 ];
            LONG RetVal_2;

            // Enumerate subkeys
            RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Enum\\BTHENUM\\" + CString( KeyNam_1 ), NULL, KEY_READ | KEY_ENUMERATE_SUB_KEYS, &hKey_2 );

            while( true )
            {
                MaxKeyLen_2 = MAX_PATH;
                RetVal_2 = RegEnumKeyEx( hKey_2, KeyNdx_2, KeyNam_2, &MaxKeyLen_2, NULL, NULL, NULL, NULL );

                if( RetVal_2 == ERROR_NO_MORE_ITEMS )
                {
                    break;
                }

                if( RetVal_2 == ERROR_SUCCESS )
                {
                    // Find out if the key name contains &ADDRESS_
                    CString sKey = "SYSTEM\\CurrentControlSet\\Enum\\BTHENUM\\" + CString( KeyNam_1 ) + "\\" + CString( KeyNam_2 );

                    sKey.MakeUpper();

                    if( sKey.Find( "&" + sAddr + "_" ) != -1 )
                    {
                        HKEY hKey;
                        char szPort[ 100 + 1 ];
                        DWORD dwLen = 100;

                        // I find out the device
                        RegOpenKeyEx( HKEY_LOCAL_MACHINE, sKey + "\\Device Parameters", 0, KEY_READ, &hKey );
                        if( RegQueryValueEx( hKey, "PortName", NULL, NULL, ( LPBYTE ) &szPort, &dwLen ) == ERROR_SUCCESS )
                        {
                            szPort[ dwLen ] = 0;
                            CString sPort = CString( szPort );

                            sPort.MakeUpper();

                            if( sPort.Find( "COM" ) == -1 )
                            {
                                RegCloseKey( hKey );
                                continue;
                            }

                            sPort.Replace( "COM", "" );
                            sPort.Trim();

                            iPort = atoi( sPort.GetBuffer() );

                            if( iPort != 0 )
                            {
                                RegCloseKey( hKey );
                                break;
                            }
                        }
                        RegCloseKey( hKey );
                    }
                }

                ++KeyNdx_2;
            }

            RegCloseKey( hKey_2 );

            if( iPort != 0 )
            {
                break;
            }
        }

        ++KeyNdx_1;
    };

    RegCloseKey( hKey_1 );

    return iPort;
}
于 2016-09-24T13:33:53.120 回答