Bluetooth Low Energy is an awesome technology. It enables us to connect to every day things that, say 10 years ago, think it would be crazy to do. (Thinking about connecting your phone to your shoes in the early 2000’s. Isn’t it weird?) I have no doubts that connected items will be ubiquitous with every day life. So, why not join the party?

During my initial foray into developing for Bluetooth Low Energy, I took some notes that I feel would benefit everyone. I use a Mac as my primary development platform but unfortunately the SDK is not as easy and open (and you need to rely on mostly closed source tools). Luckily Bluez, the Bluetooth stack for Linux is open source at easy to work with.

First, lets discuss the most important tools that are included with the Bluez stack.

Get Acquainted With The Tools


hcitool is the swiss army knife for Bluetooth in Linux. It is aptly named hcitool as it communicates via a common HCI (Host Controller Interface) port to your bluetooth devices. You can utilize the utility to scan for devices and send commands/data for standard Bluetooth and Bluetooth Low Energy.


gatttool is used to access the “services” running on your bluetooth device. In my case, it was instrumental in accessing the Bluetooth Low Energy services running on my nrf51822. The Bluetooth SIG has already spec’d out several services for general use. More information on these services can be found here.

Install The Tools

In order to use Bluez, I needed to install Linux on a virtual machine. If you need a helping hand installing Debian may I suggest this step-by-step guide?

  1. Get the latest Bluez source:


    Note: make sure you uninstall Bluez if it is already installed. (apt-get doesn’t have a very recent version) To check if it’s installed run this command:

    dpkg --get-selections | grep -v deinstall | grep bluez
  2. Extract the source

    tar xvf bluez-5.18.tar.xz
  3. Install dependencies

    sudo apt-get install libglib2.0-dev libdbus-1-dev libusb-dev libudev-dev libical-dev systemd libreadline-dev
  4. Run configure

    .configure --enable-library

    Note: –enable-library will enable use of the library so you can create your own applications utilizing the Bluez stack

  5. Compile and install the source

    make -j8 && sudo make install
  6. The install script does not copy gatttool to your /usr/local/bin/ directory. You must do it manually:

    sudo cp attrib/gatttool /usr/local/bin/

Scan For Bluetooth Low Energy Devices

After installing Bluez (and tools) lets see if we can find a Bluetooth Low Energy device.

Note: because my Mac does not have built in Bluetooth Low Energy I am using a cheap Bluetooth Low Energy dongle. These dongles can usually be picked up for around $8.

  1. Attach your Bluetooth device to your VM.

    Virtualbox Add BLTE Device

    Note: if you get a Failed to attach USB device error, you may need to create a device filter that will autoconnect. More information on creating a device filter here.

  2. Check if hcitool can see your device:

    hcitool dev

    My output looked like this:

            hci0    00:15:83:6B:CC:EB

    Note: if nothing shows up you may have to reinsert your Bluetooth dongle. (if you’re using one)

  3. Now, run a low energy scan

    sudo hcitool lescan

    If you device is advertising it should show up.

    F4:C7:F8:0A:BF:C9 TWI

    In my case, the device I’m using is call ‘TWI’ and its address is ‘F4:C7:F8:0A:BF:C9’

    Note: you need to make sure your BTLE device is advertising for it to show up.

Connect To Your Bluetooth Low Energy Device

Now that we can see the intended Bluetooth device let’s connect to it.

  1. Open gatttool

    sudo gatttool -b <BLE ADDRESS> -I

    Where <BLE ADDRESS> is the address you obtained in the earlier steps.

    -I indicates you want to open up an interactive session

  2. Once open, type connect to connect.

    Gatttool Connect

    Note: As long as your BTLE device is still advertising you should the address change to a purple color in the command prompt.

    If you get a connect: No route to host (113), that means the device is not advertising, you’ve used the wrong address or you haven’t run sudo hcitool lescan before opening gatttool.

  3. Get the primary UUIDs


    The command above will generate a list of all the available “services” running on the low energy device. This could give you an idea of what type of functionality the device has (if you have no idea how it works).

    An example output is:

    attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
    attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
    attr handle: 0x000c, end grp handle: 0xffff uuid: 0000180f-0000-1000-8000-00805f9b34fb
  4. Get all the available handles


    This command generates a list of all the available handles. Handles are the “connection points” where you can read and write access data. For instance, my device has a handle to access battery level data and another to enable automatic reporting of the battery level data.

    An example output is:

    handle: 0x0001, uuid: 2800
    handle: 0x0002, uuid: 2803
    handle: 0x0003, uuid: 2a00
    handle: 0x0004, uuid: 2803
    handle: 0x0005, uuid: 2a01
    handle: 0x0006, uuid: 2803
    handle: 0x0007, uuid: 2a04
    handle: 0x0008, uuid: 2800
    handle: 0x0009, uuid: 2803
    handle: 0x000a, uuid: 2a05
    handle: 0x000b, uuid: 2902
    handle: 0x000c, uuid: 2800
    handle: 0x000d, uuid: 2803
    handle: 0x000e, uuid: 2a19
    handle: 0x000f, uuid: 2902
    Discover descriptors finished: No attribute found within the given range

    Remember, a handle is a sequential number generated by Bluez which is tied to a specific characteristic. You can use the output of char-desc to relate the characteristic UUID to each open handle.

  5. Read from a handle

    In my case, I know that the handle for reading the battery level is 0x000e. The command to read a handle is as follows:

    char-read-hnd <handle>

    So, when I run char-read-hnd 0x0001 I get a response of:

    Characteristic value/descriptor: 64

    The result returned is a hexadecimal number which, when converted to decimal, is equal to 100. In this case, this number is the percent battery power left on the device according to the Battery Service definition.

  6. Write to a handle

    Now, for giggles, I want to enable notifications for my battery level. I know that, in my case, the handle to enable notifications is 0x000f. The command to write to a handle is as follows:

    char-write-req <handle> <data>

    So, when I run char-write-req 0x000f 0100 I start receiving battery level messages (if the level has changed) like the following:

    Characteristic value was written successfully
    Notification handle = 0x000e value: 64
    Notification handle = 0x000e value: 64
    Notification handle = 0x000e value: 64

    To disable, I simply run the following:

    char-write-req 0x000f 0000

Moving forward

We have only reached the tip of the iceberg in terms of information regarding Bluetooth (and Bluetooth Low Energy). Stay tuned for more Bluetooth Low Energy related posts in the future!

In the meantime subscribe below to my list if you haven’t already and i’ll see you on the next one!