簡體   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