Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux上C blueZ中的蓝牙配对_C_Linux_Bluetooth_Bluez - Fatal编程技术网

Linux上C blueZ中的蓝牙配对

Linux上C blueZ中的蓝牙配对,c,linux,bluetooth,bluez,C,Linux,Bluetooth,Bluez,我找不到任何关于如何在使用BlueZ bluetooth库的C语言编写的程序中在linux上配对蓝牙设备的参考资料。我已经设法做了一个HCI级别的查询,以获得具有更高RSSI级别的设备(在设备发现过程中),但目前我仍无法做到这一点。我看到一个建议,建议在blueZ simple agent中使用DBUS api,但是有没有办法避免这种情况,只使用blueZ中的一些C级方法?您可以在这里下载最新版本的源代码: 这里有一个工具“btmgmt”,还有一个可以用于配对的bluez简单代理。代码都在源代码

我找不到任何关于如何在使用BlueZ bluetooth库的C语言编写的程序中在linux上配对蓝牙设备的参考资料。我已经设法做了一个HCI级别的查询,以获得具有更高RSSI级别的设备(在设备发现过程中),但目前我仍无法做到这一点。我看到一个建议,建议在blueZ simple agent中使用DBUS api,但是有没有办法避免这种情况,只使用blueZ中的一些C级方法?

您可以在这里下载最新版本的源代码: 这里有一个工具“btmgmt”,还有一个可以用于配对的bluez简单代理。代码都在源代码中,还有一些文档(在docs文件夹中)。也许你可以根据自己的愿望使用其中一个工具的代码,或者它可以帮助你理解配对

首先,我想将2设备与bluez蓝牙库配对,但我碰巧在bluez工具的源代码中找到了有用的代码。 有文件“btmgmt.c”和其中包含的一些实现配对的文件

对我来说,不幸的是,它不起作用,我不明白为什么。但也许你会更成功。下面是如何测试它的

如果尚未下载,请在此处下载最新版本的源代码: 解压缩它并在bluez文件夹中打开一个终端

然后在终端中运行以下操作:

./configure --prefix=/usr    \
        --sysconfdir=/etc    \
        --localstatedir=/var \
        --enable-tools       \
        --disable-test       \
        --disable-systemd
我不记得您需要安装的所有软件包,但您可以运行此命令并检查失败原因,然后安装软件包并重新运行,直到它正常工作。如果您不知道需要安装哪个软件包,请询问谷歌。 之后:

make
现在,您可以从terminal切换到tools文件夹并键入./btmgmt以查看如何使用它。 您也可以通过键入“btmgmt”来安装它,以便在任何位置都可以使用它

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

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

来自
hcitool
的身份验证代码(原始源代码可参见)

/*请求身份验证*/
静态void cmd_auth(int dev_id,int argc,char**argv)
{
结构hci连接信息请求*cr;
bdaddr_t bdaddr;
int-opt,dd;
对于每个选项(选项、验证选项、空){
开关(opt){
违约:
printf(“%s”,身份验证帮助);
返回;
}
}
helper_arg(1,1,&argc,&argv,auth_help);
str2ba(argv[0],&bdaddr);
if(dev_id<0){
dev_id=每个dev的hci_(hci_UP,find_conn,(long)和bdaddr);
if(dev_id<0){
fprintf(stderr,“未连接”。\n”);
出口(1);
}
}
dd=hci_打开_开发(开发id);
if(dd<0){
perror(“HCI设备打开失败”);
出口(1);
}
cr=malloc(sizeof(*cr)+sizeof(struct hci_conn_info));
if(!cr){
perror(“无法分配内存”);
出口(1);
}
bacpy(&cr->bdaddr,&bdaddr);
cr->type=ACL\U链接;
if(ioctl(dd,HCIGETCONNINFO,(无符号长)cr)<0){
perror(“获取连接信息失败”);
出口(1);
}
如果(hci\U认证\U链接(dd,htobs(cr->conn\U info->handle),25000)<0){
perror(“HCI身份验证请求失败”);
出口(1);
}
免费(cr);
hci_关闭_开发(dd);
}
和设置销

/* 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);
}
/*激活加密*/
静态void cmd_enc(int dev_id,int argc,char**argv)
{
结构hci连接信息请求*cr;
bdaddr_t bdaddr;
uint8_t加密;
int-opt,dd;
对于每个选项(选项、附件选项、空){
开关(opt){
违约:
printf(“%s”,附件帮助);
返回;
}
}
helper_arg(1、2和argc、argv、enc_help);
str2ba(argv[0],&bdaddr);
if(dev_id<0){
dev_id=每个dev的hci_(hci_UP,find_conn,(long)和bdaddr);
if(dev_id<0){
fprintf(stderr,“未连接”。\n”);
出口(1);
}
}
dd=hci_打开_开发(开发id);
if(dd<0){
perror(“HCI设备打开失败”);
出口(1);
}
cr=malloc(sizeof(*cr)+sizeof(struct hci_conn_info));
if(!cr){
perror(“无法分配内存”);
出口(1);
}
bacpy(&cr->bdaddr,&bdaddr);
cr->type=ACL\U链接;
if(ioctl(dd,HCIGETCONNINFO,(无符号长)cr)<0){
perror(“获取连接信息失败”);
出口(1);
}
encrypt=(argc>1)?atoi(argv[1]):1;
如果(hci\U加密链接(dd,htobs(cr->conn\U info->handle),加密,25000)<0){
perror(“HCI设置加密请求失败”);
出口(1);
}
免费(cr);
hci_关闭_开发(dd);
}

此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是Bluetooth的进程id


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

我曾在c/c++中使用bluez。据我所知,在BlueZ中,C/C++接口并不真正受用户欢迎,它更喜欢python

因此,主要的想法是看一下bluezrepo,它在C中实现了一些必需的特性

另外,您还可以看看这篇文章,它展示了从普通C使用BlueZ的一些可能性:

以下是我的想法(基于hcidump): (灵感来自,)

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

// 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;

}
//连接到设备
bool btCore::connect(常量字符*地址){

std::cout我在这里找到的一本非常酷的书在这方面帮助了我:它有c和python中的设置、配对等示例。我想尝试使用它来启动一个bluetooth classic(spp)连接在ipad上,但不要认为内核有我需要的东西。使用bluetoothctl,它从Bluez5开始就可以使用,在这一点上,make代理OnAn回答了一个类似的问题:它可能会帮助你!
// 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;

}