NimBLEUUID: Add operator == and != + correct equals() to test if values are set.

Adds convenience operators == and != to NimBLEUUID class.

Tests if both values are not set in equals operation and returns true if so.
This commit is contained in:
h2zero 2020-05-06 21:08:50 -06:00
parent 1779a3f723
commit 04b524d1f8
2 changed files with 44 additions and 75 deletions

View file

@ -18,6 +18,8 @@
#include "NimBLEUUID.h" #include "NimBLEUUID.h"
#include "NimBLELog.h" #include "NimBLELog.h"
#include <algorithm>
static const char* LOG_TAG = "NimBLEUUID"; static const char* LOG_TAG = "NimBLEUUID";
@ -42,50 +44,25 @@ static const char* LOG_TAG = "NimBLEUUID";
m_valueSet = true; m_valueSet = true;
if (value.length() == 4) { if (value.length() == 4) {
m_uuid.u.type = BLE_UUID_TYPE_16; m_uuid.u.type = BLE_UUID_TYPE_16;
m_uuid.u16.value = 0; m_uuid.u16.value = strtoul(value.c_str(), NULL, 16);
for(int i=0;i<value.length();){
uint8_t MSB = value.c_str()[i];
uint8_t LSB = value.c_str()[i+1];
if(MSB > '9') MSB -= 7;
if(LSB > '9') LSB -= 7;
m_uuid.u16.value += (((MSB&0x0F) <<4) | (LSB & 0x0F))<<(2-i)*4;
i+=2;
}
} }
else if (value.length() == 8) { else if (value.length() == 8) {
m_uuid.u.type = BLE_UUID_TYPE_32; m_uuid.u.type = BLE_UUID_TYPE_32;
m_uuid.u32.value = 0; m_uuid.u32.value = strtoul(value.c_str(), NULL, 16);
for(int i=0;i<value.length();){
uint8_t MSB = value.c_str()[i];
uint8_t LSB = value.c_str()[i+1];
if(MSB > '9') MSB -= 7;
if(LSB > '9') LSB -= 7;
m_uuid.u32.value += (((MSB&0x0F) <<4) | (LSB & 0x0F))<<(6-i)*4;
i+=2;
} }
} else if (value.length() == 16) {
else if (value.length() == 16) { // how we can have 16 byte length string reprezenting 128 bit uuid??? needs to be investigated (lack of time) *this = NimBLEUUID((uint8_t*)value.data(), 16, true);
m_uuid.u.type = BLE_UUID_TYPE_128;
NimBLEUtils::memrcpy(m_uuid.u128.value, (uint8_t*)value.data(), 16);
} }
else if (value.length() == 36) { else if (value.length() == 36) {
// If the length of the string is 36 bytes then we will assume it is a long hex string in // If the length of the string is 36 bytes then we will assume it is a long hex string in
// UUID format. // UUID format.
m_uuid.u.type = BLE_UUID_TYPE_128; char * position = const_cast<char *>(value.c_str());
int n = 0; uint32_t first = strtoul(position, &position, 16);
for(int i=0;i<value.length();){ uint16_t second = strtoul(position + 1, &position, 16);
if(value.c_str()[i] == '-') uint16_t third = strtoul(position + 1, &position, 16);
i++; uint16_t fourth = strtoul(position + 1, &position, 16);
uint8_t MSB = value.c_str()[i]; uint64_t fifth = strtoull(position + 1, NULL, 16);
uint8_t LSB = value.c_str()[i+1]; *this = NimBLEUUID(first, second, third, (uint64_t(fourth) << 48) + fifth);
if(MSB > '9') MSB -= 7;
if(LSB > '9') LSB -= 7;
m_uuid.u128.value[15-n++] = ((MSB&0x0F) <<4) | (LSB & 0x0F);
i+=2;
}
} }
else { else {
NIMBLE_LOGE(LOG_TAG,"ERROR: UUID value not 2, 4, 16 or 36 bytes"); NIMBLE_LOGE(LOG_TAG,"ERROR: UUID value not 2, 4, 16 or 36 bytes");
@ -110,8 +87,9 @@ NimBLEUUID::NimBLEUUID(uint8_t* pData, size_t size, bool msbFirst) {
return; return;
} }
m_uuid.u.type = BLE_UUID_TYPE_128; m_uuid.u.type = BLE_UUID_TYPE_128;
if (msbFirst) { if (msbFirst) {
NimBLEUtils::memrcpy(m_uuid.u128.value, pData, 16); std::reverse_copy(pData, pData + 16, m_uuid.u128.value);
} else { } else {
memcpy(m_uuid.u128.value, pData, 16); memcpy(m_uuid.u128.value, pData, 16);
} }
@ -198,10 +176,7 @@ uint8_t NimBLEUUID::bitSize() {
* @return True if the UUIDs are equal and false otherwise. * @return True if the UUIDs are equal and false otherwise.
*/ */
bool NimBLEUUID::equals(NimBLEUUID uuid) { bool NimBLEUUID::equals(NimBLEUUID uuid) {
if(ble_uuid_cmp(&m_uuid.u, &uuid.getNative()->u) == 0){ return *this == uuid;
return true;
}
return false;
} }
@ -255,47 +230,20 @@ ble_uuid_any_t* NimBLEUUID::getNative() {
* A UUID can be internally represented as 16bit, 32bit or the full 128bit. This method * 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. * will convert 16 or 32 bit representations to the full 128bit.
*/ */
NimBLEUUID NimBLEUUID::to128() { NimBLEUUID &NimBLEUUID::to128() {
// If we either don't have a value or are already a 128 bit UUID, nothing further to do. // If we either don't have a value or are already a 128 bit UUID, nothing further to do.
if (!m_valueSet || m_uuid.u.type == BLE_UUID_TYPE_128) { if (!m_valueSet || m_uuid.u.type == BLE_UUID_TYPE_128) {
return *this; return *this;
} }
// If we are 16 bit or 32 bit, then set the 4 bytes of the variable part of the UUID. // If we are 16 bit or 32 bit, then set the other bytes of the UUID.
if (m_uuid.u.type == BLE_UUID_TYPE_16) { if (m_uuid.u.type == BLE_UUID_TYPE_16) {
uint16_t temp = m_uuid.u16.value; *this = NimBLEUUID(m_uuid.u16.value, 0x0000, 0x1000, 0x800000805f9b34fb);
m_uuid.u128.value[15] = 0;
m_uuid.u128.value[14] = 0;
m_uuid.u128.value[13] = (temp >> 8) & 0xff;
m_uuid.u128.value[12] = temp & 0xff;
} }
else if (m_uuid.u.type == BLE_UUID_TYPE_32) { else if (m_uuid.u.type == BLE_UUID_TYPE_32) {
uint32_t temp = m_uuid.u32.value; *this = NimBLEUUID(m_uuid.u32.value, 0x0000, 0x1000, 0x800000805f9b34fb);
m_uuid.u128.value[15] = (temp >> 24) & 0xff;
m_uuid.u128.value[14] = (temp >> 16) & 0xff;
m_uuid.u128.value[13] = (temp >> 8) & 0xff;
m_uuid.u128.value[12] = temp & 0xff;
} }
// Set the fixed parts of the UUID.
m_uuid.u128.value[11] = 0x00;
m_uuid.u128.value[10] = 0x00;
m_uuid.u128.value[9] = 0x10;
m_uuid.u128.value[8] = 0x00;
m_uuid.u128.value[7] = 0x80;
m_uuid.u128.value[6] = 0x00;
m_uuid.u128.value[5] = 0x00;
m_uuid.u128.value[4] = 0x80;
m_uuid.u128.value[3] = 0x5f;
m_uuid.u128.value[2] = 0x9b;
m_uuid.u128.value[1] = 0x34;
m_uuid.u128.value[0] = 0xfb;
m_uuid.u.type = BLE_UUID_TYPE_128;
return *this; return *this;
} // to128 } // to128
@ -311,11 +259,28 @@ NimBLEUUID NimBLEUUID::to128() {
* @return A string representation of the UUID. * @return A string representation of the UUID.
*/ */
std::string NimBLEUUID::toString() { std::string NimBLEUUID::toString() {
if (!m_valueSet) return "<NULL>"; // If we have no value, nothing to format. return std::string(*this);
} // toString
bool NimBLEUUID::operator ==(const NimBLEUUID & rhs) {
if(m_valueSet && rhs.m_valueSet) {
return ble_uuid_cmp(&m_uuid.u, &rhs.m_uuid.u) == 0;
}
return m_valueSet == rhs.m_valueSet;
}
bool NimBLEUUID::operator !=(const NimBLEUUID & rhs) {
return !this->operator==(rhs);
}
NimBLEUUID::operator std::string() const {
if (!m_valueSet) return std::string(); // If we have no value, nothing to format.
char buf[BLE_UUID_STR_LEN]; char buf[BLE_UUID_STR_LEN];
return ble_uuid_to_str(&m_uuid.u, buf); return ble_uuid_to_str(&m_uuid.u, buf);
} // toString }
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */

View file

@ -40,10 +40,14 @@ public:
uint8_t bitSize(); // Get the number of bits in this uuid. uint8_t bitSize(); // Get the number of bits in this uuid.
bool equals(NimBLEUUID uuid); bool equals(NimBLEUUID uuid);
ble_uuid_any_t* getNative(); ble_uuid_any_t* getNative();
NimBLEUUID to128(); NimBLEUUID & to128();
std::string toString(); std::string toString();
static NimBLEUUID fromString(std::string uuid); // Create a NimBLEUUID from a string static NimBLEUUID fromString(std::string uuid); // Create a NimBLEUUID from a string
bool operator ==(const NimBLEUUID & rhs);
bool operator !=(const NimBLEUUID & rhs);
operator std::string() const;
private: private:
ble_uuid_any_t m_uuid; // The underlying UUID structure that this class wraps. ble_uuid_any_t m_uuid; // The underlying UUID structure that this class wraps.
bool m_valueSet = false; // Is there a value set for this instance. bool m_valueSet = false; // Is there a value set for this instance.