16

BlueZ Bluetooth ライブラリを使用して C で記述されたプログラムで、Linux で Bluetooth デバイスをペアリングする方法に関する参照が見つかりません。HCI レベルのクエリを実行して、(デバイスの検出中に) RSSI レベルと共にデバイスを取得することはできましたが、現在はこれに固執しています。blueZ-simple-agent に DBUS API を使用するという提案を見ましたが、これを回避して BlueZ の C レベル メソッドを使用する方法はありますか?

4

4 に答える 4

6

認証コード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);
}
于 2014-09-26T22:06:05.170 に答える
1

C/C++ で Bluez をいじっていました。私が理解できる限り、BlueZ では C/C++ インターフェイスはユーザーにとってあまり歓迎されていません。Python の方が好まれます。

したがって、主なアイデアは、C で必要な機能の一部を実装しているディレクトリ /tools にある BlueZ リポジトリを確認することです。

また、プレーン 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 関数の可能な実装の小さな例:

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

また、ここにあなたが答えることができる私の古い質問があります:BlueZ上のLinuxでのC ++ Bluetoothヘッドフォン

注: すべての API (これらの内部関数を「API」と名付けることができる場合) は、他のバージョンの BlueZ と同じであるとは限りません。少なくとも、そのような動作の保証はありません。

于 2019-02-12T08:57:39.137 に答える
1

この 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 のプロセス ID です。

/org/bluez/agent_1317 は bluetooth ペアリング エージェントです。bluez/test の agent.c として提供される bluezagent をこの目的で使用できます。

于 2016-06-11T00:01:15.070 に答える