54#define CHAR_DECL_PROPS_ENUM(X) \
55 X(BTGattChar,Broadcast,broadcast) \
56 X(BTGattChar,Read,read) \
57 X(BTGattChar,WriteNoAck,write-noack) \
58 X(BTGattChar,WriteWithAck,write-ack) \
59 X(BTGattChar,Notify,notify) \
60 X(BTGattChar,Indicate,indicate) \
61 X(BTGattChar,AuthSignedWrite,authenticated-signed-writes) \
62 X(BTGattChar,ExtProps,extended-properties)
76#define CASE2_TO_STRING2(U,V,W) case U::V: return #W;
83 return "Unknown property";
88 const uint8_t
one = 1;
91 for(
int i=0; i<8; i++) {
93 if( none != ( mask & propertyBit ) ) {
94 if( has_pre ) { out.append(
", "); }
103std::shared_ptr<BTGattDesc> BTGattChar::findGattDesc(
const jau::uuid_t& desc_uuid)
noexcept {
104 const size_t descriptors_size = descriptorList.size();
105 for(
size_t j = 0; j < descriptors_size; j++) {
107 if(
nullptr != descriptor && desc_uuid == *(descriptor->type) ) {
114std::string BTGattChar::toString() const noexcept {
115 std::string char_name =
"";
116 std::string desc_str;
118 if( uuid_t::TypeSize::UUID16_SZ ==
value_type->getTypeSize() ) {
124 if(
nullptr != ud ) {
125 char_name.append(
", '" +
dfa_utf8_decode( ud->value.get_ptr(), ud->value.size() ) +
"'");
130 desc_str =
", descr[";
141 std::string notify_str;
151std::string BTGattChar::toShortString() const noexcept {
152 std::string char_name;
154 if( uuid_t::TypeSize::UUID16_SZ ==
value_type->getTypeSize() ) {
160 if(
nullptr != ud ) {
161 char_name.append(
", '" +
dfa_utf8_decode( ud->value.get_ptr(), ud->value.size() ) +
"'");
164 std::string notify_str;
176 return s->getGattHandlerUnchecked();
184 return s->getDeviceUnchecked();
190 enabledState[0] =
false;
191 enabledState[1] =
false;
195 if( !hasEnableNotification && !hasEnableIndication ) {
196 DBG_PRINT(
"Characteristic has neither Notify nor Indicate property present: %s", toString().c_str());
200 std::shared_ptr<BTDevice> device = getDeviceUnchecked();
201 std::shared_ptr<BTGattHandler> gatt =
nullptr != device ? device->getGattHandler() :
nullptr;
202 if(
nullptr == gatt ) {
203 if( !enableNotification && !enableIndication ) {
205 DBG_PRINT(
"Characteristic's device GATTHandle not connected: %s", toShortString().c_str());
207 ERR_PRINT(
"Characteristic's device GATTHandle not connected: %s", toShortString().c_str());
211 const bool resEnableNotification = hasEnableNotification && enableNotification;
212 const bool resEnableIndication = hasEnableIndication && enableIndication;
214 if( resEnableNotification == enabledNotifyState &&
215 resEnableIndication == enabledIndicateState )
217 enabledState[0] = resEnableNotification;
218 enabledState[1] = resEnableIndication;
219 DBG_PRINT(
"GATTCharacteristic::configNotificationIndication: Unchanged: notification[shall %d, has %d: %d == %d], indication[shall %d, has %d: %d == %d]",
220 enableNotification, hasEnableNotification, enabledNotifyState, resEnableNotification,
221 enableIndication, hasEnableIndication, enabledIndicateState, resEnableIndication);
226 if(
nullptr == cccd ) {
227 DBG_PRINT(
"Characteristic has no ClientCharacteristicConfig descriptor: %s", toString().c_str());
230 bool res = gatt->configNotificationIndication(*cccd, resEnableNotification, resEnableIndication);
231 DBG_PRINT(
"GATTCharacteristic::configNotificationIndication: res %d, notification[shall %d, has %d: %d -> %d], indication[shall %d, has %d: %d -> %d]",
233 enableNotification, hasEnableNotification, enabledNotifyState, resEnableNotification,
234 enableIndication, hasEnableIndication, enabledIndicateState, resEnableIndication);
236 enabledNotifyState = resEnableNotification;
237 enabledIndicateState = resEnableIndication;
238 enabledState[0] = resEnableNotification;
239 enabledState[1] = resEnableIndication;
248 const bool enableNotification = hasEnableNotification;
249 const bool enableIndication = !enableNotification && hasEnableIndication;
251 return configNotificationIndication(enableNotification, enableIndication, enabledState);
255 bool enabledState[2];
261 if(
nullptr == device ) {
262 ERR_PRINT(
"Characteristic's device null: %s", toShortString().c_str());
266 if(
nullptr == service ) {
267 ERR_PRINT(
"Characteristic's service null: %s", toShortString().c_str());
271 if(
nullptr == service ) {
272 ERR_PRINT(
"Characteristic not in service: %s", toShortString().c_str());
275 return device->addCharListener(l, characteristic);
279 if( !enableNotificationOrIndication(enabledState) ) {
282 return addCharListener(l);
286 std::shared_ptr<BTDevice> device = getDeviceUnchecked();
287 if(
nullptr == device ) {
288 ERR_PRINT(
"Characteristic's device null: %s", toShortString().c_str());
291 return device->removeCharListener(l);
295 if( shallDisableIndicationNotification ) {
296 disableIndicationNotification();
298 std::shared_ptr<BTDevice> device = getDeviceUnchecked();
299 if(
nullptr == device ) {
300 ERR_PRINT(
"Characteristic's device null: %s", toShortString().c_str());
303 return device->removeAllAssociatedCharListener(
this);
307 std::shared_ptr<BTDevice> device = getDeviceUnchecked();
308 if(
nullptr == device ) {
309 ERR_PRINT(
"Characteristic's device null: %s", toShortString().c_str());
312 std::shared_ptr<BTGattHandler> gatt = device->getGattHandler();
313 if(
nullptr == gatt ) {
314 ERR_PRINT(
"Characteristic's device GATTHandle not connected: %s", toShortString().c_str());
317 return gatt->readCharacteristicValue(*
this, res, expectedLength);
323 std::shared_ptr<BTDevice> device = getDeviceUnchecked();
324 if(
nullptr == device ) {
325 ERR_PRINT(
"Characteristic's device null: %s", toShortString().c_str());
328 std::shared_ptr<BTGattHandler> gatt = device->getGattHandler();
329 if(
nullptr == gatt ) {
330 ERR_PRINT(
"Characteristic's device GATTHandle not connected: %s", toShortString().c_str());
333 return gatt->writeCharacteristicValue(*
this, value);
340 std::shared_ptr<BTDevice> device = getDeviceUnchecked();
341 if(
nullptr == device ) {
342 ERR_PRINT(
"Characteristic's device null: %s", toShortString().c_str());
345 std::shared_ptr<BTGattHandler> gatt = device->getGattHandler();
346 if(
nullptr == gatt ) {
347 ERR_PRINT(
"Characteristic's device GATTHandle not connected: %s", toShortString().c_str());
350 return gatt->writeCharacteristicValueNoResp(*
this, value);
static std::string _getPropertyBitValStr(const BTGattChar::PropertyBitVal prop) noexcept
#define CASE2_TO_STRING2(U, V, W)
"reliable-write" "writable-auxiliaries" "encrypt-read" "encrypt-write" "encrypt-authenticated-read" "...
#define CHAR_DECL_PROPS_ENUM(X)
BTGattChar event listener for notification and indication events.
BTGattServiceRef getServiceUnchecked() const noexcept
ssize_type clientCharConfigIndex
std::unique_ptr< const jau::uuid_t > value_type
bool disableIndicationNotification() noexcept
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration.
BTGattHandlerRef getGattHandlerUnchecked() const noexcept
bool addCharListener(const BTGattCharListenerRef &l) noexcept
Add the given BTGattCharListener to the listener list if not already present.
const uint16_t handle
Characteristic Handle of this instance.
BTDeviceRef getDeviceUnchecked() const noexcept
BTGattDescRef getUserDescription() const noexcept
Return the User Description BTGattDescRef if available or nullptr.
const PropertyBitVal properties
const uint16_t value_handle
Characteristics Value Handle.
bool removeCharListener(const BTGattCharListenerRef &l) noexcept
Remove the given associated BTGattCharListener from the listener list if present.
bool configNotificationIndication(const bool enableNotification, const bool enableIndication, bool enabledState[2]) noexcept
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration.
bool enableNotificationOrIndication(bool enabledState[2]) noexcept
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration.
size_type removeAllAssociatedCharListener(bool shallDisableIndicationNotification) noexcept
Removes all associated BTGattCharListener and and BTGattCharListener from the listener list.
PropertyBitVal
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.1.1 Characteristic Properties.
bool hasProperties(const PropertyBitVal v) const noexcept
bool writeValue(const jau::TROOctets &value) noexcept
BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value.
jau::darray< BTGattDescRef > descriptorList
List of Characteristic Descriptions as shared reference.
bool readValue(jau::POctets &res, int expectedLength=-1) noexcept
BT Core Spec v5.2: Vol 3, Part G GATT: 4.8.1 Read Characteristic Value.
bool writeValueNoResp(const jau::TROOctets &value) noexcept
BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response.
Persistent endian aware octet data, i.e.
Transient read only and endian aware octet data, i.e.
constexpr size_type size() const noexcept
Like std::vector::size().
#define ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
#define DBG_PRINT(...)
Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] De...
uint32_t dfa_utf8_decode(uint32_t &state, uint32_t &codep, const uint32_t byte_value)
std::string to_string(const alphabet &v) noexcept
#define JAU_TYPENAME_CUE(A)
const char * type_name() noexcept
Returns the type name of given type T using template Compile Time Type Information (CTTI) only via RT...
std::shared_ptr< BTGattHandler > BTGattHandlerRef
std::shared_ptr< BTDevice > BTDeviceRef
std::string to_string(const DiscoveryPolicy v) noexcept
std::string GattCharacteristicTypeToString(const GattCharacteristicType v) noexcept
GattCharacteristicType
GATT Assigned Characteristic Attribute Type for single logical value.
std::shared_ptr< BTGattCharListener > BTGattCharListenerRef
std::shared_ptr< BTGattChar > BTGattCharRef
std::shared_ptr< BTGattService > BTGattServiceRef
std::shared_ptr< BTGattDesc > BTGattDescRef
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
constexpr const jau::fraction_i64 one(1l, 1lu)
one is 10^0 or 1/1
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
static const char * name()
Return the string representation of this type.