繁体   English   中英

在Linux上的C blueZ中进行蓝牙配对

[英]Bluetooth pairing in C blueZ on Linux

在使用BlueZ蓝牙库以C语言编写的程序中,我找不到如何在Linux上配对蓝牙设备的任何参考。 我已经设法进行了HCI级别查询,以使设备与RSSI级别一起(在设备发现过程中),但是目前我对此感到困惑。 我看到了将DBUS api用于blueZ-simple-agent的建议-但是有什么方法可以避免这种情况,而只是使用BlueZ中的一些C级方法?

来自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);
}

您可以在此处下载源代码的最新版本: http : //www.bluez.org/那里有“ btmgmt”工具以及可用于配对的bluez-simple-agent。 代码全部在源代码中,并且还有一些文档(在docs文件夹中)。 也许您可以根据需要使用其中一种工具的代码,或者它可以帮助您理解配对。

我想首先将2台设备与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

现在,您可以从终端切换到tools文件夹,然后键入./btmgmt来查看如何使用它。 您也可以通过键入“ btmgmt”来安装它以使用它,而无论您身在何处。

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

您需要使用sudo权限才能使用它。

此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是蓝牙的进程ID

/ org / bluez / agent_1317是蓝牙配对代理。bluez/ test中作为agent.c出现的bluezagent可以用于此目的。

我曾经在C / C ++中玩过Bluez。 据我了解,BlueZ并不真正欢迎用户使用C / C ++接口,它确实更喜欢python。

因此,主要思想是查看目录/ tools中的BlueZ存储库,该目录在C中实现了一些必需的功能。

另外,您可以看一下这篇文章,该文章显示了从纯C语言使用BlueZ的一些可能性: https : //people.csail.mit.edu/albert/bluez-intro/c404.html

以下是我想出了(基于hcidump): https://github.com/IGR2014/Alsa-BlueZ-Example (灵感https://github.com/pauloborges/bluezHTTPS://git.kernel .org / pub / scm / bluetooth / bluez.git

连接功能可能实现的小示例:

// Connect to device
bool btCore::connect(const char* address) {

    std::cout << "Connecting to device\t" << address << " ..." << std::endl;
    std::cout << std::endl;

    uint16_t     handle;
    unsigned int ptype      = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5;

    char         addr[19]   = {0};

    bdaddr_t     bdaddr;

    str2ba(address, &bdaddr);

    // Open local HCI device
    int sk      = hci_open_dev(dev_id);
    if (sk < 0) {

        std::cerr << "HCI open device:\t\t" << strerror(errno) << std::endl;
        return false;

    }

    // Establish HCI connection with device
    if (hci_create_connection(sk, &bdaddr, htobs(ptype), 0, 0, &handle, 0) < 0) {

        std::cerr << "HCI create connection:\t" << strerror(errno) << std::endl;
        close(sk);
        return false;

    } else {

        std::cout << "Connection:\t\tOK" << std::endl;

    }

    // Authenticate HCI link (without pin)
    if (hci_authenticate_link(sk, handle, 0) < 0) {

        std::cerr << "HCI authenticate connection:\t" << strerror(errno) << std::endl;
        close(sk);
        return false;

    } else {

        std::cout << "Authentication:\t\tOK" << std::endl;

    }

    // Encrypt HCI link
    if (hci_encrypt_link(sk, handle, 1, 0) < 0) {

        std::cerr << "HCI encrypt connection:\t" << strerror(errno) << std::endl;
        close(sk);
                return false;

    } else {

        std::cout << "Encryption:\t\tOK" << std::endl;

    }

    close(sk);

    return true;

}

接下来要做的就是发现服务( https://www.bluetooth.com/specifications/assigned-numbers/service-discovery

这也是我的老问题,可能会导致您回答: Linux over BlueZ下的C ++蓝牙耳机

请注意:不能保证所有API(如果可以将这些内部函数命名为“ API”)都与其他版本的BlueZ相同。 至少,对于这种行为没有任何保证。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM