| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
cycle, allowing TO detection
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Comparing native and java performance numbers:
- similar results
- java seems to be less responsive, esp for CONNECT
- CONNECT performance in general seems to vary a lot
and brings down overal performance
Native:
==========
dbt10-native-01.log:PERF: adapter-init -> FOUND__-0 292 ms
dbt10-native-01.log:PERF: adapter-init -> CONNECTED-0 2489 ms
dbt10-native-01.log:PERF: GATT primary-services completed
dbt10-native-01.log:PERF: adapter-init to processing-start 2499 ms,
dbt10-native-01.log:PERF: get-gatt-services 1117 ms,
dbt10-native-01.log:PERF: discovered to gatt-complete 1127 ms (connect 10 ms),
dbt10-native-01.log:PERF: adapter-init to gatt-complete 3616 ms
dbt10-native-02.log:PERF: adapter-init -> FOUND__-0 317 ms
dbt10-native-02.log:PERF: adapter-init -> CONNECTED-0 572 ms
dbt10-native-02.log:PERF: GATT primary-services completed
dbt10-native-02.log:PERF: adapter-init to processing-start 577 ms,
dbt10-native-02.log:PERF: get-gatt-services 1108 ms,
dbt10-native-02.log:PERF: discovered to gatt-complete 1113 ms (connect 5 ms),
dbt10-native-02.log:PERF: adapter-init to gatt-complete 1685 ms
dbt10-native-03.log:PERF: adapter-init -> CONNECTED-0 1865 ms
dbt10-native-03.log:PERF: GATT primary-services completed
dbt10-native-03.log:PERF: adapter-init to processing-start 1872 ms,
dbt10-native-03.log:PERF: get-gatt-services 1502 ms,
dbt10-native-03.log:PERF: discovered to gatt-complete 1510 ms (connect 8 ms),
dbt10-native-03.log:PERF: adapter-init to gatt-complete 3374 ms
dbt10-native-04.log:PERF: adapter-init -> FOUND__-0 459 ms
dbt10-native-04.log:PERF: adapter-init -> CONNECTED-0 715 ms
dbt10-native-04.log:PERF: GATT primary-services completed
dbt10-native-04.log:PERF: adapter-init to processing-start 727 ms,
dbt10-native-04.log:PERF: get-gatt-services 1108 ms,
dbt10-native-04.log:PERF: discovered to gatt-complete 1120 ms (connect 12 ms),
dbt10-native-04.log:PERF: adapter-init to gatt-complete 1835 ms
Java:
==========
dbt10-java-01.log:PERF: adapter-init -> FOUND__-0 1866 ms
dbt10-java-01.log:PERF: adapter-init -> CONNECTED-0 2343 ms
dbt10-java-01.log:PERF: GATT primary-services completed
dbt10-java-01.log:PERF: adapter-init to processing-start 2352 ms,
dbt10-java-01.log:PERF: get-gatt-services 1118 ms,
dbt10-java-01.log:PERF: discovered to gatt-complete 1128 ms (connect 10 ms),
dbt10-java-01.log:PERF: adapter-init to gatt-complete 3470 ms
dbt10-java-02.log:PERF: adapter-init -> FOUND__-0 1046 ms
dbt10-java-02.log:PERF: adapter-init -> CONNECTED-0 1299 ms
dbt10-java-02.log:PERF: GATT primary-services completed
dbt10-java-02.log:PERF: adapter-init to processing-start 1310 ms,
dbt10-java-02.log:PERF: get-gatt-services 1119 ms,
dbt10-java-02.log:PERF: discovered to gatt-complete 1135 ms (connect 16 ms),
dbt10-java-02.log:PERF: adapter-init to gatt-complete 2429 ms
dbt10-java-03.log:PERF: adapter-init -> FOUND__-0 1626 ms
dbt10-java-03.log:PERF: adapter-init -> CONNECTED-0 1870 ms
dbt10-java-03.log:PERF: GATT primary-services completed
dbt10-java-03.log:PERF: adapter-init to processing-start 1883 ms,
dbt10-java-03.log:PERF: get-gatt-services 1132 ms,
dbt10-java-03.log:PERF: discovered to gatt-complete 1147 ms (connect 15 ms),
dbt10-java-03.log:PERF: adapter-init to gatt-complete 3015 ms
dbt10-java-04.log:PERF: adapter-init -> FOUND__-0 189 ms
dbt10-java-04.log:PERF: adapter-init -> CONNECTED-0 441 ms
dbt10-java-04.log:PERF: GATT primary-services completed
dbt10-java-04.log:PERF: adapter-init to processing-start 454 ms,
dbt10-java-04.log:PERF: get-gatt-services 1131 ms,
dbt10-java-04.log:PERF: discovered to gatt-complete 1145 ms (connect 14 ms),
dbt10-java-04.log:PERF: adapter-init to gatt-complete 1585 ms
|
|
|
|
|
|
|
| |
lastUpdate: getLastUpdateTimestamp()
For performance measurement discovery -> gatt complete,
we need to use the last discovery timestamp, since the device could have been created earlier.
|
|
|
|
|
|
|
| |
processConnectedDevice(),
ensuring a pending connection command from a failed connect*(..) attempt
will also have discovery disabled.
|
|
|
|
| |
VERBOSE and DEBUG. Use the latter in DBTManager.
|
|
|
|
| |
GATTHandler::State for L2CAPComm::State
|
|
|
|
| |
section with reference to used algo
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Misc..
Introduce HCITypes + HCIHandler: Providing C++ basics for full HCI support
============================================================================
- HCITypes defines the HCI command and event data structures,
similar to MgmtTypes and ATTPDUTypes.
For more coding efficiency we use template command and event classes, allowing to reuse
the HCIIoctl struct types being wrapped in the C++ classes
for flow and lifecycle control.
HCITypes further includes all essential 'enum class' command opcodes, event types etc,
ensuring type safety.
- HCIHandler defines the command/event workflow similar to GATTHandler and DBTManager.
One HCIHandler per DBTAdapter is being used, each HCIHandler using its
event reader thread and ringbuffer.
Socket event filtering and manual le-meta filtering ensures reduced workload (DoS safety).
Similar to HCITypes, we use template function to utilize
the template command and event classes, reuising the HCIIoctl struct types...
HCIHandler can be extended for more functionality as well as used to implement
our own DBTManager, i.e. Reducing HCIEvents to MgmtEvents with callback support.
At least this is a viable option now, if so desired (non-linux, etc).
- HCIComm: Contains the core I/O functionality only, dropped all semantic HCI code.
The latter resides in HCIHandler now.
- DBTAdapter now uses HCIHander instead of HCIComm, renamed field to simply 'hci'
Misc..
=======
- reduced all ringbuffer capacity to 128 from 256
- Moved Mgmt*EventCallback from DBTManager to MgmtTypes,
as we might want to reuse the MgmtTypes incl callbacks
for alternative DBTManager implementations.
- Added 'enum class' to underlying number type conversion pattern:
<NumberType> number('enum class type')
Avoiding the many static_cast<NumberType>(..) directives.
- align all Type -> String method names: 'get<Type>String(Type)'
- BasicTypes: Add safe uint32_t bitfield mask helper
|
| |
|
|
|
|
|
|
|
| |
(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.
|
|
|
|
| |
case, skip devices-in-processing
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
- Only WHITELIST and !WHITELIST discovery mode, remove confusion of 'esotheric' use case 'keepDiscovery'
- Use simple address lists for processed and processing devices
- Catch exception while processing GATT and add device processed on success
|
|
|
|
| |
disconnect
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
connection to BDADDR_LE_PUBLIC
BDADDR_LE_RANDOM connection attempts to some foreign BLE devices 'floating around'
causes the HCI sub-system to 'give up', i.e. no more connection will be possible
after a number of failures.
This is the use case w/o whitelist and without filtering for a specific MAC.
It seems that the following configurations (use cases) are stable:
- filter for a specific MAC and connect to these only
- use autoconnect whitelist to specific MAC
|
|
|
|
|
|
|
| |
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::toString(..) defaults to not incl. services
|
|
|
|
|
|
|
|
|
|
| |
dbt_scanner10
Some issues still:
- disconnect HCI command failure (same w/ native code, need to check)
- Whitelist command OK but no connection at all.
'-mac address' use-case is working
|
|
|
|
| |
Characteristic values, exposing human readable string portions
|
|
|
|
|
|
| |
ignore a failure as connect will happen
Investigating this situation a bit further.
|
|
|
|
| |
required - soothing API usage and JNI binding as well
|
|
|
|
| |
failed in block_discovery mode
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In both classes, certain fields must be handled atomic to avoid data race conditions.
GATTHandler: Store pthread_id of l2capReaderThread at creation before detaching,
since post detach the pthread_id native_handle() is null.
L2CAP's ::connect() call must be interruptable by it's disconnect to avoid
a long timeout hang.
DBTDevice's notifyDisconnected() issues a disconnect() on GATTHandler and L2CAPComm.
+++
This change set enables recovery of attempting to process a 'non GATT responding' device.
The DISCONNECT event breaks up the connection attempt, as being sent for such devices by the adapter.
|
|
|
|
| |
multi-device-threading test
|
|
|
|
|
|
| |
min/max ce_len,filter params
Show device on connection failure.
|
|
|
|
|
|
|
|
|
|
|
| |
GenericAccess after GATT discovery and update data (name)
As there is no need to discover the GATT services more than once, we shall reuse the already stored GATTService list in GATTHandler.
For the auto-connect whitelist use case (dbt_scanner10) w/o _any_ HCI discovery,
the connected LE device has no name set. Hence we retrieve the GATT GenericAccess data
and update the DBTDevice's name and appearance.
Eventually after getGATTServices(), the device name is set!
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
1+ second slower)
Essential for the whitelist autoconnect is the 'action' parameter,
which is now declared as HCIWhitelistConnectType (BTTypes).
BlueZ Linux kernel sources describe the semantics.
We are now technically enabled to use the auto-connect
and don't even required a discovery phase.
However, the device name is not included in the connect EIR data.
Further, performance lacks heavily similar to no connect
and is more than 1s slower than our procedure below:
- startDiscovery
- device-found
- stopDiscovery
- connect
- GATT operation
...
- startDiscovery
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
multithreading test
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
-disconnect, try all LE devices
TODO: Incorporate the discovery halt in the API .. maybe
+ device->getAdapter().stopDiscovery();
+ device->disconnect();
+ device->getAdapter().startDiscovery();
However, a running discovery reduces GATT performance
and should be adjusted with the application logic.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
DBTAdapter:
- Add HCI mutex
- openHCI() returns already open HCIComm
- Notify device on disconnected
DBTDevice:
- Add data mutex, covering race-condition on data update(..) and data usage
- notifyDisconnected(): Clear hciConnHandle
- getServices() -> getGATTServices() to differenciate from scan-result
+++
Java/JNI DBTAdapter:
- Remove open/openImpl() in favor of implicit openHCI() @ connect call.
+++
Added multithreading example dbt_scanner10.cpp
|
| |
|
|
|
|
| |
HCIComm directly
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
option (default = true)
Via DBTManager.setUnifyUUID128Bit(boolean):
Enables or disables uuid128_t consolidation
for native uuid16_t and uuid32_t values before string conversion.
Default is {@code true}, as this represent compatibility with original TinyB D-Bus behavior.
If desired, this value should be set once before the first call of {@link #getBluetoothManager()}!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'technical' GATTHandler
GATT Types made fully functional for user to avoid 'technical' GATTHandler (C++)
> GATTService, GATTCharacteristic, GATTDescriptor
-- Reside in their own respective files
-- Added semantic methods (readValue(), ..) implemented using DBTDevice -> GATTHandler
-- GATTDescriptor owns its value
-- GATTHandler setSendIndicationConfirmation(..) defaults to true
-- Allow user to cirvumvent using GATTHandler manually completely,
device 1--*> services 1--*> characteristics 1--*> descriptor
-- C++ GATT types aligned 1:1 to TinyB (Java)
> Merged GATTIndicationListener + GATTNotificationListener -> GATTCharacteristicListener
-- Simplifying usage, unifying notification and indication
-- Now using a list of shared_ptr<GATTCharacteristicListener> allowing multiple actors
instead of just a one shot entry. Similar to AdapterStatusListener,
we utilize this also on the Java side to implement the TinyB notifications.
See dbt_scanner00.cpp: Simplified high-level usage.
See dbt_scanner01.cpp: Lower-level technical usage w/ GATTHandler.
+++
> Simplified more names
> Removed redundancy in listener callbacks,
-- don't pass adapter when device is already given.
device <*--1> adapter
-- don't pass GATT handle explicitly when characteristic is passed
> Comparison of all GATT types are done by their respective unique handle
Attribute handles are unique for each device (server) (BT Core Spec v5.2: Vol 3, Part F Protocol..: 3.2.2 Attribute Handle)
> GATTHandler: Own L2CAPComm instance directly, instead of shared_ptr.
> JNIMem: Added JNICriticalArray class for RAII style release
++++
++++
Working GATT Java Side
> All toString() methods return the C++ toString() via JNI for better representation.
> DBTDevice.java/JNI: Resolved the odd 'adapter' reference issue:
-- Was not passing the jobject of DBTAdapter, but its shared container refeference ;-)
> All GATT types receive their GATT handler for equal test and identity @ ctor
> GATT read/write Value update the cached value as well as issue the notifyValue on change,
including GATTCharacteristic notification/indication listener
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
reasonable and efficient traversal...
GATT Cleanup of method + field names
- the service and characteristic uuid's specify types, hence name field *type* being of value-type uuid_t.
- use short and clear names like 'Characteristic' and simply 'Descriptor' for 'Characteristic Descriptor'.
- etc etc
GATT discoverDescriptors: Use more reasonable and efficient traversal through Charactecteristics
- Previous we traversed through all handle of services for Descriptors,
only to find the matching Charactecteristic to attach to.
The latter was done via another loop through all Charactecteristic and hence even reduced
performance by one magnitude.
Further, not all handles reflect Descriptors ;-)
- Simply iterate through all Charactecteristic and find their Descriptors within
their value handle range as per BT spec.
Also read the Descriptor value right away.
|
|
|
|
| |
Descriptor)
|
|
|
|
|
|
|
|
|
|
|
|
| |
Cleanup GATT type names aligned to TinyB.
Remove unused types.
Complete relationship: Descriptor <*-1> Characteristic <*-1> Service,
read all Descriptor with value instead of only ClientCharacteristicConfig.
Prepate for GATT Descriptor: Extended properties etc, TODO: parse!
Add JavaUplink, preparing for JNI.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
DBTDevice
- don't native delete @ JNI deleteImpl, adapter holds share_ptr ownership
- only create its java object 1st time @ deviceFound callback of JNI DBTAdapter
DBTAdapter::mgmtEvDeviceFoundCB
- in case of !discoveredDeviceList but sharedDeviceList,
the device shall be updated first,
then deviceFound callbacks issued, allowing listener to act and register,
then deviceUpdate callbacks issued, allowing data update on existing actors
DBTManager.java:
- Add ShutdownHook calling custom hooks and shutdown()
- shutdown() in depth shutdown:
-- iterated through all adapter issueing adapter.close()
-- Adapter.close() iterates through all discoveredDevices issuing close()
DBTDevice.java:
- adds adapter JNI proxy to removeStatusListener(..), same 'to be resolved' issue
as with addStatusListener(..).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
****** Loop 3
Caught: Inconsistent discovered device count: Native 3, callback 1
java.lang.InternalError: Inconsistent discovered device count: Native 3, callback 1
at direct_bt.tinyb.DBTAdapter.removeDevices(DBTAdapter.java:280)
at direct_bt.tinyb.DBTAdapter.startDiscovery(DBTAdapter.java:249)
at ScannerTinyB01.main(ScannerTinyB01.java:194)
...
Exception thrown due to discoveredDevices differences of native / java side.
We may resolve this issue or allow such case.
However, we need to properly shutdown the native direct_bt
before the VM exits - otherwise we won't be able handle the lost Java references.
TODO: Add a java shutdown hook!
|
|
|
|
| |
closing w/o being connected
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Commit 09cd1183b3599357b05c426e2b59e8df813304c5 describes existed issue
in a multi device and hence multi-device-discovery environment.
(The change has been reverted)
This changed resolves the shared device reference usage,
by having adapter maintaining a 'sharedDevices' list
in parallel to the 'discoveredDevices'.
Adapter will add a newly found and created device
to both lists, shared- and discovered devices.
Device may remove itself from the sharedDevices list
via remove() and its destructor.
Adapter will also look in sharedDevices in connected and found
callback to determine if a device is known and re-adds it
to the discovered devices list for consistency.
(Note: discoveredDevices may be flushed via a new startDiscovery)
|
|
|
|
|
|
|
|
| |
direct_bt, ..
.. however, keeping discovery alive while GATT processing will [naturally] slow down performance.
Therefor, discovery should be stopped before GATT processing if possible.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
relationship
GATTServiceDecl: Add DBTDevice reference and 'isPrimary'
GATTCharacterisicsDecl: Add GATTServiceDecl reference
and remove now obsolete copies of service_uuid and service_handle_end.
+++
GattHandler only have ctor w/ DBTDevice reference hence
and pass the GATTServiceDeclRef by reference itself (efficiency).
+++
TODO: Add the JNI code and complete the GATT Java binding
to access native GATTServiceDecl + GATTCharacterisicsDecl mapping
and also support the read/write functionality via GATTHandler.
|
|
|
|
| |
JavaUplink base to GATTCharacterisicsDecl + GATTServiceDecl
|