Соединение Bluetooth в C blueZ на Linux

Я не могу найти ссылку на то, как подключить Bluetooth-устройство к Linux в программе, написанной на C, используя библиотеки Bluetooth BlueZ. Мне уже удалось выполнить запрос уровня HCI для получения устройств вместе с уровнями RSSI (во время обнаружения устройства), но в настоящее время я застрял в этом. Я видел предложение использовать DBUS api для blueZ-simple-agent - но есть ли способ избежать этого и просто использовать некоторые методы уровня C из BlueZ?

Ответ 1

Действительно классная книга, которую я нашел здесь, помогла мне в этой области: http://people.csail.mit.edu/rudolph/Teaching/Articles/BTBook.pdf

У него есть примеры в c и python для настройки, спаривания и т.д. Я хотел попробовать и использовать его для запуска bluetooth classic (spp) connection на ipad, но не думаю, что у ядра есть то, что мне нужно.

Ответ 2

Код аутентификации из hcitool (исходный код можно увидеть на http://git.kernel.org/cgit/bluetooth/bluez.git/tree/tools/hcitool.c)

/* Request authentication */

static void cmd_auth(int dev_id, int argc, char **argv)
{
        struct hci_conn_info_req *cr;
        bdaddr_t bdaddr;
        int opt, dd;

        for_each_opt(opt, auth_options, NULL) {
            switch (opt) {
            default:
                printf("%s", auth_help);
                return;
            }
        }
        helper_arg(1, 1, &argc, &argv, auth_help);

        str2ba(argv[0], &bdaddr);

        if (dev_id < 0) {
            dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
            if (dev_id < 0) {
                fprintf(stderr, "Not connected.\n");
                exit(1);
            }
        }

        dd = hci_open_dev(dev_id);
        if (dd < 0) {
            perror("HCI device open failed");
            exit(1);
        }

        cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
        if (!cr) {
            perror("Can't allocate memory");
            exit(1);
        }

        bacpy(&cr->bdaddr, &bdaddr);
        cr->type = ACL_LINK;
        if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
            perror("Get connection info failed");
            exit(1);
        }

        if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) {
            perror("HCI authentication request failed");
            exit(1);
        }

        free(cr);

        hci_close_dev(dd);
}

И настройка PIN-кода

/* Activate encryption */

static void cmd_enc(int dev_id, int argc, char **argv)
{
    struct hci_conn_info_req *cr;
    bdaddr_t bdaddr;
    uint8_t encrypt;
    int opt, dd;

    for_each_opt(opt, enc_options, NULL) {
        switch (opt) {
        default:
            printf("%s", enc_help);
            return;
        }
    }
    helper_arg(1, 2, &argc, &argv, enc_help);

    str2ba(argv[0], &bdaddr);

    if (dev_id < 0) {
        dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr);
        if (dev_id < 0) {
            fprintf(stderr, "Not connected.\n");
            exit(1);
        }
    }

    dd = hci_open_dev(dev_id);
    if (dd < 0) {
        perror("HCI device open failed");
        exit(1);
    }

    cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
    if (!cr) {
        perror("Can't allocate memory");
        exit(1);
    }

    bacpy(&cr->bdaddr, &bdaddr);
    cr->type = ACL_LINK;
    if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
        perror("Get connection info failed");
        exit(1);
    }

    encrypt = (argc > 1) ? atoi(argv[1]) : 1;

    if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) {
        perror("HCI set encryption request failed");
        exit(1);
    }

    free(cr);

    hci_close_dev(dd);
}

Ответ 3

Вы можете скачать самую новую версию исходного кода здесь: http://www.bluez.org/ Существует инструмент "btmgmt", а также сине-простой агент, который может использоваться для спаривания. Код находится в источниках, а также имеется документация (в папке docs). Возможно, вы можете использовать код одного из этих инструментов для своих желаний или, может быть, это поможет вам понять спаривание.

Я хочу сначала установить пару с Bluetooth-библиотекой bluez, но я нашел полезный код в источнике для bluez-tools. Существует файл "btmgmt.c" и некоторые файлы, которые включены в него, которые реализуют сопряжение.

Для меня, к сожалению, это не работает, и я не понимаю, почему. Но, возможно, у вас больше успеха. Вот как вы можете протестировать его.

Если вы еще этого не сделали, загрузите самую новую версию исходного кода здесь: http://www.bluez.org/ Извлеките его и откройте терминал в папке bluez.

Затем запустите в терминале следующее:

./configure --prefix=/usr    \
        --sysconfdir=/etc    \
        --localstatedir=/var \
        --enable-tools       \
        --disable-test       \
        --disable-systemd

Я не помню все пакеты, которые вам нужно установить, но вы можете запустить эту команду и проверить, почему она не работает, а затем установить пакет и повторно запустить его до тех пор, пока он не будет работать. Спросите у Google, если вы не знаете, какой пакет вам нужно установить. После этого:

make

Теперь вы можете переключиться в папку инструментов с терминала и набрать. /btmgmt, чтобы узнать, как ее использовать. Вы также можете использовать его, чтобы использовать его, просто набрав "btmgmt" независимо от вашего местоположения.

sudo /usr/bin/install -c tools/btmgmt /usr/bin/btmgmt

Вам нужны права sudo для его использования.

Ответ 4

Эта команда dbus может использоваться для инициирования спаривания

 dbus-send --system --print-reply --dest=org.bluez /org/bluez/1301/hci0 org.bluez.Adapter.CreatePairedDevice string:"XX:XX:XX:XX:XX:XX" objpath:/org/bluez/agent_1317 string:"NoInputNoOutput"

Здесь 1301 - это идентификатор процесса bluetoothd

/org/bluez/agent_1317 является агентом сопряжения bluetooth. Для этой цели может использоваться синийзагент, который поступает как agent.c в bluez/test.