diff options
-rw-r--r-- | api/direct_bt/GATTCharacteristic.hpp | 12 | ||||
-rw-r--r-- | api/direct_bt/GATTDescriptor.hpp | 14 | ||||
-rw-r--r-- | api/direct_bt/GATTService.hpp | 12 | ||||
-rw-r--r-- | src/direct_bt/GATTCharacteristic.cpp | 42 | ||||
-rw-r--r-- | src/direct_bt/GATTDescriptor.cpp | 16 | ||||
-rw-r--r-- | src/direct_bt/GATTService.cpp | 14 |
6 files changed, 89 insertions, 21 deletions
diff --git a/api/direct_bt/GATTCharacteristic.hpp b/api/direct_bt/GATTCharacteristic.hpp index 9e93637b..033e190d 100644 --- a/api/direct_bt/GATTCharacteristic.hpp +++ b/api/direct_bt/GATTCharacteristic.hpp @@ -80,6 +80,16 @@ namespace direct_bt { bool enabledNotifyState = false; bool enabledIndicateState = false; + /** + * For an unknown reason, using the virtual function 'toString()' + * while constructing an exception message causes a SIGSEGV. + * <p> + * This method represents a non-virtual variation, + * which also does not call any other virtual function. + * </p> + */ + std::string toSafeString() const; + public: /** BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.1.1 Characteristic Properties */ enum PropertyBitVal : uint8_t { @@ -161,7 +171,7 @@ namespace direct_bt { std::string getPropertiesString() const { return getPropertiesString(properties); } - std::string toString() const; + std::string toString() const override; void clearDescriptors() { descriptorList.clear(); diff --git a/api/direct_bt/GATTDescriptor.hpp b/api/direct_bt/GATTDescriptor.hpp index 3c3b7bd0..e721b67c 100644 --- a/api/direct_bt/GATTDescriptor.hpp +++ b/api/direct_bt/GATTDescriptor.hpp @@ -64,6 +64,16 @@ namespace direct_bt { /** Descriptor's characteristic weak back-reference */ std::weak_ptr<GATTCharacteristic> wbr_characteristic; + /** + * For an unknown reason, using the virtual function 'toString()' + * while constructing an exception message causes a SIGSEGV. + * <p> + * This method represents a non-virtual variation, + * which also does not call any other virtual function. + * </p> + */ + std::string toSafeString() const; + public: static const uuid16_t TYPE_EXT_PROP; static const uuid16_t TYPE_USER_DESC; @@ -128,9 +138,7 @@ namespace direct_bt { std::shared_ptr<GATTCharacteristic> getCharacteristicChecked() const; std::shared_ptr<DBTDevice> getDeviceChecked() const; - virtual std::string toString() const { - return "[type 0x"+type->toString()+", handle "+uint16HexString(handle)+", value["+value.toString()+"]]"; - } + virtual std::string toString() const override; /** Value is uint16_t bitfield */ bool isExtendedProperties() const { return TYPE_EXT_PROP == *type; } diff --git a/api/direct_bt/GATTService.hpp b/api/direct_bt/GATTService.hpp index 6efdf11a..8f4f68d5 100644 --- a/api/direct_bt/GATTService.hpp +++ b/api/direct_bt/GATTService.hpp @@ -68,6 +68,16 @@ namespace direct_bt { /** Service's device weak back-reference */ std::weak_ptr<DBTDevice> wbr_device; + /** + * For an unknown reason, using the virtual function 'toString()' + * while constructing an exception message causes a SIGSEGV. + * <p> + * This method represents a non-virtual variation, + * which also does not call any other virtual function. + * </p> + */ + std::string toSafeString() const; + public: const bool isPrimary; @@ -109,7 +119,7 @@ namespace direct_bt { std::shared_ptr<DBTDevice> getDeviceUnchecked() const { return wbr_device.lock(); } std::shared_ptr<DBTDevice> getDeviceChecked() const; - std::string toString() const; + std::string toString() const override; }; inline bool operator==(const GATTService& lhs, const GATTService& rhs) diff --git a/src/direct_bt/GATTCharacteristic.cpp b/src/direct_bt/GATTCharacteristic.cpp index 85d15265..13131d48 100644 --- a/src/direct_bt/GATTCharacteristic.cpp +++ b/src/direct_bt/GATTCharacteristic.cpp @@ -138,10 +138,37 @@ std::string GATTCharacteristic::toString() const { service_name+", enabled[notify "+std::to_string(enabledNotifyState)+", indicate "+std::to_string(enabledIndicateState)+"] ]"; } +std::string GATTCharacteristic::toSafeString() const { + std::shared_ptr<const uuid_t> service_uuid; + uint16_t service_handle_end = 0xffff; + GATTServiceRef serviceRef = getServiceUnchecked(); + std::string service_name = ""; + std::string char_name = ""; + + if( nullptr != serviceRef ) { + service_uuid = serviceRef->type; + service_handle_end = serviceRef->endHandle; + + if( uuid_t::UUID16_SZ == service_uuid->getTypeSize() ) { + const uint16_t uuid16 = (static_cast<const uuid16_t*>(service_uuid.get()))->value; + service_name = ", "+GattServiceTypeToString(static_cast<GattServiceType>(uuid16)); + } + } + if( uuid_t::UUID16_SZ == value_type->getTypeSize() ) { + const uint16_t uuid16 = (static_cast<const uuid16_t*>(value_type.get()))->value; + char_name = ", "+GattCharacteristicTypeToString(static_cast<GattCharacteristicType>(uuid16)); + } + return "handle "+uint16HexString(handle)+", props "+uint8HexString(properties)+" "+getPropertiesString()+ + ", value[handle "+uint16HexString(value_handle)+char_name+ + "], service["+ + ", handle[ "+uint16HexString(service_handle)+".."+uint16HexString(service_handle_end)+" ]"+ + service_name+", enabled[notify "+std::to_string(enabledNotifyState)+", indicate "+std::to_string(enabledIndicateState)+"] ]"; +} + std::shared_ptr<GATTService> GATTCharacteristic::getServiceChecked() const { std::shared_ptr<GATTService> ref = wbr_service.lock(); if( nullptr == ref ) { - throw IllegalStateException("GATTCharacteristic's service already destructed: "+toString(), E_FILE_LINE); + throw IllegalStateException("GATTCharacteristic's service already destructed: "+toSafeString(), E_FILE_LINE); } return ref; } @@ -174,11 +201,11 @@ bool GATTCharacteristic::configNotificationIndication(const bool enableNotificat if( nullptr == gatt ) { if( !enableNotification && !enableIndication ) { // OK to have GATTHandler being shutdown @ disable - DBG_PRINT("Characteristic's device GATTHandle not connected: %s, %s", toString().c_str(), device->toString().c_str()); + DBG_PRINT("Characteristic's device GATTHandle not connected: %s", toSafeString().c_str()); return false; } throw IllegalStateException("Characteristic's device GATTHandle not connected: "+ - toString() + ", " + device->toString(), E_FILE_LINE); + toString(), E_FILE_LINE); } const bool resEnableNotification = hasEnableNotification && enableNotification; const bool resEnableIndication = hasEnableIndication && enableIndication; @@ -254,8 +281,7 @@ bool GATTCharacteristic::readValue(POctets & res, int expectedLength) { std::shared_ptr<DBTDevice> device = getDeviceChecked(); std::shared_ptr<GATTHandler> gatt = device->getGATTHandler(); if( nullptr == gatt ) { - throw IllegalStateException("Characteristic's device GATTHandle not connected: "+ - toString() + ", " + device->toString(), E_FILE_LINE); + throw IllegalStateException("Characteristic's device GATTHandle not connected: "+toSafeString(), E_FILE_LINE); } return gatt->readCharacteristicValue(*this, res, expectedLength); } @@ -266,8 +292,7 @@ bool GATTCharacteristic::writeValue(const TROOctets & value) { std::shared_ptr<DBTDevice> device = getDeviceChecked(); std::shared_ptr<GATTHandler> gatt = device->getGATTHandler(); if( nullptr == gatt ) { - throw IllegalStateException("Characteristic's device GATTHandle not connected: "+ - toString() + ", " + device->toString(), E_FILE_LINE); + throw IllegalStateException("Characteristic's device GATTHandle not connected: "+toSafeString(), E_FILE_LINE); } return gatt->writeCharacteristicValue(*this, value); } @@ -279,8 +304,7 @@ bool GATTCharacteristic::writeValueNoResp(const TROOctets & value) { std::shared_ptr<DBTDevice> device = getDeviceChecked(); std::shared_ptr<GATTHandler> gatt = device->getGATTHandler(); if( nullptr == gatt ) { - throw IllegalStateException("Characteristic's device GATTHandle not connected: "+ - toString() + ", " + device->toString(), E_FILE_LINE); + throw IllegalStateException("Characteristic's device GATTHandle not connected: "+toSafeString(), E_FILE_LINE); } return gatt->writeCharacteristicValueNoResp(*this, value); } diff --git a/src/direct_bt/GATTDescriptor.cpp b/src/direct_bt/GATTDescriptor.cpp index f646fdbb..08cddbfd 100644 --- a/src/direct_bt/GATTDescriptor.cpp +++ b/src/direct_bt/GATTDescriptor.cpp @@ -46,7 +46,7 @@ const uuid16_t GATTDescriptor::TYPE_CCC_DESC(Type::CLIENT_CHARACTERISTIC_CONFIGU std::shared_ptr<GATTCharacteristic> GATTDescriptor::getCharacteristicChecked() const { std::shared_ptr<GATTCharacteristic> ref = wbr_characteristic.lock(); if( nullptr == ref ) { - throw IllegalStateException("GATTDescriptor's characteristic already destructed: "+toString(), E_FILE_LINE); + throw IllegalStateException("GATTDescriptor's characteristic already destructed: "+toSafeString(), E_FILE_LINE); } return ref; } @@ -59,8 +59,7 @@ bool GATTDescriptor::readValue(int expectedLength) { std::shared_ptr<DBTDevice> device = getDeviceChecked(); std::shared_ptr<GATTHandler> gatt = device->getGATTHandler(); if( nullptr == gatt ) { - throw IllegalStateException("Descriptor's device GATTHandle not connected: "+ - toString() + ", " + device->toString(), E_FILE_LINE); + throw IllegalStateException("Descriptor's device GATTHandle not connected: "+toSafeString(), E_FILE_LINE); } return gatt->readDescriptorValue(*this, expectedLength); } @@ -69,8 +68,15 @@ bool GATTDescriptor::writeValue() { std::shared_ptr<DBTDevice> device = getDeviceChecked(); std::shared_ptr<GATTHandler> gatt = device->getGATTHandler(); if( nullptr == gatt ) { - throw IllegalStateException("Descriptor's device GATTHandle not connected: "+ - toString() + ", " + device->toString(), E_FILE_LINE); + throw IllegalStateException("Descriptor's device GATTHandle not connected: "+toSafeString(), E_FILE_LINE); } return gatt->writeDescriptorValue(*this); } + +std::string GATTDescriptor::toString() const { + return "[type 0x"+type->toString()+", handle "+uint16HexString(handle)+", value["+value.toString()+"]]"; +} + +std::string GATTDescriptor::toSafeString() const { + return "[handle "+uint16HexString(handle)+", value["+value.toString()+"]]"; +} diff --git a/src/direct_bt/GATTService.cpp b/src/direct_bt/GATTService.cpp index 1818b39e..02b6195c 100644 --- a/src/direct_bt/GATTService.cpp +++ b/src/direct_bt/GATTService.cpp @@ -41,7 +41,7 @@ using namespace direct_bt; std::shared_ptr<DBTDevice> GATTService::getDeviceChecked() const { std::shared_ptr<DBTDevice> ref = wbr_device.lock(); if( nullptr == ref ) { - throw IllegalStateException("GATTService's device already destructed: "+toString(), E_FILE_LINE); + throw IllegalStateException("GATTService's device already destructed: "+toSafeString(), E_FILE_LINE); } return ref; } @@ -53,5 +53,15 @@ std::string GATTService::toString() const { name = " - "+GattServiceTypeToString(static_cast<GattServiceType>(uuid16)); } return "type 0x"+type->toString()+", handle ["+uint16HexString(startHandle, true)+".."+uint16HexString(endHandle, true)+"]"+ - name+", "+std::to_string(characteristicList.size())+" characteristics"; + name+", "+std::to_string(characteristicList.size())+" characteristics"; +} + +std::string GATTService::toSafeString() const { + std::string name = ""; + if( uuid_t::UUID16_SZ == type->getTypeSize() ) { + const uint16_t uuid16 = (static_cast<const uuid16_t*>(type.get()))->value; + name = " - "+GattServiceTypeToString(static_cast<GattServiceType>(uuid16)); + } + return "handle ["+uint16HexString(startHandle, true)+".."+uint16HexString(endHandle, true)+"]"+ + name+", "+std::to_string(characteristicList.size())+" characteristics"; } |