| Commit message (Collapse) | Author | Age | Files | Lines |
|\ |
|
| |
| |
| |
| |
| |
| |
| | |
List<PairingMode> instead of plain array for direct usability
As user needs to test certain features using contains(PairingMode::XYZ),
returning a list is more straightforward. C++ also returns a vector.
|
|/
|
|
|
|
|
|
|
| |
L2CAP_READER_POLL_TIMEOUT) and new L2CAP_RESTART_COUNT_ON_ERROR for testing
L2CAPHandler's read/write will also issue verbose error-out messages in case the instance is still connected,
i.e. not intentionally pulled by another thread.
This is work in progress.
|
|
|
|
| |
list, oops. Added call to C++/Java example for validation
|
|
|
|
|
|
|
|
|
|
|
| |
PairingModes (C++, Java)
For now, DBTDevice has a NOP implementation, i.e. returning zero length vectors (or arrays in Java)
for supported and required PairingMode.
The pair(String passkey) simply returns HCIStatusCode::INTERNAL_FAILURE;
Intention is to validate the new API entry with our application.
|
|
|
|
| |
clear type names: CharDef and CharVal
|
| |
|
|
|
|
|
|
| |
-dbt_hci, -dbt_gatt', setting their env-vars like ScannerTinyB10.java
Aligning example apps for same experience and invocation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
skipped >= GATTService); GATTHandler owned by DBTDevice, always.
GATTService and childs might need access to their GATTHandler, not just DBTDevice.
This relationship always existed, but was skipped.
Also emphasize that GATTHandler is always owned by DBTDevice, hence has a weak back-reference to the same.
Fixed in ATTPDUTypes C++ Direct-BT API doc overview.
Further impact:
- GATTService has a weak back-reference to GATTHandler instead of DBTDevice,
DBTDevice reference will then be picked up from GATTHandler, the usual.
- GATTHandler::discoverPrimaryServices(..), discoverCompletePrimaryServices(..)
needs to receive GATTHandler's shared_ptr from owner and caller to build the back-reference in GATTService
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
w/ one thread per device
Testing w/ 2 devices in fastest rapid reconnect (using automatic disconnect) on Raspberry-Pi:
(1) Native run-dbt_scanner10.sh -silent_gatt -mac C0:26:DA:01:DA:B1 -mac C0:26:DF:01:E5:CA -disconnect -count 12
(2) Java run-java-scanner10.sh -silent_gatt -mac C0:26:DA:01:DA:B1 -mac C0:26:DF:01:E5:CA -disconnect -count 12
The Java (2) test case disclosed a race condition as follows:
"An application using one thread per device and rapid connect, should either use disconnect() or remove(),
but never issue remove() after disconnect(). Doing so would eventually delete the device being already
in use by another thread due to discovery post disconnect!"
The example code was issuing (1) disconnect and waiting for being diconnected and only then
(2) removing the device. In between the device got discovered already and a new processing thread has started
while the closing previous processing thread is removing the device and hence the underlying DBTDevice.
A user shall either use disconnect() or remove(), period.
|
| |
|
|
|
|
| |
init-list of ctor
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'connect' lifecycle
Further:
- L2CAPComm
-- disconnect(): Only lock mtw_write if connected and mark noexcept
-- Added '~L2CAPComm() noexcept' for RAII
-- Removed unsued accessors
- GATTHandler
-- Similar treatment as L2CAPComm
- DBTDevice
-- Remove mtx_gatt and its locks, they were not consistent.
Rely on mtx_connect (connectGATT/getGATTServices/disconnect)
and atomic local GATTHandler copy when using.
-- disconnect GATTHandler directly in disconnect, remove explicit method.
-- pingGATT uses local gattHandler copy to avoid parallel disconnect nullptr,
however, it will fail immediately due to disconnection.
|
|
|
|
|
|
| |
detailed GATT info, nor PERF
Testing with multiple devices in parallel, it is useful to be in the most quiet mode - not walking through tons of info dumps.
|
|
|
|
| |
multi device test support like ScannerTinyB10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
C++ Libs -> none (2x)
Java Jar -> none
Java JNI Libs -> C++ Lib + Java Jar (2x)
C++ Examples -> C++ Libs
Java Examples -> Java Jar
Test -> C++ Lib
+++
scripts/[re]build.sh uses `getconf _NPROCESSORS_ONLN`
for the make -j <number of parallel processes>.
|
|
|
|
|
|
|
|
|
| |
i.e. Debian 10 Buster with GCC 8.3)
GCC 10.1 mostly covers C++20 and is default on Debian 11 Bullseye, we will move there when established.
For now let's use C++17 at least, especially since GCC C++ ABI fixes a few code generation issues
and we intend to further simplify our C++ codebase.
|
|
|
|
| |
The \example tag referring to the example code file must be added to the actual API (header) files.
|
|
|
|
|
|
| |
depenencies, build, ..); Add \example tag in examples.
For unknown reason, examples are not visible in result.
|
|
|
|
|
|
| |
(can be) enabled; Act upon power-off: Close all connections etc.
ScannerTinyB10 also reacts on power-on, i.e. start discovery.
|
|
|
|
|
|
| |
BTMode from AdapterInfo's AdapterSettings
Java property is 'org.tinyb.btmode' (not yet mapped to C++)
|
|
|
|
| |
'direct_bt.debug.manager.event' -> 'direct_bt.debug.mgmt.event'
|
|
|
|
|
|
|
|
| |
Use exploding properties for DBTManager, HCIHandler and GATTHandler timeout+ settings
Also support these via ScannerTinyB10.java, so a user may call:
sh ../scripts/run-java-scanner10.sh -debug -dbt_debug hci.event=false,gatt.event=true -dbt_gatt cmd.read.timeout=10000,cmd.write.timeout=20000,cmd.init.timeout=9999,ringsize=512
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'writeValue(byte[] value, boolean withResponse)'
Add both writeValue(..) mapping to Java
[1] BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response
[2] BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value
Previously only [1] existed and [2] seemingly isn't supported by DBus yet(?)
Adding the additional paramter 'boolean withResponse' to determine which variant is desired,
while removing the original method type.
The TinyB/DBus implementation will throw a BluetoothException if 'withResponse' == true,
as it is not supported.
This change allows clarification of the actual method being desired
and supports a fail fast if not supported.
|
| |
|
|
|
|
| |
declaration where needed; Fix source accordingly.
|
|
|
|
|
|
| |
library.
Building the native lib on slow systems becomes a burden, hence skip if not required.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
values, i.e. "direct_bt.debug" = "hci.event,manager.event"
The renaming of 'foo.bar' to 'foo_bar' is not necessary and only complicates things, hence dropped.
+++
Adding 'Exploding variable-name values'
=======================================
If the value of variable 'direct_bt.debug' is neither 'true' or 'false',
it is treated as a list of sub-variable names separated by comma ','.
Each sub-variable name will be trimmed and if not zero-length
appended to the basename "direct_bt.debug" with a dot '.'.
The new variable name will be set in the environment with value 'true'.
The boolean variable value having an exploded value is considered true!
This is supported for DEBUG 'direct_bt.debug' and VERBOSE 'direct_bt.verbose'.
Example:
"direct_bt.debug" = "hci.event,manager.event,gatt.data".
This leads DBTEnv to set the following environment variables:
"direct_bt.debug.hci.event" = "true"
"direct_bt.debug.manager.event" = "true"
"direct_bt.debug.gatt.data" = "true"
In this case, DEBUG "direct_bt.debug" is also considered true!
+++
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
VERBOSE via lazy DBTEnv from C++ (
DEBUG := environment 'direct_bt_debug' or JVM property 'direct_bt.debug'
VERBOSE := environment 'direct_bt_verbose' or JVM property 'direct_bt.verbose'
This changes allows passing JVM properties as C++ environment variables,
to be accessed via DBTEnv.
JVM property names are renamed from 'foo.bar' to 'jvm_foo_bar'
and can be queried via 'DBTEnv::getProperty("foo_bar")'
as it will also attempt the 'jvm_' prefix if the plain name wasn't resolved.
The singleton DBTEnv instance can be retrieved via DBTEnv::get(),
which allows lazy initialization of DEBUG, VERBOSE from environment variables.
This is required, as the JVM loads the native libraries first,
initializes all native static variables and only then
can pass the properties to the native environment via POSIX 'setenv(..)'.
Hence users should never use static initialization from native code
in such cases, otherwise they can't benefit from the unified JVM properties.
|
|
|
|
| |
discovery toggle with ScannerTinyB10
|
|
|
|
| |
startDiscovery(true) if no devices in process
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
initialization; DBTManager: Validate enabled for non-user default adapter.
DBTAdapter: Have non-enabled adapter to be valid, use lazy HCI initialization
In a multi adapter setting, it is possible to have one adapter not being enabled,
i.e. blocked from operations (e.g. rfkill).
HCI communication is not possible in such cases and 'openHCI()' will fail.
We still need to treat such adapter as valid, as they are,
and distinguish the states: 'valid' and 'enabled'.
This allows 'delivery' of all adapters to a manager
and allows querying whether they are enabled.
Therefor, the native DBTAdapter will not issue an aggregated 'openHCI()'
at construction and initial validation, but treat the HCI instance as a singleton
to be lazily created via 'getHCI()' if not yet existing.
Here the required listener are also attached to the instance.
In the future, this shall also allow dynamically adding/removing
and enabling/disabling adapters.
Hence before using a chosen adapter, one should query its enabled state
via 'isEnabled()', which will also potentially initializing HCI.
+++
DBTManager: Validate enabled for non-user default adapter.
On the Java side, we can chose a default adapter via the property 'org.tinyb.default_adapter'.
If so chosen, it shall be the default adapter, regardless of its 'enabled' state.
Otherwise, the default adapter shall be the first enabled adapter in the list.
|
|
|
|
|
|
|
|
|
|
| |
(C++/Java) and BluetoothDevice.java
To help tracking a device in user space and support more 'down to the metal' access,
the HCI connection handle has been exposed to the Java DBTDevice
and the AdapterStatusListener.
For the latter, especially disconnectDevice(..) is of interest,
since the disconnected handle is lost already when the callback gets invoked.
|
|
|
|
|
|
|
| |
of just boolean, passing through potential HCI error detail
The HCIStatusCode on failed connect*/disconnect commands issued via direct_bt HCI,
could help applications making a better fail-recovery decision than just having the binary result.
|
|
|
|
| |
try - catch, avoiding retry on exception and fail once only.
|
|
|
|
|
|
|
|
|
| |
milliseconds in log upfront.
BluetoothFactory stores the magic t0, i.e. module startup time, to be used to be substracted from current time
to determine elapsed milliseconds.
Naturally, this can only be used after initialization of the native library, before initialization this value is just 0.
|
|
|
|
| |
testing robustness of object lifecycle
|
| |
|
|
|
|
| |
Use it accordingly, reducing duplicated code etc.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
DIRECTBT_CHARACTERISTIC_VALUE_CACHE_NOTIFICATION_COMPAT
GATTCharacteristic (Java/C++): Add enableNotificationOrIndication(..) and use it as default for BLE active addCharacteristicListener(..).
It is recommended to utilize notification over indication, as its link-layer handshake
and higher potential bandwidth may deliver material higher performance.
+++
Add setting BluetoothFactory.DIRECTBT_CHARACTERISTIC_VALUE_CACHE_NOTIFICATION_COMPAT
(and also document DEBUG and VERBOSE).
DIRECTBT_CHARACTERISTIC_VALUE_CACHE_NOTIFICATION_COMPAT
Have direct_bt provide compatibility to TinyB's BluetoothGattCharacteristic
API: BluetoothGattCharacteristic#getValue() value cache and
BluetoothGattCharacteristic#enableValueNotifications(BluetoothNotification) value notification.
DBTGattCharacteristic benefits from _disabled_ compatibility (and DEBUG)
performance wise, as no listener nor cache needs to be added in this case!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Aligned all related C++ and Java API doc entries and made sure it matches implementation.
- Renaming SpecificGATTCharacteristicListener to AssociatedGATTCharacteristicListener,
as we refer to the associate GATTCharacteristic of a GATTCharacteristicListener
AssociatedGATTCharacteristicListener is a specialization knowing its
associated GATTCharacteristic to be used for match().
- Renamed 'configIndicationNotification(..)' to 'configNotificationIndication(..)',
matching order of arguments and the returned enabledState array.
- Exposed 'configNotificationIndication(..)' incl enabledState array to Java
- Clarified the 'add listener' and 'configNotificationIndication(..)' semantic in API doc
and implementation. Added new API entries to distinguish them.
- DBTGattCharacteristic.java skips adding its 'TinyB API compatibility' GATTCharacteristicListener
in case neither notify nor indicate property exist.
Also skip the native configNotificationIndication(..) in such case.
This reduces the overall listener load to GattHandler by factor 5!
- General: Add new method 'removeAllAssociatedCharacteristicListener(GATTCharacteristic)',
allowing removal of all GATTCharacteristic associated listener.
This is usefull to complete the GATTCharacteristic C++ dtor or Java close() operation.
- DBTDevice: Add GATTCharacteristicListener methods to align with Java API
and allow user not to deal with GATTHandler directly.
Convenience and validates the C++/Java API alignement.
- C++ JNICriticalArray: Added 2nd template typename for the java-array-type,
enabling it for other than jbyteArray. Here used for a jbooleanArray.
- The GATTCharacteristicListener Java to C++ native holding specialization JNICharacteristicListener
keeps a new global reference to the Java GATTCharacteristicListener
and the optional associated GATTCharacteristic.
This ensures the instances won't get garbage collected and hence ensures proper
object lifecycle even when passing 'throw away' listener object created just
for the add*Listener call.
- Removal and hence destruction of the listeners is always guaranteed at:
-- Device / GATTHandler disconnect
-- GattCharacteristic dtor or close
|
|
|
|
|
|
|
| |
accessing BluetoothFactory
BluetoothFactory static init will set its VERBOSE and DEBUG field as read from properties,
hence we need to postpone its access.
|
|
|
|
|
|
|
|
|
|
|
| |
disable it (self disable)
The temp discovery enabling kick-off simply ensures that discovery allows new devices to be found,
no need to disable it @ pingGATT.
Further startDiscovery commands will be ignored if in process,
may only change the keepAlive state.
This reduces the overall workload.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'keepDiscoveringAlive' even if still in discovery
Hence adding locking mtx_discovery in mgmtEvDeviceDiscoveringMgmt due to multiple state changes
and updating keepDiscoveringAlive even if not initiating discovery (still running).
Further all calls to startDiscovery(..) (C++ and Java) shall clear the list of discovered devices
to end up in the same state, regardless of an alread running discovery or not.
Note: We might have to observe this behavior in more detail, but as we usually utilize the
status listener model, this list is of less interest.
The Java implementation simply always calls down to native code,
ensuring same 'keepAlive' behavior.
It hence also always clears the list of discovered devices.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
lifecycle)
Since HCIHandler is being used to track all connections (direct or whitelisted),
it is essential to have it running over the whole adapter lifecycle.
openHCI() is now being performed within validateDevInfo(),
hence also sets adapter's valid state.
Call newly added checkValid() in user API on most 'action' methods,
throws exception if adapter is in invalid state.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
characteristic
In contrast to the dbus implementation, where all find(..) is being funnelled through
manager's native find(..) vehicle, direct-bt goes the opposite direction
reusing the existing cached data within the objects.
Manager, adapter, device, service and characteristic object implement findInCache(..),
which compares the uuid and/or name *case-sensitive* of its direct childs (if approriate)
and traverses through its children's findInCache(..) if required.
Note to *case-sensitive* comparison:
- EUI48 (mac) address string use capital hex-letters
- UUID uses lower-case hex-letters
Since service and characteristic object already stores its UUID no extra caching is required here.
For device, an extra WeakReference cache of the services has been added when retrieved via getServices().
This cache is used for device's findInCache(..).
service and characteristic always check whether their WeakReference uplink is still valid,
i.e. no resources pulled (GC'ed) - as well as whether device's cached services exist.
This detail is implemented via each object's 'checkServiceCache()'.
device's 'checkServiceCache(true)' also will retrieve the services if not done yet
within 'findInCache(..)'.
This also ensures services has been retrieved for manager and adapter traversing through device
via 'findInCache(..)'.
Notable, manager's generic find(..) method is *not* implemented:
Due to generic type erasure, we cannot determine the matching BluetoothType for the return parameter,
hence this orig TinyB API method is rather misleading than useful.
|
|
|
|
| |
getBluetoothManager(..) using fq BluetoothManager implementation class name
|
|
|
|
| |
native libs commonly exposed in Java via BluetoothUtils.cxx JNI
|
|
|
|
| |
remark: .. debug facility
|
| |
|