44 #define CHAR_DECL_PROPS_ENUM(X) \
45 X(BTGattChar,Broadcast,broadcast) \
46 X(BTGattChar,Read,read) \
47 X(BTGattChar,WriteNoAck,write-without-response) \
48 X(BTGattChar,WriteWithAck,write) \
49 X(BTGattChar,Notify,notify) \
50 X(BTGattChar,Indicate,indicate) \
51 X(BTGattChar,AuthSignedWrite,authenticated-signed-writes) \
52 X(BTGattChar,ExtProps,extended-properties)
66 #define CASE2_TO_STRING2(U,V,W) case U::V: return #W;
73 return "Unknown property";
78 const uint8_t one = 1;
81 for(
int i=0; i<8; i++) {
83 if( none != ( properties & propertyBit ) ) {
84 if( has_pre ) { out.append(
", "); }
96 const uint8_t one = 1;
97 for(
int i=0; i<8; i++) {
99 if( none != ( properties & propertyBit ) ) {
107 uint16_t service_handle_end = 0xffff;
109 std::string service_uuid_str =
"";
110 std::string service_name =
"";
111 std::string char_name =
"";
112 std::string desc_str =
", descr[ ";
114 if(
nullptr != serviceRef ) {
115 std::unique_ptr<const uuid_t> & service_uuid = serviceRef->type;
116 service_uuid_str = service_uuid->
toString();
117 service_handle_end = serviceRef->endHandle;
120 const uint16_t uuid16 = (
static_cast<const uuid16_t*
>(service_uuid.get()))->value;
125 const uint16_t uuid16 = (
static_cast<const uuid16_t*
>(value_type.get()))->value;
128 for(
size_t i=0; i<descriptorList.size(); i++) {
130 desc_str += cd->toString() +
", ";
134 ", value[type 0x"+value_type->toString()+
", handle "+
to_hexstring(value_handle)+char_name+desc_str+
135 "], service[type 0x"+service_uuid_str+
140 std::string BTGattChar::toShortString() const noexcept {
141 std::string char_name =
"";
144 const uint16_t uuid16 = (
static_cast<const uuid16_t*
>(value_type.get()))->value;
155 std::shared_ptr<BTGattService> ref = wbr_service.lock();
156 if(
nullptr == ref ) {
163 std::shared_ptr<BTGattService> s = getServiceUnchecked();
171 return getServiceChecked()->getGattHandlerChecked();
175 std::shared_ptr<BTGattService> s = getServiceUnchecked();
183 return getServiceChecked()->getDeviceChecked();
187 enabledState[0] =
false;
188 enabledState[1] =
false;
192 if( !hasEnableNotification && !hasEnableIndication ) {
193 DBG_PRINT(
"Characteristic has neither Notify nor Indicate property present: %s", toString().c_str());
197 std::shared_ptr<BTDevice> device = getDeviceUnchecked();
198 std::shared_ptr<BTGattHandler> gatt =
nullptr != device ? device->
getGattHandler() :
nullptr;
199 if(
nullptr == gatt ) {
200 if( !enableNotification && !enableIndication ) {
202 DBG_PRINT(
"Characteristic's device GATTHandle not connected: %s", toShortString().c_str());
208 const bool resEnableNotification = hasEnableNotification && enableNotification;
209 const bool resEnableIndication = hasEnableIndication && enableIndication;
211 if( resEnableNotification == enabledNotifyState &&
212 resEnableIndication == enabledIndicateState )
214 enabledState[0] = resEnableNotification;
215 enabledState[1] = resEnableIndication;
216 DBG_PRINT(
"GATTCharacteristic::configNotificationIndication: Unchanged: notification[shall %d, has %d: %d == %d], indication[shall %d, has %d: %d == %d]",
217 enableNotification, hasEnableNotification, enabledNotifyState, resEnableNotification,
218 enableIndication, hasEnableIndication, enabledIndicateState, resEnableIndication);
223 if(
nullptr == cccd ) {
224 DBG_PRINT(
"Characteristic has no ClientCharacteristicConfig descriptor: %s", toString().c_str());
228 DBG_PRINT(
"GATTCharacteristic::configNotificationIndication: res %d, notification[shall %d, has %d: %d -> %d], indication[shall %d, has %d: %d -> %d]",
230 enableNotification, hasEnableNotification, enabledNotifyState, resEnableNotification,
231 enableIndication, hasEnableIndication, enabledIndicateState, resEnableIndication);
233 enabledNotifyState = resEnableNotification;
234 enabledIndicateState = resEnableIndication;
235 enabledState[0] = resEnableNotification;
236 enabledState[1] = resEnableIndication;
245 const bool enableNotification = hasEnableNotification;
246 const bool enableIndication = !enableNotification && hasEnableIndication;
248 return configNotificationIndication(enableNotification, enableIndication, enabledState);
254 std::shared_ptr<BTGattChar::Listener> delegate;
258 : associatedChar(characteristicMatch), delegate(l) { }
261 if(
nullptr == associatedChar ) {
264 return *associatedChar == characteristic;
274 const bool confirmationSent)
override {
279 {
return delegate.get() == rhs.delegate.get(); }
282 {
return !(*
this == rhs); }
290 if( !enableNotificationOrIndication(enabledState) ) {
293 return addCharListener(l);
297 if( disableIndicationNotification ) {
298 bool enabledState[2];
299 configNotificationIndication(
false,
false, enabledState);
301 return getDeviceChecked()->removeAllAssociatedCharListener(
this);
305 std::shared_ptr<BTDevice> device = getDeviceChecked();
307 if(
nullptr == gatt ) {
316 std::shared_ptr<BTDevice> device = getDeviceChecked();
318 if(
nullptr == gatt ) {
328 std::shared_ptr<BTDevice> device = getDeviceChecked();
330 if(
nullptr == gatt ) {