Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluetooth pairing in C blueZ on Linux

I cannot find any reference on how to pair a bluetooth device on linux in a program written in C using the BlueZ Bluetooth libraries. I already managed to do a HCI level query to get devices along with thier RSSI levels (during the device discovery) but currently I am stuck with this. I saw a suggestion to use the DBUS api for the blueZ-simple-agent - but is there any way to avoid this and just use some C level methods from BlueZ?

like image 918
okipol Avatar asked Feb 11 '13 20:02

okipol


People also ask

How do I connect a Bluetooth device to Linux?

To get a Bluetooth device working with Blueman, first click the Bluetooth icon in the system tray. Then, click the “search” button to search for a device. When a device appears, select it with the mouse, then click “setup”. The Blueman tool will take you through the pairing process.

Is BlueZ a Bluetooth package?

BlueZ is the official Linux Bluetooth stack.

How do I fix Bluetooth on Linux?

Make sure that your device is set up to allow connections. Your Bluetooth adapter or dongle may not have been recognized by the computer. This could be because drivers for the adapter are not installed. Some Bluetooth adapters are not supported on Linux, so you may not be able to get the right drivers for them.


2 Answers

Authentication code from hcitool (original source code can see at 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);
}

And setting up 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);
}
like image 73
disable13 Avatar answered Sep 20 '22 14:09

disable13


You can download the newest version of the source code here: http://www.bluez.org/ There ist the tool "btmgmt" and also the bluez-simple-agent that can be used for pairing. The code is all in the sources and there is also some documentation (in docs folder). Maybe you can use code of one of these tools for your desires or maybe it helps you understand the pairing.

I want to pair 2 device with the bluez bluetooth library in the first place but I happend to find helpful code in the source for the bluez-tools. There is the file "btmgmt.c" and some files that are include in it which implement the pairing.

For me unfortunately it is not working and I can't understand why. But maybe you have more success with it. Here is how you can test it.

If you haven't already, download the newest version of the source code here: http://www.bluez.org/ Extract it and open a terminal in the bluez folder.

Then run the following in the terminal:

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

I don't remember all packages you need to install but you can run this command and check why it fails, then install the package and rerun it till it works. Ask google if you don't know which package you need to install. Afterwards:

make

Now you can switch into tools folder from terminal and type ./btmgmt to see how to use it. You can also intall it to be able to use it by just typing "btmgmt" regardless of your location.

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

You need sudo rights to use it.

like image 42
progo Avatar answered Sep 18 '22 14:09

progo