summaryrefslogtreecommitdiffstats
path: root/java
Commit message (Collapse)AuthorAgeFilesLines
* Conclude POWERED state change across C++/Java; Newly added ↵Sven Gothel2020-09-232-1/+17
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Fix Java_direct_1bt_tinyb_DBTGattDescriptor_toStringImpl(..): Wrong arg ↵v2.1.27Sven Gothel2020-09-221-4/+4
| | | | list, oops. Added call to C++/Java example for validation
* LE Secure Connections: Initial API to support secure pairing with varying ↵Sven Gothel2020-09-225-21/+274
| | | | | | | | | | | 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.
* Handle abort() via dbt_debug's new ABORT(..), ensure a message is being send ↵Sven Gothel2020-09-201-2/+1
| | | | and process aborted; Use it.
* C++ DBTManager / Java BluetoothFactory: Default operation is BTMode::LE (Was ↵Sven Gothel2020-09-201-3/+3
| | | | | | | | | | 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.
* POctets::malloc: throw new exception type OutOfMemoryError early on malloc ↵Sven Gothel2020-09-192-1/+8
| | | | | | | | | | | 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)
* C++/JNI: helper_base.hpp/cxx: Rework raise_java_exception(..) and ↵Sven Gothel2020-09-192-119/+131
| | | | | | | | | | | | | | | | | | | 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.
* C++ tinyb/general: Use rethrow_and_raise_java_exception(..) instead of ↵Sven Gothel2020-09-197-1336/+268
| | | | exploded exception case blocks
* helper_base.hpp: Have all raise_java_exception(..) and ↵Sven Gothel2020-09-192-111/+126
| | | | | | | 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.
* DBTDevice: Resolve disconnect/remove resource race condition @ rapid connect ↵v2.1.22Sven Gothel2020-09-182-11/+35
| | | | | | | | | | | | | | | | | | | | | | 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.
* Correct API doc for DBTDevice::remove() (C++ and Java):Sven Gothel2020-09-161-4/+6
| | | | | | 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.
* CMake: Support full parallel build by adding target dependenciesSven Gothel2020-09-152-0/+4
| | | | | | | | | | | | | | | | 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>.
* Only generate JNI headers when Java sources have been modified, i.e. when ↵Sven Gothel2020-09-151-9/+21
| | | | | | | | | | | | | 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.
* C++ noexcept: DBTManager, DBTAdapter and DBTDevice (concluding for now)Sven Gothel2020-09-151-1/+1
| | | | | | | | | | | | | | | | | | 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.
* C++ noexcept: JavaUplink, DBTObject, JavaGlobalObjSven Gothel2020-09-151-11/+11
|
* C++ noexcept: JNIMem* (convert exception in dtor to abort)Sven Gothel2020-09-152-17/+19
|
* CMake Build: Use C++17 (C++20 not yet supported on all target platforms, ↵Sven Gothel2020-09-121-1/+2
| | | | | | | | | 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.
* Fixing Example crossreference and Menu itemSven Gothel2020-09-031-0/+26
| | | | The \example tag referring to the example code file must be added to the actual API (header) files.
* Complete mapping of BTMode (C++, Java) and have Adapter recognize actual ↵Sven Gothel2020-09-034-8/+107
| | | | | | BTMode from AdapterInfo's AdapterSettings Java property is 'org.tinyb.btmode' (not yet mapped to C++)
* DBTDevice::pingGATT(): Disconnect and return false if: GATT not connected or ↵Sven Gothel2020-08-281-2/+5
| | | | | | | | | 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.
* DBTManager, HCIHandler, GATTHandler: Defer fetching timeout+ config from ↵Sven Gothel2020-08-281-1/+1
| | | | | | | 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.
* BluetoothFactory, DBTEnv: Only pass '[org.]tinyb.*' and 'direct_bt.*' ↵Sven Gothel2020-08-271-5/+7
| | | | | | properties to native environment, remove the 'jvm.' prefix! Make it more simple.
* BluetoothGattCharacteristic: API Change: 'writeValue(byte[] value)' -> ↵Sven Gothel2020-08-266-15/+75
| | | | | | | | | | | | | | | | | | | '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.
* PlatformToolkit: EABI_AARCH64 maps to 'arm64' not 'aarch64' for our common ↵Sven Gothel2020-08-261-1/+1
| | | | os_arch
* PlatformToolkit: Properly map 'os.arch' -> CPUType (reduction) -> 'os_arch' ↵Sven Gothel2020-08-261-5/+250
| | | | | | | | | | | | | | | | | | | | | | | | (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)
* PlatformToolkit: White space fixSven Gothel2020-08-261-277/+275
|
* PlatformToolkit::addPath(..): Resolve complete path via ↵Sven Gothel2020-08-261-3/+25
| | | | File::getCanonicalPath() (absolute resolved path ) and drop duplicates
* PlatformToolkit: Reuse BluetoothFactory.DEBUGSven Gothel2020-08-251-10/+8
|
* BluetoothFactory: Attempt to load native libraries from 'os_and_arch' subdir ↵Sven Gothel2020-08-252-46/+338
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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)
* cmake: Add variable/define 'SKIP_TINYB': Allow to not build the tinyb native ↵Sven Gothel2020-08-251-1/+4
| | | | | | library. Building the native lib on slow systems becomes a burden, hence skip if not required.
* BluetoothFactory: Disable codepath using OS_AND_ARCH library basename ↵Sven Gothel2020-08-251-4/+10
| | | | | | | | feature for now Was introduced in commit 70e9b98afce8d9e6f1e7ce5eb477bc8503950cbe Requires more discussion about clean implementation of platform independent deployment etc.
* DBTEnv: Use plain 'foo.bar' names, not 'foo_bar'; Add 'exploding' name ↵Sven Gothel2020-08-241-5/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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! +++
* BluetoothFactory: Attempt to load native libraries with 'os_and_arch' ↵Sven Gothel2020-08-241-9/+38
| | | | | | | | | | | | | | | 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
* Adapt to new DBG_PRINT(..) semantics, reduce verbosity, use specific macros ↵Sven Gothel2020-08-243-19/+5
| | | | for special cases (e.g. GATT_PRINT, ..)
* BluetoothFactory/DBTEnv: Pass JVM properties to environment, access DEBUG, ↵Sven Gothel2020-08-242-0/+47
| | | | | | | | | | | | | | | | | | | | | | | 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.
* HCIStatusCode.java: Add INTERNAL_TIMEOUTSven Gothel2020-08-231-0/+2
| | | | Sync w/ native HCIStatusCode, commit 9ced6e129123838ff00e2cd119ecc68d24031b11
* DBTAdapter::stopDiscover() now returns the boolean result w/ proper native ↵Sven Gothel2020-08-231-2/+1
| | | | | | | | | -> 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
* DBTAdapter: Have non-enabled adapter to be valid, use lazy HCI ↵Sven Gothel2020-08-225-3/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* DiscoveryState: Complete state transition tableSven Gothel2020-07-291-10/+10
|
* JNI: Complete C++ to Java Exception mappingSven Gothel2020-07-293-29/+77
|
* DBTAdapter DiscoveryState: Refine currentMetaScanType, introduce ↵Sven Gothel2020-07-291-4/+21
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Refine enum BTMode and ScanType: Elevate to 'enum class', shorten value ↵Sven Gothel2020-07-291-1/+1
| | | | definition and add getScanTypeString(..) getScanType(BTMode)
* Fix typo in HCIStatusCode enum valueSven Gothel2020-07-281-2/+2
|
* Expose hciConnectionHandle: AdapterStatusListener connect/disconnect ↵Sven Gothel2020-07-286-20/+52
| | | | | | | | | | (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.
* DBusManager_delete: Do not call destructor, C++ implementation says so. ↵Sven Gothel2020-07-271-1/+2
| | | | Avoid double free @ closing.
* DBTManager.getServices(): Simplify gathering services, dropping manual connect.Sven Gothel2020-07-271-17/+6
|
* C++/Java *Device::connect*(..), disconnect(): Return HCIStatusCode instead ↵Sven Gothel2020-07-275-64/+130
| | | | | | | 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.
* BluetoothUtil: Add getElapsedMillisecond(); ScannerTinyB10 shows elapsed ↵Sven Gothel2020-07-272-0/+19
| | | | | | | | | 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.
* GATTHandler::sendWithReply(): Disclose timeout value in error and exception ↵Sven Gothel2020-07-271-2/+2
| | | | on .. timeout
* Robustness: Distinguish between get<Type>Checked() and get<Type>Unchecked(): ↵Sven Gothel2020-07-262-8/+2
| | | | Use it accordingly, reducing duplicated code etc.