From 2386a8a68a5077cd92b7cbbff20a21778c8ff2cc Mon Sep 17 00:00:00 2001 From: h2zero Date: Tue, 18 Jan 2022 14:48:07 -0700 Subject: [PATCH] Retrieve attributes with 16bit uuid if 128bit fails. When retrieving attribute handles using the 128bit base version of a 16 bit UUID some devices will report "not found". This will attempt to convert the UUID to the 16bit version and try again. * Adds `to16()` method to NimBLEUUID. --- src/NimBLEClient.cpp | 11 ++++++++++- src/NimBLERemoteCharacteristic.cpp | 11 ++++++++++- src/NimBLERemoteService.cpp | 11 ++++++++++- src/NimBLEUUID.cpp | 27 +++++++++++++++++++++++++-- src/NimBLEUUID.h | 1 + 5 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/NimBLEClient.cpp b/src/NimBLEClient.cpp index bc796cb..0abb408 100644 --- a/src/NimBLEClient.cpp +++ b/src/NimBLEClient.cpp @@ -611,7 +611,7 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) { return m_servicesVector.back(); } - // If the request was successful but 16/32 bit service not found + // If the request was successful but 16/32 bit uuid not found // try again with the 128 bit uuid. if(uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) @@ -619,6 +619,15 @@ NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) { NimBLEUUID uuid128(uuid); uuid128.to128(); return getService(uuid128); + } else { + // If the request was successful but the 128 bit uuid not found + // try again with the 16 bit uuid. + NimBLEUUID uuid16(uuid); + uuid16.to16(); + // if the uuid was 128 bit but not of the BLE base type this check will fail + if (uuid16.bitSize() == BLE_UUID_TYPE_16) { + return getService(uuid16); + } } } diff --git a/src/NimBLERemoteCharacteristic.cpp b/src/NimBLERemoteCharacteristic.cpp index 3667742..d25bce1 100644 --- a/src/NimBLERemoteCharacteristic.cpp +++ b/src/NimBLERemoteCharacteristic.cpp @@ -316,7 +316,7 @@ NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUU return m_descriptorVector.back(); } - // If the request was successful but 16/32 bit descriptor not found + // If the request was successful but 16/32 bit uuid not found // try again with the 128 bit uuid. if(uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) @@ -324,6 +324,15 @@ NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUU NimBLEUUID uuid128(uuid); uuid128.to128(); return getDescriptor(uuid128); + } else { + // If the request was successful but the 128 bit uuid not found + // try again with the 16 bit uuid. + NimBLEUUID uuid16(uuid); + uuid16.to16(); + // if the uuid was 128 bit but not of the BLE base type this check will fail + if (uuid16.bitSize() == BLE_UUID_TYPE_16) { + return getDescriptor(uuid16); + } } } diff --git a/src/NimBLERemoteService.cpp b/src/NimBLERemoteService.cpp index d628e9f..218396d 100644 --- a/src/NimBLERemoteService.cpp +++ b/src/NimBLERemoteService.cpp @@ -109,7 +109,7 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU return m_characteristicVector.back(); } - // If the request was successful but 16/32 bit characteristic not found + // If the request was successful but 16/32 bit uuid not found // try again with the 128 bit uuid. if(uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) @@ -117,6 +117,15 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU NimBLEUUID uuid128(uuid); uuid128.to128(); return getCharacteristic(uuid128); + } else { + // If the request was successful but the 128 bit uuid not found + // try again with the 16 bit uuid. + NimBLEUUID uuid16(uuid); + uuid16.to16(); + // if the uuid was 128 bit but not of the BLE base type this check will fail + if (uuid16.bitSize() == BLE_UUID_TYPE_16) { + return getCharacteristic(uuid16); + } } } diff --git a/src/NimBLEUUID.cpp b/src/NimBLEUUID.cpp index 4234650..255f771 100644 --- a/src/NimBLEUUID.cpp +++ b/src/NimBLEUUID.cpp @@ -235,8 +235,8 @@ const ble_uuid_any_t* NimBLEUUID::getNative() const { /** * @brief Convert a UUID to its 128 bit representation. - * @details A UUID can be internally represented as 16bit, 32bit or the full 128bit. This method - * will convert 16 or 32 bit representations to the full 128bit. + * @details A UUID can be internally represented as 16bit, 32bit or the full 128bit. + * This method will convert 16 or 32bit representations to the full 128bit. * @return The NimBLEUUID converted to 128bit. */ const NimBLEUUID &NimBLEUUID::to128() { @@ -257,6 +257,29 @@ const NimBLEUUID &NimBLEUUID::to128() { } // to128 +/** + * @brief Convert 128 bit UUID to its 16 bit representation. + * @details A UUID can be internally represented as 16bit, 32bit or the full 128bit. + * This method will convert a 128bit uuid to 16bit if it contains the ble base uuid. + * @return The NimBLEUUID converted to 16bit if successful, otherwise the original uuid. + */ +const NimBLEUUID& NimBLEUUID::to16() { + if (!m_valueSet || m_uuid.u.type == BLE_UUID_TYPE_16) { + return *this; + } + + if (m_uuid.u.type == BLE_UUID_TYPE_128) { + uint8_t base128[] = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, + 0x00, 0x80, 0x00, 0x10, 0x00, 0x00}; + if (memcmp(m_uuid.u128.value, base128, sizeof(base128)) == 0 ) { + *this = NimBLEUUID(*(uint16_t*)(m_uuid.u128.value + 12)); + } + } + + return *this; +} + + /** * @brief Get a string representation of the UUID. * @details diff --git a/src/NimBLEUUID.h b/src/NimBLEUUID.h index 724db19..2c24971 100644 --- a/src/NimBLEUUID.h +++ b/src/NimBLEUUID.h @@ -48,6 +48,7 @@ public: bool equals(const NimBLEUUID &uuid) const; const ble_uuid_any_t* getNative() const; const NimBLEUUID & to128(); + const NimBLEUUID& to16(); std::string toString() const; static NimBLEUUID fromString(const std::string &uuid);