Thursday, March 23, 2017

Hack for changing Min and Max connection interval for Bluez stack using kernel interface .

I tried this on Raspberry Pi(RPI) setup.  I configured Bluez as a LE peripheral . by default Bluez keeps Min connection interval as approximately 60ms and max as 80ms which is pretty high, as a result BLE throughput I was getting was very less (~= 28kbps).

Bluez does not provide any API to change connection interval when Bluez is acting in peripheral role.So for experimental purpose I figured out a way to change min and max connection interval . Bluez provides sys debug interface to change these parameters . here is the method to do that:

1) browse through /sys/kernel directory.
pi@raspberrypi:/sys/kernel $ ls -la
total 0
drwxr-xr-x  8 root root    0 Jan  1  1970 .
dr-xr-xr-x 12 root root    0 Jan  1  1970 ..
drwxr-xr-x  3 root root    0 Jan  1  1970 config
drwx------ 24 root root    0 Jan  1  1970 debug
drwxr-xr-x  2 root root    0 Mar 23 22:32 fscache
-r--r--r--  1 root root 4096 Mar 23 22:32 fscaps
drwxr-xr-x  2 root root    0 Jan  1  1970 mm
-r--r--r--  1 root root   36 Mar 23 22:32 notes
-rw-r--r--  1 root root 4096 Mar 23 22:32 profiling
-rw-r--r--  1 root root 4096 Mar 23 22:32 rcu_expedited
drwxr-xr-x 81 root root    0 Mar 23 00:04 slab
dr-xr-xr-x  2 root root    0 Mar 23 22:32 tracing
-rw-r--r--  1 root root 4096 Mar 23 22:32 uevent_helper
-r--r--r--  1 root root 4096 Mar 23 22:32 uevent_seqnum



2) RPI does not let you access debug folder without root permission.
pi@raspberrypi:/sys/kernel $ cd debug/
bash: cd: debug/: Permission denied

So change made for debug folder as follows

pi@raspberrypi:/sys/kernel $ sudo chmod 777  debug/

3) browse debug folder :
pi@raspberrypi:/sys/kernel $ cd debug/

pi@raspberrypi:/sys/kernel/debug/bluetooth/hci0 $ ls
adv_channel_map             features                       remote_oob
adv_max_interval            force_static_address           rpa_timeout
adv_min_interval            hardware_error                 sc_only_mode
auto_accept_delay           hci_revision                   sniff_max_interval
blacklist                   hci_version                    sniff_min_interval
conn_info_max_age           identity                       ssp_debug_mode
conn_info_min_age           identity_resolving_keys        static_address
conn_latency                idle_timeout                   supervision_timeout
conn_max_interval           inquiry_cache                  use_debug_keys
conn_min_interval           link_keys                      uuids
dev_class                   long_term_keys                 voice_setting
device_id                   manufacturer                   white_list
device_list                 quirk_simultaneous_discovery   white_list_size
discov_interleaved_timeout  quirk_strict_duplicate_filter
dut_mode                    random_address



4) Now change conn_max_interval and conn_max_interval parameters as follows:

pi@raspberrypi:/sys/kernel/debug/bluetooth/hci0 $ echo 6  > conn_min_interval

pi@raspberrypi:/sys/kernel/debug/bluetooth/hci0 $ echo 12  > conn_max_interval


after these modifications whatver central device your RPI connects to it would get allocated connection interval between the range of (6* 1.25ms ) to (12 * 1.25ms).

Hack for changing connection interval on bluez peripheral !!

In BlueZ  – to enforce a Connection Interval edit a file that is located in  /var/lib/bluetooth/[ADAPTER]/[DEVICE]/info  where [ADAPTER] and [DEVICE] is the bluetooth adapter address and device address bluez is connected to respectively and  and restart bluetoothd. Add the following lines:
Tune MinInterval and MaxInterval as per your  peripheral needs.

Monday, March 20, 2017

How to set connection parameters on Central device on bluez?

Here is the code snippet which will send connection parameters update request:

static void UpdateConnParams(uint16_t handle ,uint16_t min, uint16_t max )
{
    int dev_id = -1;
    uint16_t  latency, timeout;
    int dd;
    printf("\n Connection Parameters update !!");

    latency = 0x0007;
    timeout = 0x0C80;

    if (dev_id < 0)
        dev_id = hci_get_route(NULL);

    dd = hci_open_dev(dev_id);
    if (dd < 0) {
        fprintf(stderr, "HCI device open failed\n");
        exit(1);
    }

    if (hci_le_conn_update(dd, htobs(handle), htobs(min), htobs(max),
                htobs(latency), htobs(timeout), 5000) < 0) {
        int err = -errno;
        fprintf(stderr, "Could not change connection params: %s(%d)\n",
                            strerror(-err), -err);
    }

    hci_close_dev(dd);
}