Bluetooth-Kopplung in C blueZ unter Linux

Lesezeit: 7 Minuten

Benutzer-Avatar
okipol

Ich kann keine Referenz zum Koppeln eines Bluetooth-Geräts unter Linux in einem in C geschriebenen Programm finden, das die BlueZ Bluetooth-Bibliotheken verwendet. Ich habe es bereits geschafft, eine Abfrage auf HCI-Ebene durchzuführen, um Geräte zusammen mit ihren RSSI-Ebenen zu erhalten (während der Geräteerkennung), aber derzeit stecke ich damit fest. Ich habe einen Vorschlag gesehen, die DBUS-API für den blueZ-Simple-Agent zu verwenden – aber gibt es eine Möglichkeit, dies zu vermeiden und einfach einige C-Level-Methoden von BlueZ zu verwenden?

  • Ein wirklich cooles Buch, das ich hier gefunden habe, hat mir in diesem Bereich geholfen: people.csail.mit.edu/rudolph/Teaching/Articles/BTBook.pdf Es enthält Beispiele in C und Python zum Einrichten, Koppeln usw. Ich wollte versuchen, damit eine klassische Bluetooth-Verbindung (spp) auf dem iPad zu starten, glaube aber nicht, dass der Kernel die Dinge hat, die ich brauche.

    Benutzer1638120

    6. Juni 2013 um 13:16 Uhr

  • Verwenden Sie bluetoothctl , das ab Bluez5 verfügbar ist, indem Sie einfach den Agenten aktivieren

    – asch

    11. September 2015 um 12:02 Uhr

  • Beantwortet eine ähnliche Frage hier: stackoverflow.com/questions/29767053/bluez-programming Es könnte Ihnen helfen!

    – Zimano

    5. Oktober 2015 um 22:20 Uhr


Authentifizierungscode von hcitool (ursprünglicher Quellcode siehe unter 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);
}

Und PIN einrichten

/* 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);
}

Benutzer-Avatar
progo

Sie können die neueste Version des Quellcodes hier herunterladen: http://www.bluez.org/
Es gibt das Tool „btmgmt“ und auch den bluez-simple-agent, der zum Pairing verwendet werden kann. Der Code befindet sich vollständig in den Quellen und es gibt auch einige Dokumentation (im Ordner docs). Vielleicht können Sie den Code eines dieser Tools für Ihre Wünsche verwenden oder vielleicht hilft es Ihnen, die Paarung zu verstehen.

Ich möchte zunächst 2 Geräte mit der Bluez-Bluetooth-Bibliothek koppeln, aber ich habe zufällig hilfreichen Code in der Quelle für die Bluez-Tools gefunden. Es gibt die Datei „btmgmt.c“ und einige darin enthaltene Dateien, die das Pairing implementieren.

Bei mir funktioniert es leider nicht und ich verstehe nicht warum. Aber vielleicht hast du damit mehr Erfolg. So können Sie es testen.

Falls noch nicht geschehen, laden Sie hier die neueste Version des Quellcodes herunter: http://www.bluez.org/
Extrahieren Sie es und öffnen Sie ein Terminal im bluez-Ordner.

Führen Sie dann im Terminal Folgendes aus:

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

Ich erinnere mich nicht an alle Pakete, die Sie installieren müssen, aber Sie können diesen Befehl ausführen und prüfen, warum er fehlschlägt, dann das Paket installieren und erneut ausführen, bis es funktioniert. Fragen Sie Google, wenn Sie nicht wissen, welches Paket Sie installieren müssen. Danach:

make

Jetzt können Sie vom Terminal in den Tools-Ordner wechseln und ./btmgmt eingeben, um zu sehen, wie man es benutzt. Sie können es auch installieren, um es verwenden zu können, indem Sie einfach “btmgmt” eingeben, unabhängig von Ihrem Standort.

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

Sie benötigen sudo-Rechte, um es zu verwenden.

Dieser dbus-Befehl kann verwendet werden, um das Pairing zu initiieren

 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"

Hier ist 1301 die Prozess-ID von bluetoothd

/org/bluez/agent_1317 ist der Bluetooth-Pairing-Agent. Der bluezagent, der als agent.c in bluez/test kommt, kann für diesen Zweck verwendet werden.

Benutzer-Avatar
IGR94

Früher habe ich mit Bluez in C/C++ herumgespielt. Soweit ich verstehen kann, ist die C/C++-Schnittstelle in BlueZ für Benutzer nicht wirklich willkommen, es bevorzugt Python.

Die Hauptidee ist also, einen Blick auf das BlueZ-Repo zu werfen, auf das Verzeichnis /tools, das einige der erforderlichen Funktionen in C implementiert.

Sie können sich auch diesen Artikel ansehen, der einige Möglichkeiten der BlueZ-Nutzung von einfachem C zeigt: https://people.csail.mit.edu/albert/bluez-intro/c404.html

Folgendes habe ich mir ausgedacht (basierend auf hcidump):
https://github.com/IGR2014/Alsa-BlueZ-Beispiel (inspiriert von https://github.com/pauloborges/bluez, https://git.kernel.org/pub/scm/bluetooth/bluez.git)

Kleines Beispiel einer möglichen Implementierung für die Connect-Funktion:

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

}

Als nächstes müssen Sie Dienste entdecken (https://www.bluetooth.com/specifications/assigned-numbers/service-discovery)

Auch hier ist meine alte Frage, die Sie zur Beantwortung führen kann: C++ Bluetooth-Kopfhörer unter Linux über BlueZ

Bitte beachten Sie: Es ist nicht garantiert, dass die gesamte API (wenn wir diese internen Funktionen “API” nennen können) für andere Versionen von BlueZ gleich ist. Zumindest gibt es keine Garantie für ein solches Verhalten.

1042900cookie-checkBluetooth-Kopplung in C blueZ unter Linux

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy