Java Bluetooth Manager. A library/framework for managing bluetooth adapters, bluetooth devices, GATT services and characteristics
Clone or download

README.md

Maven Central Build Status Coverage Status Codacy Badge Join the chat at https://gitter.im/sputnikdev/bluetooth-manager

bluetooth-manager

Java Bluetooth Manager. A library/framework for managing bluetooth adapters, bluetooth devices, GATT services and characteristics

The Bluetooth Manager is a set of java APIs which is designed to streamline all the hard work of dealing with unstable by its nature Bluetooth protocol.

KPIs

The following KPIs were kept in mind while designing and implementing the Bluetooth Manager:

  1. Flexibility in using different transports, e.g. serial port, dbus or any other (like tinyb).
  2. Extensibility in adding new supported devices, e.g. different sensors and other hardware.
  3. Robustness. Due to the nature of the Bluetooth protocol the biggest challenge is making the API stable enough so that end-users could use it.
  4. Comprehensive support for Bluetooth GATT specifications. This is a powerful feature which would allow users:
    1. add any device which conforms GATT specification without developing any custom code
    2. add custom made devices by only specifying a path to a custom defined GATT specification for a device

Implementation overview

The following diagram outlines some details of the Bluetooth Manager: Bluetooth Manager diagram

Governors API

The central part of the BM architecture is "Governors" (examples and more info BluetoothGovernor,
AdapterGovernor, DeviceGovernor and BluetoothManager). These are the components which define lifecycle of BT objects and contain logic for error recovery. They are similar to the transport APIs (see below), but yet different because they are "active" components, i.e. they implement some logic for each of BT objects (adapter, device, characteristic) that make the system more robust and enable the system to recover from unexpected situations such as disconnections and power outages.

Apart from making the system stable, the Governors are designed in a such way that they can be used externally, in other words it is another abstraction layer which hides some specifics/difficulties of the BT protocol behind user-friendly APIs.

Transport API

A specially designed abstraction layer (transport) is used to bring support for various bluetooth adapters/dongles, operation systems and hardware architecture types.

The following diagram outlines some details of the Bluetooth Manager Transport abstraction layer: Transport diagram

There are two implementations of the BT Transport currently:

  • TinyB Transport. The TinyB transport brings support for:
    • Conventional USB bluetooth dongles.
    • Linux based operation systems.
    • A wide range of hardware architectures (including some ARM based devices, e.g. Raspberry PI etc).
  • WIP: Bluegiga Transport. The Bluegiga transport brings support for:
    • Bluegiga (BLE112) USB bluetooth dongles.
    • Linux, Windows and OSX based operation systems.
    • A wide range of hardware architectures (including some ARM based devices, e.g. Raspberry PI etc).

Compatibility matrix

TinyB Bluegiga
Windows - Y
Linux Y Y
Mac - Y
X86 32bit Y Y
X86 64bit Y Y
ARM v6 (Raspberry PI) Y Y
Adapters autodiscovery Y Y
Adapter power management Y -
Adapter aliases Y -
BLE devices discovery Y Y
BR/EDR devices discovery (legacy BT) Y -

Troubleshooting

Using Bluetooth Manager

Start using it by specifying maven dependencies from the Maven Central repository:

<dependency>
    <groupId>org.sputnikdev</groupId>
    <artifactId>bluetooth-manager</artifactId>
    <version>X.Y.Z</version>
</dependency>
<dependency>
    <groupId>org.sputnikdev</groupId>
    <artifactId>bluetooth-manager-tinyb</artifactId>
    <version>X.Y.Z</version>
</dependency>

The example below shows how to set up the Bluetooth Manager and read a characteristic value.

Reading characteristic

import org.sputnikdev.bluetooth.URL;
import org.sputnikdev.bluetooth.manager.CharacteristicGovernor;
import org.sputnikdev.bluetooth.manager.impl.BluetoothManagerBuilder;

public final class BluetoothManagerSimpleTest {

    public static void main(String[] args) throws Exception {
        new BluetoothManagerBuilder()
                .withTinyBTransport(true)
                .withBlueGigaTransport("^*.$")
                .build()
                .getCharacteristicGovernor(new URL("/XX:XX:XX:XX:XX:XX/F7:EC:62:B9:CF:1F/" 
                        + "0000180f-0000-1000-8000-00805f9b34fb/00002a19-0000-1000-8000-00805f9b34fb"), true)
                .whenReady(CharacteristicGovernor::read)
                .thenAccept(data -> {
                    System.out.println("Battery level: " + data[0]);   
                }).get();
    }
    
}

Here is what happening behind the scene in the example above:

  • detecting what adapters are installed in the system (Generic and BlueGiga)
  • automatically loading native libraries for the current architecture type (CPU type and OS type)
  • setting up bluetooth manager
  • choosing the nearest bluetooth adapter
  • connecting to the bluetooth device
  • resolving GATT services and characteristics
  • reading the "Battery Level" characteristic

Receiving characteristic notifications

import org.sputnikdev.bluetooth.URL;
import org.sputnikdev.bluetooth.manager.BluetoothManager;
import org.sputnikdev.bluetooth.manager.impl.BluetoothManagerBuilder;

public class BluetoothManagerSimpleTest {

    public static void main(String args[]) {
        // get the Bluetooth Manager
        BluetoothManager manager = new BluetoothManagerBuilder()
                .withTinyBTransport(true)
                .withBlueGigaTransport("^*.$")
                .build();
        // define a URL pointing to the target characteristic
        URL url = new URL("/88:6B:0F:01:90:CA/CF:FC:9E:B2:0E:63/" +
                "0000180f-0000-1000-8000-00805f9b34fb/00002a19-0000-1000-8000-00805f9b34fb");
        // subscribe to the characteristic notification
        manager.getCharacteristicGovernor(url, true).addValueListener(value -> {
            System.out.println("Battery level: " + value[0]);
        });
        // do your other stuff
        Thread.sleep(10000);
    }
}

More examples here: bluetooth-cli


Contribution

You are welcome to contribute to the project, the project environment is designed to make it easy by using:

  • Travis CI to release artifacts directly to the Maven Central repository.
  • Code style rules to support clarity and supportability. The results can be seen in the Codacy.
  • Code coverage reports in the Coveralls to maintain sustainability. 100% of code coverage with unittests is the target.

The build process is streamlined by using standard maven tools.

To build the project with maven:

mvn clean install

To cut a new release and upload it to the Maven Central Repository:

mvn release:prepare -B
mvn release:perform

Travis CI process will take care of everything, you will find a new artifact in the Maven Central repository when the release process finishes successfully.