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

时间:2013-10-16 00:34:10

标签: c++ winapi bluetooth serial-port

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

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

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;

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

我该怎么做?

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

关键: 的 HKEY_LOCAL_MACHINE \ SYSTEM \ CURRENTCONTROLSET \枚举\ BTHENUM 你可以找到一个子密钥,其中包含一个包含设备地址的密钥列表。

在最后一个密钥下,您可以找到名为设备参数的子项,该子项最终具有 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;
}