| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
AdapterStatusListener shall receive adapterSettingsChanged(..) for initial AdapterSettings
Conclude POWERED state change across C++/Java
- DBTAdapter.java must be notified to have isDiscovering and discoveredDevices cleared on !POWERED.
It will additionally react to !POWERED state change, by clearing the mentioned states for robustness.
- DBTAdapter.cpp's stopDiscovery() shall send MgmtEvtDiscovering (-> AdapterStatusListener.discoveryChanged(..))
itself in case of le_enable_scan != SUCCESS, otherwise
- DBTAdapter.cpp's poweredOff():
-- Shall not clearAllMgmtEventCallbacks() on HCI before stopDiscovery() and disconnectAllDevices(),
otherwise stopDiscovery events won't be received and forwarded to AdapterStatusListener.
hci->close() will deal with it afterwards.
It is up to the user (application) to react to POWERED (power on) state change,
i.e. restart discovery!
+++
Newly added AdapterStatusListener shall receive adapterSettingsChanged(..) for initial AdapterSettings.
This is required to have e.g. the DBTAdapter.java instance be aware of its initial state, e.g. isPowered etc.
|
|
|
|
| |
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.
|
|
|
|
| |
and process aborted; Use it.
|
|
|
|
|
|
|
|
|
|
| |
DUAL in Java)
All global BTMode defaults to LE (only)
- C++ DBTManager: Add MgmtEnv::DEFAULT_BTMODE, env-var 'direct_bt.mgmt.btmode' first, then try 'org.tinyb.btmode'.
- DBTEnv:getProperty(name): Add COND_PRINT(debug,..) for no default value root method as well.
|
|
|
|
|
|
|
|
|
|
|
| |
failure, also throw IllegalArgumentException on size <= 0
- Add exception type 'direct_bt::OutOfMemoryError' and wire it in helper_base for C++/JNI interoperability.
- std::malloc may not return nullptr on zero size, but a valid dummy pointer usable by free.
Hence check for malloc(0) and throw IllegalArgumentException
- also throw OutOfMemoryError on nullptr == malloc(size)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
rethrow_and_raise_java_exception[->_impl](..) ..
Commit 5cfe7e13c4dbf07360d928e421050de5e00684a1 intention was noble,
however, 'inline' is not guaranteed and doesn't work here.
I.e. the desired inline reduction with automatic elision and using __FILE__ and __LINE__ macros is not supported.
Instead, move the functions back to helper_base.cxx and add paramter for __FILE__ and __LINE__
to be passed by the only caller macro 'rethrow_and_raise_java_exception(E)'.
The latter simply explodes to 'rethrow_and_raise_java_exception_impl((E), __FILE__, __LINE__)',
which serves the purposed of having exposed the file and line position
where the exceotion got caught.
Also support api/tinyb/BluetoothException, rendering commit 3139f93409cac61ba5b80caf506375d94eff8778 valid,
i.e. use rethrow_and_raise_java_exception(..) in the tinyb C++/JNI code instead of exploded exception case blocks.
|
|
|
|
| |
exploded exception case blocks
|
|
|
|
|
|
|
| |
rethrow_and_raise_java_exception(..) inline, benefitting from __FILE__ and __LINE__
Also have all raise_java_exception(..) call print_exception(..) upfront unconditionally, to not miss any exception
in case a thread has died or the Java caller suppresses the output.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
Fix order of explicitly removing shared reference: connected-devices, discovered-devices and shared-devices.
Fix disconnect also removes its ref from discovered-devices, besides connected-devices,
but not shared-devices.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Jar file is being build.
JNI header generation is satisfied by 'add_jar(.. GENERATE_NATIVE_HEADERS <target> DESTINATION <dir>)',
note that its GENERATE_NATIVE_HEADERS target is a dummy target, since jni/direct_bt defines target javadirect_bt.
Weakness of not directly checking build dependency of javadirect_bt against generated headers exists,
however, it is unrealistic to assume that the transient generated JNI header will be edited manually
within the process.
Therefor we can use the dummy target javadirect_bt_javah and JNI header generation will only
occur when java sources have been modified, i.e. the jar file being actually build.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
RELEASE Builds w/ -O3: dist-amd64/lib/libdirect_bt.so.2.1.20
pre-opt:
2,131,720
post-opt: 74,424 bytes reduced: 3.5%
2,057,296 commit (this commit)
Besides footprint and natural performance benefits,
mostly quality regarding conscious managing of exception handling
benefitted this last 'noexcept' changeset.
Notable here *Octets and ATTPDU types range checking
has been moved into the ctor to allow member access
w/o range checks and hence avoiding potential exceptions.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
BTMode from AdapterInfo's AdapterSettings
Java property is 'org.tinyb.btmode' (not yet mapped to C++)
|
|
|
|
|
|
|
|
|
| |
no GATTServices available
This required getGATTServices() (C++) or getServices() (Java) to be completed, hence added remark in API doc.
Reasoning is that pingGATT shall not initiated resource creation, but assumes all set set up well.
If failing, it shall cause a disconnected.
|
|
|
|
|
|
|
| |
environment until instance creation using singleton holder
Otherwise static initialization at library load will occur
and hence not allow the Java BluetoothFactory to pass the properties to the environment before.
|
|
|
|
|
|
| |
properties to native environment, remove the 'jvm.' prefix!
Make it more simple.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'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.
|
|
|
|
| |
os_arch
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(our common name)
As it turned out that OpenJDK uses 'arm' for 'os.arch' on an armhf machine,
we are required to perform some mapping, i.e. reduction of 'os.arch' and map.
Hence the reuse of CPUFamily, CPUType (reduction) and ABIType
which eventually map to our common name.
This is also required as we already have chosen our common name,
based on the 'archabi' name used on the platform.
Too bad OpenJDK couldn't use same name here,
so they use 'armhf' for the native installation folder
but 'arm' for 'os.arch'.
However, introducing this 'reduce map' will easy further support.
Tested on OS Linux
- i386
- amd64
- armhf
- aarch64 (not yet, but names are known)
|
| |
|
|
|
|
| |
File::getCanonicalPath() (absolute resolved path ) and drop duplicates
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
to CWD and 'java.library.path', supporting multi-platform deployment.
This change resolved initial attempts as discussed in
- commit 70e9b98afce8d9e6f1e7ce5eb477bc8503950cbe
- commit 2d6c05f88c379f9091d291aad90fc03e4ea10b33
+++
In detail, PlatformToolkit's loadLibrary(..), takes a libBaseName,
a library basename without prefix (like 'lib') or suffix like '.so'.
Basic order of library locations
User locations:
- current working directory + {@link #os_and_arch}
- iterate through paths within 'java.library.path', adding {@link #os_and_arch} to each
- current working directory
- iterate through paths within 'java.library.path'
System locations:
- optional OSX path
- iterate through paths within 'sun.boot.library.path'
If the above fails, {@link System#loadLibrary(String)} is called using the plain {@code libBaseName},
exhausting all simple locations and methods.
Example:
/usr/local/projects/direct_bt/dist-amd64/linux-amd64/libdirect_bt.so (addPath cwd.os_and_arch)
/usr/local/projects/direct_bt/dist-amd64/lib/linux-amd64/libdirect_bt.so (addPath java-user-libpath.os_and_arch:0)
/usr/local/projects/direct_bt/dist-amd64/libdirect_bt.so (addPath cwd)
/usr/local/projects/direct_bt/dist-amd64/lib/libdirect_bt.so (addPath java-user-libpath:0)
/usr/lib/jvm/java-14-openjdk-amd64/lib/libdirect_bt.so (addPath java-boot-libpath:0)
|
|
|
|
|
|
| |
library.
Building the native lib on slow systems becomes a burden, hence skip if not required.
|
|
|
|
|
|
|
|
| |
feature for now
Was introduced in commit 70e9b98afce8d9e6f1e7ce5eb477bc8503950cbe
Requires more discussion about clean implementation of platform independent deployment etc.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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!
+++
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
postfix in basename, easing multi-platform deployment.
Using 'os_and_arch' postfix derived from
lower-case Java system property 'os.name' and 'os.arch', e.g. 'linux-amd64'.
If '<basename>-<os_and_arch>' fails, we attempt to load the plain '<basename>',
e.g. the following loadLibrary sequence is performed,
each line only the first available.
- 1) direct_bt-linux-amd64, 2) direct_bt
- 3) javadirect_bt-linux-amd64, 4) javadirect_bt
|
|
|
|
| |
for special cases (e.g. GATT_PRINT, ..)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
Sync w/ native HCIStatusCode, commit 9ced6e129123838ff00e2cd119ecc68d24031b11
|
|
|
|
|
|
|
|
|
| |
-> java proagation
As we use HCIHandler's le_enable_scan etc, the result of start/stop discovery is meaningful now.
This especially as the HCI command is of CMD_COMPLETE class and hence completes its operation.
See commit e7164946014ab8d5c5587fe8f69e6262aed64bc5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
currentNativeScanType, check valid states, add sendEvent
Define the 'DiscoveryState' consisting out of: currentMetaScanType, currentNativeScanType and keepAlive
* + ------+--------+-----------+----------------------------------------------------+
* | meta | native | keepAlive | Note
* + ------+--------+-----------+----------------------------------------------------+
* | true | true | false | -
* | false | false | false | -
* + ------+--------+-----------+----------------------------------------------------+
* | true | true | true | -
* | true | false | true | temporarily disabled -> startDiscoveryBackground()
* | false | false | true | manual event generation
* + ------+--------+-----------+----------------------------------------------------+
Added rare case of stopDiscovery() transition
from (meta=true, native=false, keepAlive=true)
to.. (meta=false, native=false, keepAlive=true),
where we are required to send an new Discovering event to the user.
Added checkDiscoveryState() validation method,
called after each transition to ensure consistency throwing an IllegalStateException.
|
|
|
|
| |
definition and add getScanTypeString(..) getScanType(BTMode)
|
| |
|
|
|
|
|
|
|
|
|
|
| |
(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.
|
|
|
|
| |
Avoid double free @ closing.
|
| |
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
on .. timeout
|
|
|
|
| |
Use it accordingly, reducing duplicated code etc.
|