This project's canonical repositories is hosted on Gothel Software.
Goals
This project aims to create a clean, modern and easy to use API for
Bluetooth
LE and BREDR, fully accessible through C++, Java and other
languages.
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.
Direct-BT supports a fully event driven workflow from
adapter management via device discovery to GATT programming. using its
platform agnostic HCI, L2CAP, SMP and GATT client-side protocol
implementation.
Direct-BT may be utilized via its C++
API or via its Java
API.
Direct-BT is exposed via the following native libraries
libdirect_bt.so for the core C++ implementation.
libjavadirect_bt.so for the Java binding.
Direct-BT is C++17 conform and shall upgrade towards C++20
when widely available on all target platforms.
Some elaboration on the implementation details
The host-side of HCI, L2CAP etc is usually implemented within the OS,
e.g. Linux/BlueZ Kernel. These layers communicate with the
actual BT controller and the user application, acting as the
middleman.
Direct-BT offers packet types and handler facilities for
HCI, L2CAP, SMP, ATT-PDU and GATT (as well to Linux/BlueZ-Mngr)
to communicate with these universal host-side Bluetooth layers and hence
to reach-out to devices.
Implementation Status
LE master/client mode is fully supported to work with LE BT
devices.
The LE slave/server mode is in progress (peripheral):
BTRole separation implemented
Advertising implemented
GATT Server in progress
SMP LE Secure Connections and LE legacy pairing is
fully supported, exposing BTSecurityLevel and SMPIOCapability setup per
connection and providing automatic security mode
negotiation.
BREDR support is planned and prepared for.
To support other platforms than Linux/BlueZ, we will have to
move specified HCI host features used in DBTManager to HCIHandler,
SMPHandler,.. - and -
add specialization for each new platform using their
non-platform-agnostic features.
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)
Ubuntu 18.04 (GNU/Linux)
amd64 (validated, Generic)
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)
Since Direct-BT is not using a 3rd party Bluetooth client
library or daemon/service, they should be disabled to allow operation
without any interference. To disable the BlueZ D-Bus userspace
daemon bluetoothd via systemd, you may use the following
commands.
systemctl stop bluetooth
systemctl disable bluetooth
systemctl mask bluetooth
Required
Permissions for Direct-BT Applications
Since Direct-BT requires root permissions to certain
Bluetooth network device facilities, non-root user require to be granted
such permissions.
For GNU/Linux, there 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)
On Debian 11 we can use package libcap2-bin, version
1:2.44-1, which provides the binaries
/sbin/setcap and /sbin/getcap. It depends on
package libcap2, version >= 1:2.33. If
using earlier setcap binaries, your mileage may vary
(YMMV).
Launch as root
In case your platform lacks support for mentioned
setcap, you may need to execute your application as root
using sudo, e.g.:
Notable here is that capsh needs to be invoked by root to
hand over the capabilities and to pass over the
cap_net_raw,cap_net_admin+eip via --addamb=... it also
needs cap_setpcap,cap_setuid,cap_setgid+ep beforehand.
Launch Examples
The capsh method (default), setcap and
root method is being utilized in
Direct-BTJava
examples are availble, DBTScanner10.java
demonstrates the event driven and multithreading workflow - matching
dbt_scanner10.cpp.
Building Direct-BT
This project also uses the Jau Library as a
git submodule, which has been extracted earlier from this project to
better encapsulation and allow general use.
Direct-BT does not require GLib/GIO nor shall the
BlueZ userspace service bluetoothd be active for best
experience.
To disable the bluetoothd service using systemd:
systemctl stop bluetooth
systemctl disable bluetooth
systemctl mask bluetooth
Build Dependencies
CMake 3.13+ but >= 3.18 is recommended
GCC >= 8.3.0 (g++)
or clang >= 10.0
libunwind8 >= 1.2.1
For Java support
OpenJDK >= 11.
junit4 >= 4.12
Installing build dependencies on Debian (10 or 11):
CPU_COUNT=`getconf _NPROCESSORS_ONLN`
git clone --recurse-submodules git://jausoft.com/srv/scm/direct_bt.git
cd direct_bt
mkdir build
cd build
cmake -DBUILDJAVA=ON -DBUILDEXAMPLES=ON -DBUILD_TESTING=ON ..
make -j $CPU_COUNT install test doc
The install target of the last command will create the include/ and
lib/ directories with a copy of the headers and library objects
respectively in your build location. Note that doing an out-of-source
build may cause issues when rebuilding later on.
Our cmake configure has a number of options, cmake-gui or
ccmake can show you all the options. The interesting ones are
detailed below:
Changing install path from /usr/local to /usr
-DCMAKE_INSTALL_PREFIX=/usr
Building debug build:
-DDEBUG=ON
Disable stripping native lib even in non debug build:
If the solution is not there, please search for an existing issue in
our Bugzilla
DB, please contact us for a new
bugzilla account via email to Sven Gothel [email protected].
Contributing to
Direct-BT
You shall agree to Developer Certificate of Origin and Sign-off your
code, using a real name and e-mail address.
Please check the Contribution document
for more details.
Historical Notes
TinyB Removal since
version 2.3
Starting with version 2.3, the previously refactored TinyB
has been removed completely.
Motivation was lack of detailed Bluetooth support, inclusive
increasing diversion with Direct-BT. Furthermore, work is
underway for BLE slave peripheral and GATT server support
and its mapping to BlueZ D-Bus is questionable and would be
resource intensive.
Added Link-Key support in our SMP processing and SMPKeyBin,
supporting non-legacy SC.
Aligned BTGatt* findGatt*() methods across
Java/C++
Moved EUI48, EUI48Sub (C++/Java) and
uuid_t, Octets (C++) to jaulib
for general use.
Added BTRole and GATTRole for full master/client and slave/server
support.
Added BTAdapter advertising support
Only use and program selected BTAdapter via BTAdapter::initialize()
(required now)
Supports using multiple applications, each using one adapter,
or
One application using multiple adapter for different tasks and
BTRole
2.3.0
Removal of TinyB
2.2.14
Bluetooth 5.0 Support
Using HCI extended scanning and connecting if supported (old API may
not work on new adapter)
Parsing and translating extended and enhanced event types, etc
TODO: User selection of LE_2M and
L2_CODED, ... ???
2.2.13
Revised API: BTGattChar::addCharListener(..) in C++ and Java for a
more intuitive use.
Fix EUI48Sub::scanEUI48Sub(..): Fail on missing expected colon, i.e.
after each two digits
Fix JNIAdapterStatusListener::deviceConnected(..): NewObject(..,
deviceClazzCtor, ..) used wrong argument order
2.2.11
Fix EUI48 unit test and refine on application permissions for
launching applications
Make BTDeviceRegistry and
BTSecurityRegistry universal
Move BTDeviceRegistry and
BTSecurityRegistry to direct_bt library (from
examples)
EUI48Sub: Complement with hash_code(),
clear(), indexOf(), contains(),
...
SMPKeyBin: Tighten constraints, readAndApply(..) must
validate minSecLevel.
BTAdapter::mgmtEvDeviceFoundHCI(..): Clarify code path,
covering name change via AD EIR.
Passthrough all paramter BTAdapter::startDiscovery(..)
-> HCIHandler::le_set_scan_param(..): Add
le_scan_active and filter_policy. Active
scanning is used to gather device name in discovery mode (AD EIR).
Add -dbt_debug argument for AD EIR
direct_bt.debug.hci.scan_ad_eir and parse EIR GAPFlags
Fix BTGattHandler: Gather all Descriptors from all Characteristics
(only queried 1st Char.)
SMPKeyBin's base filename compatibility with FAT32 Long Filename
(LFN)
2.2.5
Complete SMPKeyBin user API: Convenient static 'one shot' entries +
support no-encryption case
Fix leaked AdapterStatusListener
Fixed HCIHandler and l2cap related issues
Unified free function to_string(..) and member toString()
Tested key regeneration use-case: Pairing failure (bad key), key
removal and auto security negotiation.
Adding SMPKeyBin file removal support.
Tested negative passkey/boolean input, requested via auto security
negotiation.
Using negative passkey response via
setPairingPasskey(passkey = 0) for performance.
2.2.4
Providing full featured SMPKeyBin for LTK, CSRK and
secure connection param setup persistence and upload.
Added Auto Security mode, negotiating the security setup with any
device.
Bugfixes in HCIHandler and ACL/SMP packet processing.
Enhanced robusteness of underlying C++ API and implementation.
2.2.00
Kicked off junit testing for Java implementation
Adding direct_bt-fat.jar (fat jar) bootstrapping its
contained native libraries using merged-in jaulib.
Java API renaming, incl package: org.tinyb to
org.direct_bt.
Completing SMP/Security implementation (WIP)
Replaced std::vector and jau::cow_vector with jau::darray and
jau::cow_darray
2.1.33
Added AdapterStatusListener callback methods devicePairingState(..)
and deviceReady(..), supporting security/pairing.
Added support for LE Secure Connections and LE legacy
pairing utilizing SMP and BlueZ/Kernel features.
Exposing BTSecurityLevel and SMPIOCapability for connection oriented
security setup on BlueZ/Kernel, see DBTDevice and BluetoothDevice.
Covering SMP over L2CAP messaging via SMPPDUMsg types and retrieval
via HCI/ACL/L2CAP on BlueZ/Kernel
2.1.30
Use read lock-free jau::cow_vector for all callback-lists, avoiding
locks in callback iteration
Passed GCC all warnings, compile clean
Passed GCC sanitizer runtime checks
Using extracted Jau C++ Support Library, enhanced
encapsulation
Passed valgrind's memcheck, helgrind and drd validating no memory
leak nor data race or deadlock using dbt_scanner10
Added native de-mangled backtrace support using libunwind
and and abi::__cxa_demangle
Reaching robust implementation state of Direct-BT,
including recovery from L2CAP transmission breakdown on Raspberry
Pi.
Resolved race conditions on rapid device discovery and connect,
using one thread per device.
API documentation with examples
Tested on GNU/Linux x86_64, arm32 and arm64 with native and Java
examples.
Tested on Bluetooth Adapter: Intel, CSR and Raspberry Pi
Almost removed non-standard Linux/BlueZ-Mngr kernel
dependency using the universal HCI protocol, remaining portion
configures the adapter.
2.0.0
Java D-Bus implementation details of package 'tinyb' moved to
tinyb.dbus.
The tinyb.jar jar file has been renamed to
tinyb2.jar, avoiding conflicts.
General interfaces matching the original implementation and
following BlueZ
API were created in package org.tinyb.
Class org.tinyb.BluetoothFactory provides a factory to
instantiate the initial root org.tinyb.BluetoothManager, either
using the original D-Bus implementation or an alternative
implementation.
C++ namespace and implementation kept unchanged.
0.5.0
Added notifications API
Capitalized RSSI and UUID properly in Java
Added JNI Helper classes for managing lifetime of JNIEnv and Global
Refences
0.4.0
Added asynchronous methods for discovering BluetoothObjects