/* * Author: Sven Gothel * Copyright (c) 2020 Gothel Software e.K. * Copyright (c) 2020 ZAFENA AB * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef GATT_DESCRIPTOR_HPP_ #define GATT_DESCRIPTOR_HPP_ #include #include #include #include #include #include #include #include "UUID.hpp" #include "BTTypes.hpp" #include "OctetTypes.hpp" #include "ATTPDUTypes.hpp" #include "DBTTypes.hpp" /** * - - - - - - - - - - - - - - - * * Module GATTDescriptor: * * - BT Core Spec v5.2: Vol 3, Part G Generic Attribute Protocol (GATT) * - BT Core Spec v5.2: Vol 3, Part G GATT: 2.6 GATT Profile Hierarchy */ namespace direct_bt { class DBTDevice; // forward class GATTHandler; // forward class GATTCharacteristic; // forward typedef std::shared_ptr GATTCharacteristicRef; /** * BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3 Characteristic Descriptor */ class GATTDescriptor : public DBTObject { private: /** Descriptor's characteristic weak back-reference */ std::weak_ptr wbr_characteristic; std::string toShortString() const noexcept; public: static const uuid16_t TYPE_EXT_PROP; static const uuid16_t TYPE_USER_DESC; static const uuid16_t TYPE_CCC_DESC; static std::shared_ptr getStaticType(const uuid16_t & type) noexcept { return std::shared_ptr(&type, [](const uuid_t *){}); } /** * Following UUID16 GATT profile attribute types are listed under: * BT Core Spec v5.2: Vol 3, Part G GATT: 3.4 Summary of GATT Profile Attribute Types */ enum Type : uint16_t { CHARACTERISTIC_APPEARANCE = 0x2A01, CHARACTERISTIC_PERIPHERAL_PRIV_FLAG = 0x2A02, CHARACTERISTIC_RECONNECTION_ADDRESS = 0x2A03, CHARACTERISTIC_PERIPHERAL_PREF_CONN = 0x2A04, CHARACTERISTIC_SERVICE_CHANGED = 0x2A05, /* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.1 Characteristic Extended Properties */ CHARACTERISTIC_EXTENDED_PROPERTIES = 0x2900, /* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.2 Characteristic User Description (Characteristic Descriptor, optional, single, string) */ CHARACTERISTIC_USER_DESCRIPTION = 0x2901, /* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration (Characteristic Descriptor, optional, single, uint16_t bitfield) */ CLIENT_CHARACTERISTIC_CONFIGURATION = 0x2902, /* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.4 Server Characteristic Configuration (Characteristic Descriptor, optional, single, bitfield) */ SERVER_CHARACTERISTIC_CONFIGURATION = 0x2903, /* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.5 Characteristic Presentation Format (Characteristic Descriptor, optional, single, complex) */ CHARACTERISTIC_PRESENTATION_FORMAT = 0x2904, CHARACTERISTIC_AGGREGATE_FORMAT = 0x2905, /** Our identifier to mark a custom vendor Characteristic Descriptor */ CUSTOM_CHARACTERISTIC_DESCRIPTION = 0x8888 }; /** Type of descriptor */ std::shared_ptr type; /** * Characteristic Descriptor Handle *

* Attribute handles are unique for each device (server) (BT Core Spec v5.2: Vol 3, Part F Protocol..: 3.2.2 Attribute Handle). *

*/ const uint16_t handle; /* Characteristics Descriptor's Value */ POctets value; GATTDescriptor(const GATTCharacteristicRef & characteristic, const std::shared_ptr & type_, const uint16_t handle_) noexcept : wbr_characteristic(characteristic), type(type_), handle(handle_), value(/* intentional zero sized */) {} std::string get_java_class() const noexcept override { return java_class(); } static std::string java_class() noexcept { return std::string(JAVA_DBT_PACKAGE "DBTGattDescriptor"); } std::shared_ptr getCharacteristicUnchecked() const noexcept { return wbr_characteristic.lock(); } std::shared_ptr getCharacteristicChecked() const; std::shared_ptr getGATTHandlerChecked() const; std::shared_ptr getDeviceChecked() const; virtual std::string toString() const noexcept override; /** Value is uint16_t bitfield */ bool isExtendedProperties() const noexcept { return TYPE_EXT_PROP == *type; } /* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration (Characteristic Descriptor, optional, single, uint16_t bitfield) */ bool isClientCharacteristicConfiguration() const noexcept{ return TYPE_CCC_DESC == *type; } /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.12.1 Read Characteristic Descriptor *

* BT Core Spec v5.2: Vol 3, Part G GATT: 4.12.2 Read Long Characteristic Descriptor *

*

* If expectedLength = 0, then only one ATT_READ_REQ/RSP will be used. *

*

* If expectedLength < 0, then long values using multiple ATT_READ_BLOB_REQ/RSP will be used until * the response returns zero. This is the default parameter. *

*

* If expectedLength > 0, then long values using multiple ATT_READ_BLOB_REQ/RSP will be used * if required until the response returns zero. *

*

* Convenience delegation call to GATTHandler via DBTDevice * If the DBTDevice's GATTHandler is null, i.e. not connected, an IllegalStateException is thrown. *

*/ bool readValue(int expectedLength=-1); /** * BT Core Spec v5.2: Vol 3, Part G GATT: 4.12.3 Write Characteristic Descriptors *

* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3 Characteristic Descriptor *

*

* BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration *

*

* Convenience delegation call to GATTHandler via DBTDevice * If the DBTDevice's GATTHandler is null, i.e. not connected, an IllegalStateException is thrown. *

*/ bool writeValue(); }; typedef std::shared_ptr GATTDescriptorRef; inline bool operator==(const GATTDescriptor& lhs, const GATTDescriptor& rhs) noexcept { return lhs.handle == rhs.handle; /** unique attribute handles */ } inline bool operator!=(const GATTDescriptor& lhs, const GATTDescriptor& rhs) noexcept { return !(lhs == rhs); } } // namespace direct_bt #endif /* GATT_DESCRIPTOR_HPP_ */