| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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!
|
|
|
|
| |
deleted native instance @ disable
|
|
|
|
| |
clear valueNotificationCB
|
|
|
|
| |
configNotificationIndication(..)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'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.
|
|
|
|
| |
Add uuid for non-native-valid instance's impl.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
changed within a running implementation...
|
|
|
|
| |
getBluetoothManager(..) using fq BluetoothManager implementation class name
|
| |
|
|
|
|
| |
native libs commonly exposed in Java via BluetoothUtils.cxx JNI
|
| |
|
|
|
|
|
| |
Concluding commit 22e3abf3661d7de42b3e6c738d8167718e3ca218,
having all DBTDevice lookups (find) in DBTAdapter using the BDAddressType as well.
|
|
|
|
|
|
|
| |
BDAddressType
The BDAddressType is the magic 49th bit of the EUI48 address,
as it specifies the semantics of its 2-high bits.
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
statusListener (remove @ takedown)
|
|
|
|
| |
changed DBTDevice.java ctor, added getBLERandomAddressType()
|
|
|
|
|
| |
DefaultAdapterIndex is user given via property 'org.tinyb.default_adapter',
hence a range check is appropriate.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
| |
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
|
|
|
|
| |
optionally seeding defaultAdapterIndex other than 0
|
| |
|
|
|
|
|
|
|
|
|
| |
(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().
|
|
|
|
| |
'take down' and ensure valueNotificationCB ref is nulled
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
and equality
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
owner of their resepctive backreference
GATTHandler, GATTService, pp are not owner of their resepctive backreference,
hence use std::weak_ptr for backreferences in general and validate on usage (nullptr, if destructed).
No DBTDevice has been ever destructed after using GATTHandler and discovering all GATT services.
In contrast to Java, C++ has no magic GC and hence shared_ptr use_count gets only increased
when emplying circular backreferences - none gets destructed.
Current ownership relationship is:
DBTAdapter -> DBTDevice -> GATTHandler -> GATTService ...
each contains a backreference, now using a weak_ptr.
Result is that depending on the use-case, DBTDevice instances are destructed:
- Using device->remove(): Immediately
- No explicit device->remove(): Adapter keeps sharedDevices, destruction occurs at end.
|
|
|
|
|
|
|
| |
representation adding '✝' after type.
This shall allow still using toString() while marking it deleted,
after 'notifyDeleted()' or 'delete()' has been issued.
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
shall lead to aborting the application process.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
error (TinyB API)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
return immediately (2/2)
Adjust using HCIHandler changes, see commit 9900ef4b93c191c0ac4fa8f941e06a5a8045257c
- DBTAdapter listens to HCIHandler callbacks: *connected* and *disconnected*
using same callback implementations as for DBTManager.
- DBTDevice::notifyConnect receives the actual connection handler
and will be called for all connected callbacks (DBTManager and HCIHandler)
- DBTDevice adjusted return values for *connect* and *disconnect*,
no more connection handle available immediately.
Further changes:
|
|
|
|
|
|
|
| |
JavaAnonObj implementation JavaGlobalObj
JavaAnonObj is now a full virtual interface.
JavaGlobalObj gets default spec for copy and move ctor and assignment.
|
|
|
|
| |
avoiding race condition on discovery state
|
|
|
|
|
|
|
| |
lastUpdate: getLastUpdateTimestamp()
For performance measurement discovery -> gatt complete,
we need to use the last discovery timestamp, since the device could have been created earlier.
|
|
|
|
| |
commands
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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'
|
| |
|
|
|
|
|
|
|
| |
results from AdapterStatusListener
- DBTAdapter.java: Explicitly lock user callbacks (like DBTDevice)
- Remove unnecessary synchronized from methods, AtomicBoolean and explicit locks must suffice
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
VERBOSE and DEBUG. Use the latter in DBTManager.
|
|
|
|
| |
GATTHandler::State for L2CAPComm::State
|