The birth of GattLib - Solving BLE GATT access on Long Term supported Linux distributions by Olivier on 28/04/2016 14:03

Problematic

In one of our projects we had to communicate with BLE (Bluetooth Low Energy) devices. After some early investigations we highlighted two issues:

C GATT Library

We know GATT libraries exist in other languages (eg: pygattlib for python, bluepy) but impossible to find one in C!

GATT protocol did not seem to be supported by libbluetooth:

$ mkdir /tmp/libbluetooth-dev && cd /tmp/libbluetooth-dev
$ wget http://es.archive.ubuntu.com/ubuntu/pool/main/b/bluez/libbluetooth-dev_4.101-0ubuntu13_amd64.deb
$ sudo dpkg -x libbluetooth-dev_4.101-0ubuntu13_amd64.deb
$ grep -r gatt ./usr
$

Our project being mainly built in C we were not really considering to rewrite it into another language to only use an existing GATT library.

Bluez v4.x Support

The 'new' Bluez D-BUS API that enables any user space application to communicate with Bluetooth devices through D-BUS is only supported in the latest Bluez v5.x releases. The Bluez D-BUS API is still receiving many bug fixes - we recently contributed a fix for it.
Unfortunately, few LTS (Long Term Support) Linux distributions still use Bluez v4.x - including Ubuntu 14.04 LTS that only support Bluez v4.x. Ubuntu 14.04 LTS is still supported until 2019! Either we do not support a widely available Linux distribution (including my own development machine!) or we find the solution to our issue...

Funnily enough I discovered the day we started our investigation that the day after would have been released the new Ubuntu 16.04 LTS. So I could have potentially go to the beach for a day and upgrade my Ubuntu machine the day after with the new LTS and Bluez v5.x and its D-BUS API.
But looking at different discussion threads on Internet I realized that there was a real gap. We had the mission to fix it!

Investigation

During my initial investigation, I found that the only way to use Bluez GATT support was to manually pickup the files used by BlueZ gatttool and to call the GATT functions in the way gatttool is doing.
Obviously as many Open Source project no documentation - the documentation is the source code...
After losing few hairs while trying to understand the almost non commented source code and thinking few times I would lose my time with this new project. I decided to start slowly and see if I could isolate the source files and build gatttool into its own project directory.

  1. The initial step was to retrieve the latest stable version of Bluez v4.x (ie: v4.101 - actually the same version used by Ubuntu 14.04).

  2. From the Bluez Makefile.tools, I could already see the required files and libraries used by gatttool:

    attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \
                                    attrib/gattrib.c btio/btio.c \
                                    attrib/gatttool.h attrib/interactive.c \
                                    attrib/utils.c src/log.c
    attrib_gatttool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@ @READLINE_LIBS@
    

    I also wanted to see the Bluez build command lines to avoid missing any build arguments.

  3. Build gatttool
    The following dependencies are required: automake, libtool, libdbus-1-dev, libreadline-dev

    git clone git://git.kernel.org/pub/scm/bluetooth/bluez.git
    cd bluez
    git checkout 4.101
    ./bootstrap-configure
    make V=1 attrib/gatttool
    

    Finally, ensure the application runs ./attrib/gatttool

