| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
|
|
|
| |
-> 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
|
|
|
|
|
|
|
| |
This replaces Linux Mgmt's discover start/stop with native HCI commands.
Besides avoiding side-effects, we can utilize le_set_scan_param(..)
similar to le_create_conn(..) for fine grained scanning performance.
|
|
|
|
|
| |
Utilzing new HCIHandler MgmtEvtDeviceFound events from LE_ADVERTISING_REPORT,
see commit a49ce8a8a72eb34cc6a4c8d23e4907684350d078
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
EInfoReport: Fix address-type AD -> BDAddressType
Parse LE_ADVERTISING_REPORT and produce MgmtEvtDeviceFound, call its listener.
This removes dependency of Linux Mgmt's MgmtEvtDeviceFound events.
MgmtEvtDeviceFound optionally holds the parsed std::shared_ptr<EInfoReport> instance,
removing the need to process the raw EIR again in DBTAdapter later on.
Misc:
- Fix EInfoReport AD address-type -> BDAddressType conversion (missing)
- Expose LEADVEventType enum w/ string presentation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
processCommandStatus/processCommandComplete using base HCICommand
Whether a simple HCICommand or HCIStructCommand<..> is being sent is up to the caller
and agnostic to the methods.
We either process a command with intermediate status respone (lagging result)
and hence no detailed result structure/data
- or -
we process a command with complete status (and completed operation)
potentially with detailed result structure/data.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
mutex-lock, avoiding re-entry deadlock
Commit 86eef03c262a0e93800c1558ce81e32e0d899ab1, GATTHandler: connect/disconnect: Lock mtx_command,
actually introduced a deadlock putting the mutex-lock before the 'atomic-switch'.
Since DBTDevice.disconnect can be issued by GATTHandler:disconnect (fault situation),
and another thread may also tries to directly DBTDevice.disconnect about the same time (shutdown),
we need the atomic-switch skipping the sensitive operation before locking down the object.
Further, silence the disconnect* commands, INFO_PRINT -> DBG_PRINT.
|
|
|
|
|
|
|
|
|
|
| |
constructing exception message, avoiding virtual function variant.
For an unknown reason, using the virtual function 'toString()'
while constructing an exception message causes a SIGSEGV.
This method represents a non-virtual variation,
which also does not call any other virtual function.
|
| |
|
|
|
|
| |
Use it accordingly, reducing duplicated code etc.
|
|
|
|
| |
valid check; Use new JNI getInstance() -> getDBTObject() w/ valid check
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
| |
its existence if adapter.isValid()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
directly (e.g. whitelisted devices)
HCIConnection:
- Clarify identity using address _and_ addressType
- Make members private for immutable access only, except handle.
HCIHandler:
- Track all incoming connections, i.e. events.
Earlier we initiated tracking only via user connect calls,
now we allow any incoming connection being tracked (e.g. whitelisted devices).
- Correctly identify devices with address _and_ addressType
- or - the connection handle using HCIConnection etc.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
connect must be performed (not a performance issue)
Our earlier code used the manager's implicit whitelist feature to connect.
The earlier performance lag was due to slow scanning parameter,
not the fact that no connection has been made.
|
| |
|
|
|
|
| |
new HCIHandler
|
|
|
|
|
|
| |
services; Add findGATTService(..)
Note: We might want to add more find(..) functionality, similar to the TinyB Java API.
|
|
|
|
| |
native libs commonly exposed in Java via BluetoothUtils.cxx JNI
|
|
|
|
| |
remark: .. debug facility
|
|
|
|
|
| |
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.
|
|
|
|
| |
See commit 6f67d72923b31dd5db32227a0a8f46c11bc9a9f3
|
|
|
|
|
|
|
|
|
| |
exchange (MTU)
Certain devices might require more time for their first GATT response,
which usually shall lie within 500ms.
This patch tolerates 1500ms.
|
|
|
|
| |
and procedured WIP
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
RANDOM; L2CAPComm uses device->getAddressType()
Map BLERandomAddressType::STATIC_PUBLIC -> HCILEPeerAddressType::RANDOM
This only works for a static random address not changing at all,
i.e. between power-cycles - hence a temporary hack.
We need to use 'resolving list' and/or LE Set Privacy Mode (HCI) for all devices.
+++
L2CAPComm uses device->getAddressType(), i.e. no need for a (wrong) public argument flag.
|
|
|
|
| |
HCILEPeerAddressType/HCILEOwnAddressType String representation + API doc
|
|
|
|
|
| |
# Conflicts:
# api/direct_bt/linux_kernel_types.hpp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
if already discovered
Should max return 1, however, analyzing issue having no more devices being discovered.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Use HCIHandler *connect*/disconnect incl related events (Drop DBTManager in this regard)
> Add CONNECT_FAILED HCI listener mgmtEvConnectFailedHCI
-- Issuing a DISCONNECT event
> DBTAdapter: mgmtEvDeviceConnectedHCI
-- Always pass through, just issue WARNING if not a new_connect (TBD)
> DBTAdapter: mgmtEvDeviceDisconnectedHCI + mgmtEvDeviceConnectedHCI
-- removeConnectedDevice pre event issuing
-- removeDiscoveredDevice post event issuing
> DBTDevice:
-- Add isConnectIssued to differentiate isConnected on event
-- Only use HCIHandler's *connect*/disconnect
-- disconnect(..) no more issues removeConnectedDevice, rely ion correct event issuing/handling,
as performed in time @ mgmtEvDeviceDisconnectedHCI...
-- remove() issues removeConnectedDevice and removeDiscoveredDevice pre releaseSharedInstance
to ensure a clean tracking state. The whole purpose of this command.
+++
Enhance native + java test
After disconnect() wait (poll) until no more connected, before issuing remove(),
this shall ensure proper workflow pre remove() - validation of disconnect command.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
support incl HCI connection handle
We move *connect* and disconnect from DBTManager to HCIHandler,
as we need full control of the connection tracker due to:
- expose HCI connection handle to match actual session for disconnect
- control the disconnect on IOError (no command, purge tracker element and send event)
DBTManager::disconnect:
- no more used
- still aligned the 'send event' on ioerror code path
HCIHandler, DBTManager:
- Own callbacks for verbose mode only added in VERBOSE_ON compilation
|
|
|
|
| |
synchronized
|
|
|
|
| |
This potentially avoid a SIGSEGV in case of an error, i.e. destructed device instance.
|
|
|
|
| |
exception and return an empty list (on error/exception)
|
|
|
|
|
|
|
|
|
| |
sequential processing is ensured
GATTHandler servers one device, however, applications may utilize multithreading
and concurrent command requests may lead to wrong replies.
Similar to DBTManager and HCIHandler, top-level entries shall be synchronized.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|