summaryrefslogtreecommitdiffstats
path: root/java/direct_bt
Commit message (Collapse)AuthorAgeFilesLines
* GATTCharacteristic: Add enableNotificationOrIndication(..)..; ↵v2.1.15Sven Gothel2020-07-251-12/+67
| | | | | | | | | | | | | | | | | | | | | | | 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!
* DBTGattCharacteristic::configNotificationIndicationImpl(..): Tolerate ↵v2.1.14Sven Gothel2020-07-241-1/+1
| | | | deleted native instance @ disable
* DBTGattCharacteristic removeAllAssociatedCharacteristicListener(..): Also ↵Sven Gothel2020-07-241-0/+1
| | | | clear valueNotificationCB
* DBTGattCharacteristic: Always pass valid boolean[2] to ↵Sven Gothel2020-07-241-2/+2
| | | | configNotificationIndication(..)
* Reworking GATTCharacteristicListener (C++ and Java)Sven Gothel2020-07-242-93/+99
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - 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
* Java DBTAdapter + DBTDevice close @ JVM shutdown: Avoid all interaction, ↵Sven Gothel2020-07-223-31/+54
| | | | | | | | | native dtor (deleteImpl) cleans up. Shortcut of 'close' take-down @ JVM shutdown, avoiding any potential deadlocks. However, all device's and adapter's deleteImpl() gets issued, allowing the native adapter's destructor to be called for orderly device cleanup.
* DBTAdapter: startDiscovery(..) also might need to change ↵Sven Gothel2020-07-221-5/+4
| | | | | | | | | | | | | | | | '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.
* dbus java: Add minimalistic toString() implementation; direct_bt toString(): ↵Sven Gothel2020-07-173-3/+3
| | | | Add uuid for non-native-valid instance's impl.
* Direct-BT Java: Implement find(..) in manager, adapter, device, service and ↵Sven Gothel2020-07-175-21/+456
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* DBTDevice (C++/Java) equality/identity requires its EUI48 address _and_ ↵v2.1.11Sven Gothel2020-07-031-1/+1
| | | | | | | BDAddressType The BDAddressType is the magic 49th bit of the EUI48 address, as it specifies the semantics of its 2-high bits.
* EUI48::getBLERandomAddressType(): Pass BDAddressType, to only return a valid ↵Sven Gothel2020-07-031-3/+9
| | | | | | | | | | BLERandomAddressType related to the BDAddressType. We validated the BLERandomAddressType in DBTDevice.java, but created an invalid value in DBTDevice.cpp regardless of BDAddressType. Resolved! We also perform the validate in DBTDevice.cpp now.
* DBTManager: Range-check user given DefaultAdapterIndex before usingSven Gothel2020-07-021-1/+4
| | | | | DefaultAdapterIndex is user given via property 'org.tinyb.default_adapter', hence a range check is appropriate.
* Support BDADDR_LE_RANDOM (p1): Add BLERandomAddressType, distinguish ↵Sven Gothel2020-07-021-1/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | HCIAddressType..., Move EUI48 into direct_bt namespace Add BLERandomAddressType Exposed in DBTDevice and BluetoothDevice C++ and Java. See "BT Core Spec v5.2: Vol 6 LE, Part B Link Layer Specification: 1.3.2 Random device Address" +++ Distinguish HCIAddressType -> HCILEPeerAddressType + HCILEOwnAddressType As used for HCIHandler::le_create_conn(..) See "BT Core Spec v5.2: Vol 4, Part E Host Controller Interface (HCI) Functionality: 7.8.12: LE Create Connection command" DBTDevice::connectLE(..) translates its own BDAddressType -> HCILEPeerAddressType using BLERandomAddressType (BDAddressType, address). Currently only HCILEPeerAddressType::STATIC_PUBLIC is allowed and passed through. +++ Move EUI48 into direct_bt namespace
* Minor armv7l g++ 8.3.0 build fixedSven Gothel2020-07-021-1/+1
| | | | | | Used 32bit machine: Raspbian 10.4 'buster', armv7l (armhf), g++ 8.3.0, OpenJDK 11.0.7 Note that main development occurs on GNU/Linux Debian 11 'bullseye', amd64, g++ 9.3.0, OpenJDK 11.0.7
* DBTManager: Use system property (int value) 'org.tinyb.default_adapter' for ↵Sven Gothel2020-06-291-1/+7
| | | | optionally seeding defaultAdapterIndex other than 0
* DBTAdapter: Fix equals(..)Sven Gothel2020-06-291-1/+1
|
* DBTDevice.java: Update 'name' on deviceUpdate EIRDataTypeSet.DataType.NAME ↵v2.1.9Sven Gothel2020-06-291-2/+15
| | | | | | | | | (drop final qualifier, add volatile) On rare occasions (?) it may happen that the device discovery didn't include the device's name when reported via deviceFound(..) callback etc. Therefor allow updating of the name, using the C++ DBTDevice::getName().
* DBTGattCharacteristic.disableValueNotifications(): Tolerate exception at ↵Sven Gothel2020-06-291-3/+10
| | | | 'take down' and ensure valueNotificationCB ref is nulled
* Resolve regression calling DBTNativeDownlink.delete() having notifyDeleted() ↵Sven Gothel2020-06-297-29/+54
| | | | | | | | | | | | | | | being called back from deleteNativeJavaObject(..) Regression introduced with commit 83e0c7f75b4206701c1b9c62ebd4282f50f92a31 DBTNativeDownlink.delete() calls DBTNativeDownlink.deleteNativeJavaObject(..), which by itself now calls back using DBTNativeDownlink.notifyDeleted() and purges isValid and nativeInstance. Therefor, DBTNativeDownlink.delete() needs to cache the nativeInstance reference and pass it down to DBTNativeDownlink.deleteImpl(long) as argument. Further refine synchronization, using a local Object and isValid being an AtomicBoolean to allow isValid() return the current state.
* DBTDevice.java: Align its identity with C++: Only use EUI48 address for hash ↵Sven Gothel2020-06-291-2/+2
| | | | and equality
* Resolve circular references (p3): Java: Ensure DBTDevice can be GC'ed (at ↵Sven Gothel2020-06-292-6/+12
| | | | | | | | | | | | | | | | | | | | | | | remove()) DBTDevice.close() - Also issue adapter.removeDiscoveredDevice(this); Without, the Java DBTDevice wouldn't get GC'ed - close(): super.close() -> delete() -> deleteImpl() -> DBTDevice::remove() DBTDevice.remove() - Simply calls close(), implying DBTDevice::remove() and complete reference cleanup. ScannerTinyB10: - argument '-debug' to enable DEBUG/VERBOSE DBTAdapter.cxx: - Just give more clarity on DBTDevice.java creation and delete local ref. DBTDevice.cxx:: getServices() JNI - No need to call device->connectGATT()
* Resolve circular references (p2): Java DBTDevice, GATTHandler, GATTService, ↵Sven Gothel2020-06-295-21/+63
| | | | | | | | | | | | | | pp are not owner of their resepctive backreference Even though the Java GC is capable to resolve circular references as long they are not specifically being hold by a running thread, we use WeakReference for a more clean lifecycle description. This is aligned to the C++ changes of commit dfdfd883f52e8d31c005d0f8ae42bbe6dd60c2b8 Further, also have 'DBTDevice -> DBTAdapter' backreference being weak for completion. Further, DBTDevice.remove() also removes itself from DBTAdapter's discoveredDevice list.
* Java DBTNativeDownlink toString(): If !valid use alternative short ↵Sven Gothel2020-06-286-6/+32
| | | | | | | representation adding '✝' after type. This shall allow still using toString() while marking it deleted, after 'notifyDeleted()' or 'delete()' has been issued.
* Notify DBTNativeDownlink when its native JavaUplink -> JavaGlobalObj ↵Sven Gothel2020-06-271-2/+12
| | | | | | | | | | | counterpart gets destructed DBTNativeDownlink.notifyDeleted() gets called from native destructor, so isValid and nativeInstance can be set accordingly. This resolves a periodic crash when GATTHandler flushes it's GATTServices and linked resources. Here the DBTGATTService.java's DBTNativeDownlink still holds the native instance handle and as it gets finalized after the native object, accessing it post mortem causes a SIGSEGV.
* GATTHandler/DBTDevice (incl Java): Add ping[GATT](), testing device ↵Sven Gothel2020-06-251-0/+14
| | | | | | | | | | | | | | | | availability via retrieval of GATT info Issues a ping to the device, validating whether it is still reachable. This method could be periodically utilized to shorten the underlying OS disconnect period after turning the device off, which lies within 7-13s. In case the device is no more reachable, disconnect will be initiated due to the occurring IO error. +++ Implementation attempts to read the mandatory APPEARANCE CharacteristicValue of the mandatory GENERIC_ACCESS service.
* DBTDevice::getServices() shall not throw an exception but return null on ↵Sven Gothel2020-06-241-1/+12
| | | | error (TinyB API)
* DBTAdapter (Java/C++): Explicit synchronization on start/stop discovery, ↵Sven Gothel2020-06-101-7/+12
| | | | avoiding race condition on discovery state
* DBTDevice (C++/Java): Expose getLastDiscoveryTimestamp() and rename ↵Sven Gothel2020-06-091-2/+10
| | | | | | | lastUpdate: getLastUpdateTimestamp() For performance measurement discovery -> gatt complete, we need to use the last discovery timestamp, since the device could have been created earlier.
* Java/C++: start/stop discovery shall return true even if operation not requiredSven Gothel2020-06-091-1/+1
|
* C++: Utilize 'currentScanType' for start/stop discovery same as for Java ↵Sven Gothel2020-06-091-0/+4
| | | | | | | | | | code; use atomic<ScanType> avoiding race conditions C++/Java: Only update the discovering state for false in DISCOVERING listener if keepAlive == false. C++ like Java pendant, only perform start/stop discovery in appropriate discovery state C++ expose discovery state 'currentScanType'
* DBTDevice.java: Add missing semicolon (oops)Sven Gothel2020-06-091-1/+1
|
* DBT Adapter/Device (java): Use AtomicBoolean for states and only handle ↵Sven Gothel2020-06-092-153/+139
| | | | | | | results from AdapterStatusListener - DBTAdapter.java: Explicitly lock user callbacks (like DBTDevice) - Remove unnecessary synchronized from methods, AtomicBoolean and explicit locks must suffice
* DBTAdapter.java: startDiscovery() -> keepAlive=true defaultSven Gothel2020-06-091-2/+2
|
* [DBT]Adapter (Java/C++) startDiscovery(bool keepAlive) policy change: ↵Sven Gothel2020-06-091-1/+4
| | | | | | | | | | | | | | | keepAlive default := true Using startDiscovery(keepAlive=true) and stopDiscovery() is the recommended workflow for a reliable discovery process. Without keepAlive=true, we already experienced a too short discovery cycle where the subsequent manual startDiscovery restart will purge the already discovered devices via removeDiscoveredDevices(). Hence keepAlive=true is strongly indicated for increased reliability especially when _not_ using the AdapterStatusListener, since adapter.getDevices() may simply come too late.
* Expose 'org.tinyb.verbose' and 'org.tinyb.debug' via BluetoothFactory ↵Sven Gothel2020-06-091-1/+2
| | | | VERBOSE and DEBUG. Use the latter in DBTManager.
* DBTDevice Java/JNI: Implement missing methods and cleanupSven Gothel2020-06-081-67/+189
| | | | | | | | | | Implement missing methods Java/JNI: - getManufacturerData - *BlockedNotifications* - *PairedNotifications* Cleanup - remove JNI code for pure Java impl
* Rename HCIErrorCode -> HCIStatusCode for clarity and pleasing the eyesSven Gothel2020-06-042-4/+4
|
* Clarify le_scan and conn[ection] arguments for whitelist and connect methods ↵Sven Gothel2020-06-012-12/+12
| | | | C++/Java, fix timeout semantics (API doc)
* AdapterStatusListener(C++/Java): Expose 'HCIErrorCode reason' on disconnect ↵Sven Gothel2020-05-312-9/+35
| | | | | | | (split deviceConnectionChanged up), align args of deviceUpdated The 'HCIErrorCode reason' gives us valuable information of the disconnect reason, hence we shall expose it to the user level on the C++ and Java side.
* Aligned Java scanner 10 w/ native example (working error recovery); Tolerant ↵Sven Gothel2020-05-301-1/+1
| | | | | | | | | DBTAdapter.removeDevices(). DBTAdapter.removeDevices() must behave tolerant on inconsistent discovered device count in case of an error. Both scanner examples behave properly on a forced disconnect test during GATT processing using the thrown C++ exception (fwd to Java) and receiving the DISCONNECT event.
* Java DBTDevice: Drop getGATTService() from connect* as it should be done ↵Sven Gothel2020-05-281-4/+12
| | | | | | | after connect callback @ device.getServices() This is due to a potential relaxed connect* handling, therefor we shall only go one step further with GATT services after determining a proper connection. WIP.
* DBTDevice: Avoid NPE: Check user callback reference before usingSven Gothel2020-05-281-6/+18
|
* DBTGattCharacteristic: Added commented out code to detect notify/indicate ↵Sven Gothel2020-05-281-0/+18
| | | | properties
* BluetoothGattCharacteristic::getFlags() Move flags == properties API doc to topSven Gothel2020-05-281-12/+0
|
* DBTNativeDownlink* and derivations: Avoid double-close by query isValid()Sven Gothel2020-05-285-19/+27
| | | | After closing once, all resource links are nulled.
* DBTDevice/BluetoothDevice: Expose getCreationTimestamp() and add ↵Sven Gothel2020-05-281-1/+12
| | | | BluetoothAddressType getAddressType()
* BluetoothDevice: Add connect(..) w/ LE connection parameterSven Gothel2020-05-251-2/+23
| | | | This exposes a technical detail similar to BluetoothAdapter.addDeviceToWhitelist(..) .
* Expose Whitelist (auto-)connect management to BluetoothAdapter.java, impl in ↵Sven Gothel2020-05-251-0/+30
| | | | | | | | | | | | | | DBTAdapter.java only at this point. Instead of using the "string definition" of addressType, we introduce a universal BluetoothAddressType (java) which corresponds with BDAddressType (C++). BluetoothAddressType (java) supports a string conversion, which also accepts the D-Bus names "", "public" and "random" - as also used in TinyB. ++++ Further adds HCIWhitelistConnectType (java) representing the same C++ type.
* AdapterStatusListener (C++/Java): Add discoveringChanged(..), converge ↵Sven Gothel2020-05-242-35/+39
| | | | | | | | | | | | | | | | | | | | | deviceConnected/deviceDisconnected Add discoveringChanged(..), as it is of high interest to the user to adjust connect/disconnect and GATT operations. Hence add it to this central adapter listener, also being used to synthesize the old fashion TinyB 'discovering' callback. We also expose the 'keepAlive' flag in this callback to the user. Converge deviceConnected(..)/deviceDisconnected(..) -> deviceConnectionChanged(..) to be a bit more efficient. +++ DBTAdapter: keepAlive in startDiscovery defaults to false, aligned w/ TinyB. A new startDiscovery(..) method has been added to the Java API, also adding keepAlive. +++ Java TODO: Add the whitelist add/remove functionality
* Add Whitelist to DBTManager/DBTAdapter and test (Result: No auto-connection)Sven Gothel2020-05-241-2/+5
| | | | | | | To avoid the hassle with HCI connect/disconnect while scanning, we should test the whitelist supposed to be stored on the adapter to auto-connect. Initial testing didn't show any connection.