Direct-BT, Bluetooth Server and Client Programming in C++ and Java (Part 1)

This is the first article covering Direct-BT  using version 2.7.1 and may give you a little introduction into this project.

See Direct-BT C++ Implementation Details (Part 1) for some insight view.

Overview

Direct-BT provides direct Bluetooth LE and BREDR programming, offering robust high-performance support for embedded & desktop with zero overhead via C++ and Java.

It supports a fully event driven workflow from adapter management, device discovery to GATT programming, using its platform agnostic HCI, L2CAP, SMP and GATT protocol implementation.

Multiple Bluetooth adapter are handled, as well as multiple concurrent connections per adapter.

Peripheral server device programming is supported as well as the central client, which is also used for Java and C++ self unit testing across two or more Bluetooth adapter.

LE legacy pairing as well as SMP LE Secure Connections is fully supported.

Only BREDR support is currently incomplete and not yet usable, even though the API has been prepared.

Direct-BT’s API and implementation closely follows and references the official Bluetooth Specification.

Direct-BT has been used successfully in a medical trial, as well as in a connected medical device application.

The Jau C++ and Java support library has been extracted to encapsulate its generic use-cases and some of its artifacts are discussed here in the implementation section.

Repeater, a Bluetooth LE Proxy / Forwarder

The provided dbt_repeater application allows to connect between a Bluetooth client and server to analyze their protocol.

In detail, dbt_repeater connects to a given peripheral-server device and thereafter advertises itself using same advertising and scan-response properties except the device-name to a given central-client.
After the central-client connected to dbt_repeater, all GATT requests are forwarded to the given peripheral-server and their replies are sent back.
Hence repeater requires two Bluetooth LE adapter to simultaneously maintain its client & server connection.

Besides (GATT) protocol analysis of 3rd party devices, dbt_repeater is also useful to extend peripheral-server device’s range. A third application of this idea, using TCP/IP forwarding in-between a split-repeater is under investigation. The latter would surely be a limitless range extender as well as ensuring operation without radio interference.

Direct-BT Origins

Direct-BT development started around April 2020, initially as an alternative TinyB Java-API implementation.

The work was motivated due to strict performance, discovery- and connection timing requirements, as well as being able to handle multiple devices concurrently using a real-time event driven low-overhead architecture.

Zafena’s POC-Workstation was originally implemented using TinyB and hence the D-Bus layer to the BlueZ client library.

Real time knowledge when devices are discovered and connected were not available and cloaked by the caching mechanism. Advertising package details were not exposed.

Connections attempts often took up to 10 seconds to be completed. Detailed information from the Bluetooth layer were inaccessible including detailed error states.

Fine grained control about discovery and connection parameter were not exposed by the D-Bus API and hence TinyB.

In January 2020 we tried to remedy certain aspects to meet our goals, but concluded to require direct Bluetooth control via the BlueZ/Linux kernel implementation.

Direct-BT was born.

We then implemented data types for

  • HCI Packets to handle HCI communication with the adapter
  • Mgmt Packets to support BlueZ/Linux communication
  • ATT PDU Messages to handle GATT communication with the remote device
  • SMP Packets to implement Secure Connections (SC) and Legacy pairing.

Last but not least we added

  • Bluetooth version 5 support
  • GATT-Server support to enable implementing peripheral devices, as well as to allow self-testing of Direct-BT.

Today, Direct-BT‘s C++ and Java API match 1:1 and shall not contain legacy API artifacts.

Required Permissions for Direct-BT Applications

As described above, we were required to utilize the host Bluetooth implementation in the GNU/Linux kernel, i.e. BlueZ/Kernel directly without D-Bus to achieve best performance and access the native HCI, L2CAP/GATT and SMP communication channels directly. Such direct access requires root permissions to certain Bluetooth network device facilities, non-root user require to be granted such permissions.

For GNU/Linux, these permissions are called capabilities. The following capabilites are required

  • CAP_NET_RAW (Raw HCI access)
  • CAP_NET_ADMIN (Additional raw HCI access plus (re-)setting the adapter etc)

For details you may continue reading here.

Unit-Testing Trials with two Bluetooth Adapter

The trial tests utilize one or more actual Bluetooth adapter, hence using the capsh launch for the required permissions as described above. Therefor, sudo will be called and a user interaction to enter the sudo password may occur.

The trial tests cover Direct-BT‘s Bluetooth functionality, having its master/client and slave/server peripheral facilities communicating via actual adapter, supporting regression testing of the API, its implementation and adapter.

The tests are implemented in both, C++ and Java. The C++ unit tests are also being used for valgrind memory leak and data race validation. At this point we are free of leaks and use-after-free issues.

Tested Bluetooth Adapter

  • Bluetooth 4.0
    • Intel Bluemoon Bluetooth Adapter (Internal, ID: 8087:0a2a) OK
    • Intel Wireless (Internal, ID: 8087:07dc) OK
    • CSR Bluetooth Adapter (USB-A, ID: 0a12:0001, CSR8510) OK
    • Raspberry Pi Bluetooth Adapter (Internal, BCM43455 on 3+, 4) OK
    • Asus BT-400 Broadcom BCM20702A Bluetooth (USB-A, ID 0b05:17cb, BCM20702A1) OK
    • Broadcom Corp. BCM2046B1, part of BCM2046 Bluetooth (Internal, ID 0a5c:4500) OK
  • Bluetooth 5.0
    • Intel AX200 (Internal, ID 8087:0029) OK
    • Intel AX201 (Internal, ID 8087:0026) OK
    • Asus BT-500 (USB-A, ID 0b05:190e, RTL8761BU) OK on Debian12/Kernel 5.14)
    • Realtek RTL8761BU OK (May need manual power-up, depending on firmware)

Please check the adapter list for more details.

Supported Compiler and OpenJDK

OpenJDK 11 and OpenJDK 17 have been used to pass unit testing.

GCC >= 8.3.0 and clang >= 10.0 define the minimum C++ compiler versions used.

Supported Platforms

The following platforms are tested and hence supported

Debian 12 Bookworm (GNU/Linux)

  • amd64 (validated, Generic)

Debian 11 Bullseye (GNU/Linux)

  • amd64 (validated, Generic)
  • arm64 (should work, Raspberry Pi 3+ and 4)
  • arm32 (should work, Raspberry Pi 3+ and 4)

Debian 10 Buster (GNU/Linux)

  • amd64 (validated, Generic)
  • arm64 (validated, Raspberry Pi 3+ and 4)
  • arm32 (validated, Raspberry Pi 3+ and 4)
  • potential issues with capsh, see below.

Ubuntu 20.04 (GNU/Linux)

  • amd64 (validated, Generic)

Ubuntu 18.04 (GNU/Linux)

  • amd64 (validated, Generic)
  • potential issues with capsh, see above.

Next ….

In part 2 I like to show how to actually use Direct-BT, comparing its C++ and Java examples for client- and server mode programming.

In parallel, you might like to read Direct-BT Implementation Details (Part 1).

1 thought on “Direct-BT, Bluetooth Server and Client Programming in C++ and Java (Part 1)”

Comments are closed.