Create GattLib library

  1. Isolate gatttool in its own project and create a CMake file to build the new project.

    We should have this following tree:

    ├── bluez
    │   ├── attrib
    │   │   ├── att.c
    │   │   ├── att.h
    │   │   ├── gatt.c
    │   │   ├── gatt.h
    │   │   ├── gattrib.c
    │   │   ├── gattrib.h
    │   │   ├── gatttool.c
    │   │   ├── gatttool.h
    │   │   ├── interactive.c
    │   │   └── utils.c
    │   ├── btio
    │   │   ├── btio.c
    │   │   └── btio.h
    │   └── src
    │       ├── log.c
    │       └── log.h
    └── CMakeLists.txt
    
  2. If we build this project:

    mkdir build && cd build
    cmake .. && make
    

    We have some expected linking issues because gatttool depends on lib/libbluetooth-private.la:

    Linking C executable gatttool
    /usr/bin/cmake -E cmake_link_script CMakeFiles/gatttool.dir/link.txt --verbose=1
    /usr/bin/cc      CMakeFiles/gatttool.dir/bluez/attrib/att.c.o CMakeFiles/gatttool.dir/bluez/attrib/gatt.c.o CMakeFiles/gatttool.dir/bluez/attrib/gattrib.c.o CMakeFiles/gatttool.dir/bluez/attrib/gatttool.c.o CMakeFiles/gatttool.dir/bluez/attrib/interactive.c.o CMakeFiles/gatttool.dir/bluez/attrib/utils.c.o CMakeFiles/gatttool.dir/bluez/btio/btio.c.o CMakeFiles/gatttool.dir/bluez/src/log.c.o  -o gatttool -rdynamic -lglib-2.0 
    CMakeFiles/gatttool.dir/bluez/attrib/att.c.o: In function `att_get_uuid16':
    att.c:(.text+0x1e5): undefined reference to `bt_uuid16_create'
    CMakeFiles/gatttool.dir/bluez/attrib/att.c.o: In function `att_get_uuid128':
    att.c:(.text+0x263): undefined reference to `bt_uuid128_create'
    CMakeFiles/gatttool.dir/bluez/attrib/gatt.c.o: In function `sdp_get_service_classes':
    gatt.c:(.text+0x8d): undefined reference to `sdp_get_uuidseq_attr'
    CMakeFiles/gatttool.dir/bluez/attrib/gatt.c.o: In function `att_get_uuid16':
    gatt.c:(.text+0x140): undefined reference to `bt_uuid16_create'
    CMakeFiles/gatttool.dir/bluez/attrib/gatt.c.o: In function `att_get_uuid128':
    gatt.c:(.text+0x1be): undefined reference to `bt_uuid128_create'
    CMakeFiles/gatttool.dir/bluez/attrib/gatt.c.o: In function `encode_discover_primary':
    gatt.c:(.text+0x2bc): undefined reference to `bt_uuid16_create'
    CMakeFiles/gatttool.dir/bluez/attrib/gatt.c.o: In function `primary_all_cb':
    

    lib/libbluetooth-private.la uses lib/bluetooth.c, lib/hci.c, lib/sdp.c, lib/uuid.c (see Bluez Makefile.am). Let's add these files to the project.

    After adding this file, I managed to build gatttool. The next step was to separate gatttool from the GATT code to isolate what was gatttool specific and what could be used as the core of the GATT library.

    The gatttool specific files gatttool.c, gatttool.h, interactive.c and utils.c would live in their own directory examples/gatttool.

  3. Thanks to CMake, I quickly had my first GATT shared library and gatttool application binary.
    The next challenge was to provide a new API that would make the use of GattLib really easy.

    The main issue I had during this phase was to understand how gatttool was communicating with Bluez stack.

    I finally found all the interactions were made through GLib IO Channel. GLib IO Channel is a wrapper on top of files, pipes and sockets - Unix Domain Socket are used by Bluez. The IO Channel only works when a GLib Main Event Loop is running.
    As I did not want to force the GattLib users to have to add a GLib Main Event loop to their project I added a thread to GattLib where the GattLib specific GLib Main Loop would run from.

    Bluez GATT API is all about asynchronous callbacks. I wanted my GattLib API to keep this asynchronous feature but also to support synchronous functions.

    After spending a couple of days on this new library, I ended up with a satisfactory result that was good enough for my project.
    I wrote one of my project BLE use cases with my new GattLib library and the result was a code clear to read.

    I also wrote a couple of examples to help users to use this new library.

  4. After doing a bit of CMake and its magic CPack, I could quickly package a first release of GattLib as a Debian/Ubuntu/... DEB package, a RPM package and a ZIP package.

    • DEB Package:

      $ dpkg-deb -I gattlib-0.1.deb
       new debian package, version 2.0.
       size 81510 bytes: control archive=440 bytes.
           258 bytes,    10 lines      control
           175 bytes,     3 lines      md5sums
       Package: gattlib
       Version: 0.1
       Section: devel
       Priority: optional
       Architecture: amd64
       Depends: libglib2.0-0
       Installed-Size: 227
       Maintainer: Olivier Martin <olivier@labapart.com>
       Description: Library to access GATT information from Bluetooth Low Power devices
      
      $ dpkg-deb -c gattlib-0.1.deb
      drwxrwxr-x root/root         0 2016-04-28 13:05 ./usr/
      drwxrwxr-x root/root         0 2016-04-28 13:05 ./usr/lib/
      drwxrwxr-x root/root         0 2016-04-28 13:05 ./usr/lib/pkgconfig/
      -rw-r--r-- root/root       269 2016-04-28 13:04 ./usr/lib/pkgconfig/gattlib.pc
      -rw-r--r-- root/root    228334 2016-04-28 13:05 ./usr/lib/libgattlib.so
      drwxrwxr-x root/root         0 2016-04-28 13:05 ./usr/include/
      -rw-r--r-- root/root      3421 2016-04-28 00:47 ./usr/include/gattlib.h
      
    • RPM Package:

      $ rpm -qpl gattlib-0.1.rpm
      /usr/include/gattlib.h
      /usr/lib/libgattlib.so
      /usr/lib/pkgconfig
      /usr/lib/pkgconfig/gattlib.pc
      
    • ZIP Package:

      $ unzip -l gattlib-0.1.zip
      Archive:  gattlib-0.1.zip
        Length      Date    Time    Name
      ---------  ---------- -----   ----
            269  2016-04-28 13:04   gattlib-0.1/lib/pkgconfig/gattlib.pc
         228334  2016-04-28 13:05   gattlib-0.1/lib/libgattlib.so
           3421  2016-04-28 00:47   gattlib-0.1/include/gattlib.h
      ---------                     -------
         232024                     3 files
      
  5. And finally a couple of days after starting the project, I can make it alive on Github: https://github.com/labapart/gattlib!

Anonymous on 08/02/2023 19:21
my college library essay quotations <a href="https://onlinecriticalthinking.com/">which of the following is most likely to inhibit critical thinking?</a> college essay about skydiving
Anonymous on 14/02/2023 10:29
don't you have an essay to write <a href="https://myessaywriterkos.org/">paying college athletes essay</a> how to write a college essay for admissions
Anonymous on 17/02/2023 11:44
how to write a theme essay <a href="https://mycollegeessaywritingservicekos.org/">essay editor service</a> how to correctly write a play title in an essay
Anonymous on 27/02/2023 06:48
how to write a conclusion paragraph for an essay <a href="http://helpessaywritingserviceft.com/">helpessaywritingserviceft.com</a> how to write the title of a textbook in an essay
Anonymous on 05/03/2023 07:26
great resume help 2016 <a href="https://cvvsresumeonline.com/">cover letter writer</a> sales customer service resume examples
Anonymous on 06/03/2023 03:19
write for and against essay <a href="https://collegehomeworkhelponline.org/">collegehomeworkhelponline.org</a> write a scholarship essay
Anonymous on 06/03/2023 18:09
how to write an essay to win a scholarship <a href="http://collegehomeworkhelpsfk.org/">homework help for 3rd graders</a> how to write a conclusion paragraph argumentative essay
Anonymous on 12/03/2023 07:27
community service at school essay <a href="https://writemyessaymy.org/">writing essays about literature</a> writing a good thesis statement for an essay
Anonymous on 15/03/2023 08:49
generic viagra online <a href="https://posviagra.org/">buy viagra</a> cost of sildenafil
Anonymous on 16/03/2023 11:39
viagra canada <a href="https://viagraent.org/">women viagra pills</a> buy sildenafil online

Login to comment Comment as anonymous