Search code examples
c++bluez

BlueZ - How to get number / list of available bluetooth adapters


How can I get a list of the available bluetooth adapters from BlueZ using C++? I'm specifically trying to use bluetooth/bluetooth.h, bluetooth/hci.h, as opposed to the DBUS API as I need to connect directly to the HCI sockets.

Ideally I want the number of adapters, their ids (e.g. hci0, hci1, etc), their addresses, etc.


Solution

  • I found an example of accomplishing this in the find_controllers function at bluez/tools/cltest.c which I've expanded below to include the address of the adapters

    #include <sys/socket.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/hci.h>
    #include <bluetooth/hci_lib.h>
    #include <iostream>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/ioctl.h>
    
    int main()
    {
        // Create a hci socket
        int hciSocket = hci_open_dev(hci_get_route(NULL));
        if (hciSocket < 0)
        {
            perror("Failed to open HCI device");
            return 1;
        }
    
        // Create int and pointers to hold results for later
        int devCount;
        struct hci_dev_list_req *devList;
        struct hci_dev_info devInfo;
    
        // Allocate memory for devList pointer. Based on HCI_MAX_DEV (maximum number of HCI devices) multiplied by the size of struct hci_dev_req, plus the size of uint16_t (to store the device number)
        devList = (struct hci_dev_list_req *)malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t));
        if (!devList)
        {
            perror("Failed to allocate HCI device request memory");
            close(hciSocket);
            return 1;
        }
    
        // Honestly not sure why we have to do this here?
        devList->dev_num = HCI_MAX_DEV;
    
        // Send the HCIGETDEVLIST command to get the device list.
        if (ioctl(hciSocket, HCIGETDEVLIST, (void *)devList) < 0)
        {
            perror("Failed to get HCI device list");
            free(devList);
            close(hciSocket);
            return 1;
        }
    
        // 
        devCount = devList->dev_num;
        std::cout << "Found " << devCount << " HCI devices" << std::endl;
    
        // Iterate over the devices and retrieve information
        for (int i = 0; i < devCount; i++) {
            // Set the device ID for device info retrieval
            devInfo.dev_id = devList->dev_req[i].dev_id;
            if (ioctl(hciSocket, HCIGETDEVINFO, (void *)&devInfo) < 0) {
                perror("Failed to get HCI device info");
                continue;
            }
    
            char addr[18];
            ba2str(&devInfo.bdaddr, addr);
    
            // Print device information
            std::cout << "HCI Device " << i + 1 << ":" << std::endl;
            std::cout << "  Address: " << addr << std::endl;
            std::cout << "  Dev ID: " << devInfo.dev_id << std::endl;
            std::cout << "  Flags: 0x" << std::hex << devInfo.flags << std::dec << std::endl;
            std::cout << "  Type: 0x" << std::hex << devInfo.type << std::dec << std::endl;
        }
    
        free(devList);
        close(hciSocket);
    
        return 0;
    }