diff options
author | Sven Gothel <[email protected]> | 2020-07-24 10:00:15 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-07-24 10:00:15 +0200 |
commit | 3437e34c97c1dad0c4c0d27680371f693aadac4f (patch) | |
tree | 5e2e5ad9dd3351ad5e332ed2159a0e6f3428a92e /api | |
parent | a1e74bf1e23f4833261556e55612f34afc8dbcf1 (diff) |
Reworking GATTCharacteristicListener (C++ and Java)
- 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
Diffstat (limited to 'api')
-rw-r--r-- | api/direct_bt/DBTDevice.hpp | 38 | ||||
-rw-r--r-- | api/direct_bt/GATTCharacteristic.hpp | 116 | ||||
-rw-r--r-- | api/direct_bt/GATTHandler.hpp | 21 |
3 files changed, 141 insertions, 34 deletions
diff --git a/api/direct_bt/DBTDevice.hpp b/api/direct_bt/DBTDevice.hpp index 1ff1a2a4..4b8eb806 100644 --- a/api/direct_bt/DBTDevice.hpp +++ b/api/direct_bt/DBTDevice.hpp @@ -390,6 +390,44 @@ namespace direct_bt { * </p> */ void disconnectGATT(); + + /** + * Add the given {@link GATTCharacteristicListener} to the listener list if not already present. + * <p> + * Convenience delegation call to GATTHandler + * </p> + * @param listener A {@link GATTCharacteristicListener} instance, listening to all {@link BluetoothGattCharacteristic} events of this device + * @return true if the given listener is not element of the list and has been newly added, otherwise false. + * @throws IllegalStateException if the GATTHandler is null, i.e. not connected + */ + bool addCharacteristicListener(std::shared_ptr<GATTCharacteristicListener> l); + + /** + * Remove the given {@link GATTCharacteristicListener} from the listener list. + * <p> + * If the GATTHandler is null, i.e. not connected, {@code false} is being returned. + * </p> + * @param listener A {@link GATTCharacteristicListener} instance + * @return true if the given listener is an element of the list and has been removed, otherwise false. + */ + bool removeCharacteristicListener(std::shared_ptr<GATTCharacteristicListener> l); + + /** + * Remove all {@link GATTCharacteristicListener} from the list, which are associated to the given {@link GATTCharacteristic}. + * <p> + * Implementation tests all listener's GATTCharacteristicListener::match(const GATTCharacteristic & characteristic) + * to match with the given associated characteristic. + * </p> + * @param associatedCharacteristic the match criteria to remove any GATTCharacteristicListener from the list + * @return number of removed listener. + */ + int removeAllAssociatedCharacteristicListener(std::shared_ptr<GATTCharacteristic> associatedCharacteristic); + + /** + * Remove all {@link GATTCharacteristicListener} from the list. + * @return number of removed listener. + */ + int removeAllCharacteristicListener(); }; inline bool operator<(const DBTDevice& lhs, const DBTDevice& rhs) diff --git a/api/direct_bt/GATTCharacteristic.hpp b/api/direct_bt/GATTCharacteristic.hpp index 39f132fc..7734c35f 100644 --- a/api/direct_bt/GATTCharacteristic.hpp +++ b/api/direct_bt/GATTCharacteristic.hpp @@ -173,25 +173,32 @@ namespace direct_bt { /** * BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration * <p> - * Convenience delegation call to GATTHandler via DBTDevice + * Method enables notification and/or indication for this characteristic at BLE level. * </p> * <p> - * If the DBTDevice's GATTHandler is null, i.e. not connected, an IllegalStateException is thrown. + * Convenience delegation call to GATTHandler via DBTDevice * </p> * <p> * Implementation masks this Characteristic properties PropertyBitVal::Notify and PropertyBitVal::Indicate - * with the respective user request parameters, hence removes unsupported requests.<br> - * If the resulting combination for both requests is false, method returns false. - * </p> - * <p> - * Returns false if there is no GATTDescriptor of type ClientCharacteristicConfiguration, - * or if the operation has failed. - * </p> + * with the respective user request parameters, hence removes unsupported requests. + * </p> + * @param enableNotification + * @param enableIndication + * @param enabledState array of size 2, holding the resulting enabled state for notification and indication. + * @return false if this characteristic has no PropertyBitVal::Notify or PropertyBitVal::Indication present, + * or there is no GATTDescriptor of type ClientCharacteristicConfiguration, or if the operation has failed. + * Otherwise returns true. + * @throws IllegalStateException if notification or indication is set to be enabled + * and the {@link DBTDevice's}'s {@link GATTHandler} is null, i.e. not connected */ - bool configIndicationNotification(const bool enableNotification, const bool enableIndication, bool enableResult[2]); + bool configNotificationIndication(const bool enableNotification, const bool enableIndication, bool enabledState[2]); /** - * Add the given listener to the list if not already present. + * Add the given GATTCharacteristicListener to the listener list if not already present. + * <p> + * Occurring notifications and indications, if enabled via {@link #configNotificationIndication(bool, bool, bool[])}}, + * will call the respective GATTCharacteristicListener callback method. + * </p> * <p> * Returns true if the given listener is not element of the list and has been newly added, * otherwise false. @@ -200,61 +207,88 @@ namespace direct_bt { * Convenience delegation call to GATTHandler via DBTDevice * </p> * <p> - * If the DBTDevice's GATTHandler is null, i.e. not connected, an IllegalStateException is thrown. - * </p> - * <p> * To restrict the listener to listen only to this GATTCharacteristic instance, * user has to implement GATTCharacteristicListener::match(GATTCharacteristicRef) accordingly. * <br> - * For this purpose, use may derive from SpecificGATTCharacteristicListener, + * For this purpose, use may derive from AssociatedGATTCharacteristicListener, * which provides these simple matching filter facilities. * </p> + * @throws IllegalStateException if the {@link DBTDevice's}'s {@link GATTHandler} is null, i.e. not connected */ bool addCharacteristicListener(std::shared_ptr<GATTCharacteristicListener> l); /** - * Remove the given listener from the list. + * Add the given GATTCharacteristicListener to the listener list if not already present + * and if enabling the notification and/or indication for this characteristic at BLE level was successful. * <p> - * Returns true if the given listener is an element of the list and has been removed, + * Occurring notifications and indications will call the respective {@link GATTCharacteristicListener} + * callback method. + * </p> + * <p> + * Returns true if enabling the notification and/or indication was successful + * and if the given listener is not element of the list and has been newly added, * otherwise false. * </p> * <p> * Convenience delegation call to GATTHandler via DBTDevice + * performing both, configNotificationIndication(..) and addCharacteristicListener(..). * </p> * <p> - * If the DBTDevice's GATTHandler is null, i.e. not connected, an IllegalStateException is thrown. + * To restrict the listener to listen only to this GATTCharacteristic instance, + * user has to implement GATTCharacteristicListener::match(GATTCharacteristicRef) accordingly. + * <br> + * For this purpose, use may derive from AssociatedGATTCharacteristicListener, + * which provides these simple matching filter facilities. * </p> + * @param enabledState array of size 2, holding the resulting enabled state for notification and indication + * using {@link #configNotificationIndication(bool, bool, bool[])}} + * @throws IllegalStateException if the {@link DBTDevice's}'s {@link GATTHandler} is null, i.e. not connected */ - bool removeCharacteristicListener(std::shared_ptr<GATTCharacteristicListener> l); + bool addCharacteristicListener(std::shared_ptr<GATTCharacteristicListener> l, bool enabledState[2]); /** - * Remove the given listener from the list. + * Disables the notification and/or indication for this characteristic at BLE level + * if {@code disableIndicationNotification == true} + * and removes the given {@link GATTCharacteristicListener} from the listener list. * <p> * Returns true if the given listener is an element of the list and has been removed, * otherwise false. * </p> * <p> * Convenience delegation call to GATTHandler via DBTDevice + * performing addCharacteristicListener(..) + * and {@link #configNotificationIndication(bool, bool, bool[]) if {@code disableIndicationNotification == true}. * </p> * <p> - * If the DBTDevice's GATTHandler is null, i.e. not connected, an IllegalStateException is thrown. + * If the DBTDevice's GATTHandler is null, i.e. not connected, {@code false} is being returned. * </p> + * @param l + * @param disableIndicationNotification if true, disables the notification and/or indication for this characteristic + * using {@link #configNotificationIndication(bool, bool, bool[]) + * @return */ - bool removeCharacteristicListener(const GATTCharacteristicListener * l); + bool removeCharacteristicListener(std::shared_ptr<GATTCharacteristicListener> l, bool disableIndicationNotification); /** - * Remove all event listener from the list. + * Disables the notification and/or indication for this characteristic at BLE level + * if {@code disableIndicationNotification == true} + * and removes all {@link GATTCharacteristicListener} from the listener list. * <p> * Returns the number of removed event listener. * </p> * <p> * Convenience delegation call to GATTHandler via DBTDevice + * performing addCharacteristicListener(..) + * and configNotificationIndication(..) if {@code disableIndicationNotification == true}. * </p> * <p> - * If the DBTDevice's GATTHandler is null, i.e. not connected, an IllegalStateException is thrown. + * If the DBTDevice's GATTHandler is null, i.e. not connected, {@code zero} is being returned. * </p> + * @param disableIndicationNotification if true, disables the notification and/or indication for this characteristic + * using {@link #configNotificationIndication(bool, bool, bool[]) + * @return */ - int removeAllCharacteristicListener(); + int removeAllCharacteristicListener(bool disableIndicationNotification); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.8.1 Read Characteristic Value @@ -319,6 +353,9 @@ namespace direct_bt { * see method's API doc for {@link GATTCharacteristic} filtering. * </p> * <p> + * User may utilize {@link AssociatedGATTCharacteristicListener} to listen to only one {@link GATTCharacteristic}. + * </p> + * <p> * A listener instance may be attached to a {@link GATTHandler} via * {@link GATTHandler::addCharacteristicListener(std::shared_ptr<GATTCharacteristicListener>)} * to listen to all events of the device or the matching filtered events. @@ -345,9 +382,24 @@ namespace direct_bt { return true; } + /** + * Called from native BLE stack, initiated by a received notification associated + * with the given {@link GATTCharacteristic}. + * @param charDecl {@link GATTCharacteristic} related to this notification + * @param charValue the notification value + * @param timestamp the indication monotonic timestamp, see getCurrentMilliseconds() + */ virtual void notificationReceived(GATTCharacteristicRef charDecl, std::shared_ptr<TROOctets> charValue, const uint64_t timestamp) = 0; + /** + * Called from native BLE stack, initiated by a received indication associated + * with the given {@link GATTCharacteristic}. + * @param charDecl {@link GATTCharacteristic} related to this indication + * @param charValue the indication value + * @param timestamp the indication monotonic timestamp, see {@link BluetoothUtils#getCurrentMilliseconds()} + * @param confirmationSent if true, the native stack has sent the confirmation, otherwise user is required to do so. + */ virtual void indicationReceived(GATTCharacteristicRef charDecl, std::shared_ptr<TROOctets> charValue, const uint64_t timestamp, const bool confirmationSent) = 0; @@ -367,22 +419,22 @@ namespace direct_bt { { return !(*this == rhs); } }; - class SpecificGATTCharacteristicListener : public GATTCharacteristicListener{ + class AssociatedGATTCharacteristicListener : public GATTCharacteristicListener{ private: - const GATTCharacteristic * characteristicMatch; + const GATTCharacteristic * associatedCharacteristic; public: /** - * Passing the specific GATTCharacteristic to filter out non matching events. + * Passing the associated GATTCharacteristic to filter out non matching events. */ - SpecificGATTCharacteristicListener(const GATTCharacteristic * characteristicMatch) - : characteristicMatch(characteristicMatch) { } + AssociatedGATTCharacteristicListener(const GATTCharacteristic * characteristicMatch) + : associatedCharacteristic(characteristicMatch) { } bool match(const GATTCharacteristic & characteristic) override { - if( nullptr == characteristicMatch ) { + if( nullptr == associatedCharacteristic ) { return true; } - return *characteristicMatch == characteristic; + return *associatedCharacteristic == characteristic; } }; diff --git a/api/direct_bt/GATTHandler.hpp b/api/direct_bt/GATTHandler.hpp index 99d5d7ad..40162184 100644 --- a/api/direct_bt/GATTHandler.hpp +++ b/api/direct_bt/GATTHandler.hpp @@ -106,7 +106,7 @@ namespace direct_bt { /** send immediate confirmation of indication events from device, defaults to true. */ bool sendIndicationConfirmation = true; - std::vector<std::shared_ptr<GATTCharacteristicListener>> eventListenerList; + std::vector<std::shared_ptr<GATTCharacteristicListener>> characteristicListenerList; std::recursive_mutex mtx_eventListenerList; uint16_t serverMTU; @@ -310,10 +310,13 @@ namespace direct_bt { /** * BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration * <p> + * Method enables notification and/or indication for the corresponding characteristic at BLE level. + * </p> + * <p> * Throws an IllegalArgumentException if the given GATTDescriptor is not a ClientCharacteristicConfiguration. * </p> */ - bool configIndicationNotification(GATTDescriptor & cd, const bool enableNotification, const bool enableIndication); + bool configNotificationIndication(GATTDescriptor & cd, const bool enableNotification, const bool enableIndication); /** * Add the given listener to the list if not already present. @@ -341,8 +344,22 @@ namespace direct_bt { * </p> */ bool removeCharacteristicListener(const GATTCharacteristicListener * l); + /** + * Remove all {@link GATTCharacteristicListener} from the list, which are associated to the given {@link GATTCharacteristic}. + * <p> + * Implementation tests all listener's GATTCharacteristicListener::match(const GATTCharacteristic & characteristic) + * to match with the given associated characteristic. + * </p> + * @param associatedCharacteristic the match criteria to remove any GATTCharacteristicListener from the list + * @return number of removed listener. + */ + int removeAllAssociatedCharacteristicListener(std::shared_ptr<GATTCharacteristic> associatedCharacteristic); + + int removeAllAssociatedCharacteristicListener(const GATTCharacteristic * associatedCharacteristic); + + /** * Remove all event listener from the list. * <p> * Returns the number of removed event listener. |