diff options
-rw-r--r-- | gatoattclient.cpp | 25 | ||||
-rw-r--r-- | gatoattclient.h | 2 | ||||
-rw-r--r-- | gatoperipheral.cpp | 21 | ||||
-rw-r--r-- | gatouuid.cpp | 81 | ||||
-rw-r--r-- | gatouuid.h | 42 | ||||
-rw-r--r-- | helpers.cpp | 34 |
6 files changed, 43 insertions, 162 deletions
diff --git a/gatoattclient.cpp b/gatoattclient.cpp index 033794f..54e2212 100644 --- a/gatoattclient.cpp +++ b/gatoattclient.cpp @@ -184,8 +184,7 @@ uint GatoAttClient::requestReadByType(GatoHandle start, GatoHandle end, const Ga QByteArray data; QDataStream s(&data, QIODevice::WriteOnly); s.setByteOrder(QDataStream::LittleEndian); - s << start << end; - writeUuid16or128(s, uuid); + s << start << end << gatouuid_to_bytearray(uuid, true, false); return request(AttOpReadByTypeRequest, data, receiver, member); } @@ -205,8 +204,7 @@ uint GatoAttClient::requestReadByGroupType(GatoHandle start, GatoHandle end, con QByteArray data; QDataStream s(&data, QIODevice::WriteOnly); s.setByteOrder(QDataStream::LittleEndian); - s << start << end; - writeUuid16or128(s, uuid); + s << start << end << gatouuid_to_bytearray(uuid, true, false); return request(AttOpReadByGroupTypeRequest, data, receiver, member); } @@ -429,19 +427,6 @@ bool GatoAttClient::handleResponse(const Request &req, const QByteArray &respons } } -void GatoAttClient::writeUuid16or128(QDataStream &s, const GatoUUID &uuid) -{ - s.setByteOrder(QDataStream::LittleEndian); - - bool uuid16_ok; - quint16 uuid16 = uuid.toUInt16(&uuid16_ok); - if (uuid16_ok) { - s << uuid16; - } else { - s << uuid.toUInt128(); - } -} - QList<GatoAttClient::InformationData> GatoAttClient::parseInformationData(const QByteArray &data) { const int format = data[0]; @@ -467,15 +452,17 @@ QList<GatoAttClient::InformationData> GatoAttClient::parseInformationData(const const char *s = data.constData(); for (int i = 0; i < items; i++) { InformationData d; + QByteArray uuid; d.handle = read_le<GatoHandle>(&s[pos]); switch (format) { case 1: - d.uuid = GatoUUID(read_le<quint16>(&s[pos + 2])); + uuid = data.mid(pos + 2, 2); break; case 2: - d.uuid = GatoUUID(read_le<gatouint128>(&s[pos + 2])); + uuid = data.mid(pos + 2, 16); break; } + d.uuid = bytearray_to_gatouuid(uuid); list.append(d); diff --git a/gatoattclient.h b/gatoattclient.h index aaa214b..834178e 100644 --- a/gatoattclient.h +++ b/gatoattclient.h @@ -76,8 +76,6 @@ private: bool handleEvent(const QByteArray &event); bool handleResponse(const Request& req, const QByteArray &response); - void writeUuid16or128(QDataStream& s, const GatoUUID& uuid); - QList<InformationData> parseInformationData(const QByteArray &data); QList<HandleInformation> parseHandleInformation(const QByteArray &data); QList<AttributeData> parseAttributeData(const QByteArray &data); diff --git a/gatoperipheral.cpp b/gatoperipheral.cpp index c4339ec..cc4d6db 100644 --- a/gatoperipheral.cpp +++ b/gatoperipheral.cpp @@ -430,21 +430,16 @@ void GatoPeripheralPrivate::parseEIRUUIDs(int size, bool complete, quint8 data[] { Q_UNUSED(complete); + if (size != 16/8 && size != 32/8 && size != 128/8) { + qWarning() << "Unhandled UUID size: " << size; + return; + } + for (int pos = 0; pos < len; pos += size) { - GatoUUID uuid; - switch (size) { - case 16/8: - uuid = GatoUUID(qFromLittleEndian<quint16>(&data[pos])); - break; - case 32/8: - uuid = GatoUUID(qFromLittleEndian<quint32>(&data[pos])); - break; - case 128/8: - uuid = GatoUUID(qFromLittleEndian<gatouint128>(&data[pos])); - break; - } + char *ptr = reinterpret_cast<char*>(&data[pos]); + QByteArray ba = QByteArray::fromRawData(ptr, size/8); - service_uuids.insert(uuid); + service_uuids.insert(bytearray_to_gatouuid(ba)); } } diff --git a/gatouuid.cpp b/gatouuid.cpp index 4a9625a..c5f994d 100644 --- a/gatouuid.cpp +++ b/gatouuid.cpp @@ -58,23 +58,6 @@ GatoUUID::GatoUUID(quint32 uuid) { } -GatoUUID::GatoUUID(gatouint128 uuid) - : QUuid() -{ - quint32 tmp32; - memcpy(&tmp32, &uuid.data[0], 4); - data1 = qFromBigEndian<quint32>(tmp32); - - quint16 tmp16; - memcpy(&tmp16, &uuid.data[4], 2); - data2 = qFromBigEndian<quint16>(tmp16); - - memcpy(&tmp16, &uuid.data[6], 2); - data3 = qFromBigEndian<quint16>(tmp16); - - memcpy(data4, &uuid.data[8], 8); -} - GatoUUID::GatoUUID(const QString &uuid) : QUuid(uuid) { @@ -137,24 +120,6 @@ quint32 GatoUUID::toUInt32(bool *ok) const } } -gatouint128 GatoUUID::toUInt128() const -{ - gatouint128 uuid; - - quint32 tmp32 = qToBigEndian<quint32>(data1); - memcpy(&uuid.data[0], &tmp32, 4); - - quint16 tmp16 = qToBigEndian<quint16>(data2); - memcpy(&uuid.data[4], &tmp16, 2); - - tmp16 = qToBigEndian<quint16>(data3); - memcpy(&uuid.data[6], &tmp16, 2); - - memcpy(&uuid.data[8], data4, 8); - - return uuid; -} - QDebug operator<<(QDebug debug, const GatoUUID &uuid) { quint16 uuid16; @@ -177,42 +142,14 @@ QDebug operator<<(QDebug debug, const GatoUUID &uuid) return debug.space(); } -QDataStream & operator<<(QDataStream &s, const gatouint128 &u) -{ - if (static_cast<QSysInfo::Endian>(s.byteOrder()) == QSysInfo::ByteOrder) { - for (int i = 0; i < 16; i++) { - s << u.data[i]; - } - } else { - for (int i = 15; i >= 0; i--) { - s << u.data[i]; - } - } - return s; -} - -QDataStream & operator>>(QDataStream &s, gatouint128 &u) +uint qHash(const GatoUUID &uuid, uint seed) { - if (static_cast<QSysInfo::Endian>(s.byteOrder()) == QSysInfo::ByteOrder) { - for (int i = 0; i < 16; i++) { - s >> u.data[i]; - } - } else { - for (int i = 15; i >= 0; i--) { - s >> u.data[i]; - } - } - return s; -} - -uint qHash(const GatoUUID &a) -{ - gatouint128 u128 = a.toUInt128(); - - uint h = u128.data[0] << 24 | u128.data[1] << 16 | u128.data[2] << 8 | u128.data[3] << 0; - h ^= u128.data[4] << 24 | u128.data[5] << 16 | u128.data[6] << 8 | u128.data[7] << 0; - h ^= u128.data[8] << 24 | u128.data[9] << 16 | u128.data[10] << 8 | u128.data[11] << 0; - h ^= u128.data[12] << 24 | u128.data[13] << 16 | u128.data[14] << 8 | u128.data[15] << 0; - - return h; +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + return uuid.data1 ^ uuid.data2 ^ (uuid.data3 << 16) + ^ ((uuid.data4[0] << 24) | (uuid.data4[1] << 16) | (uuid.data4[2] << 8) | uuid.data4[3]) + ^ ((uuid.data4[4] << 24) | (uuid.data4[5] << 16) | (uuid.data4[6] << 8) | uuid.data4[7]) + ^ seed; +#else + return qHash<QUuid>(uuid, seed); +#endif } @@ -8,41 +8,6 @@ class GatoUUIDPrivate; -struct gatouint128 -{ - quint8 data[16]; -}; - -template<> -inline LIBGATO_EXPORT gatouint128 qFromLittleEndian<gatouint128>(const uchar *src) -{ - gatouint128 dest; -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - for (int i = 0; i < 16; i++) { - dest.data[i] = src[i]; - } -#else - for (int i = 0; i < 16; i++) { - dest.data[i] = src[15 - i]; - } -#endif - return dest; -} - -template<> -inline LIBGATO_EXPORT void qToLittleEndian<gatouint128>(gatouint128 src, uchar *dest) -{ -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - for (int i = 0; i < 16; i++) { - dest[i] = src.data[i]; - } -#else - for (int i = 0; i < 16; i++) { - dest[i] = src.data[15 - i]; - } -#endif -} - class LIBGATO_EXPORT GatoUUID : public QUuid { public: @@ -71,7 +36,6 @@ public: GatoUUID(GattUuid uuid); explicit GatoUUID(quint16 uuid); explicit GatoUUID(quint32 uuid); - explicit GatoUUID(gatouint128 uuid); explicit GatoUUID(const QString &uuid); GatoUUID(const GatoUUID &o); GatoUUID(const QUuid &uuid); @@ -81,14 +45,10 @@ public: quint16 toUInt16(bool *ok = 0) const; quint32 toUInt32(bool *ok = 0) const; - gatouint128 toUInt128() const; }; LIBGATO_EXPORT QDebug operator<<(QDebug debug, const GatoUUID &uuid); -LIBGATO_EXPORT QDataStream & operator<<(QDataStream &s, const gatouint128 &u); -LIBGATO_EXPORT QDataStream & operator>>(QDataStream &s, gatouint128 &u); - -LIBGATO_EXPORT uint qHash(const GatoUUID &a); +LIBGATO_EXPORT uint qHash(const GatoUUID &a, uint seed = 0); #endif // GATOUUID_H diff --git a/helpers.cpp b/helpers.cpp index b62b464..ceb4454 100644 --- a/helpers.cpp +++ b/helpers.cpp @@ -20,6 +20,16 @@ #include "helpers.h" +static QByteArray reverse(const QByteArray &ba) +{ + int size = ba.size(); + QByteArray r(size, Qt::Uninitialized); + for (int i = 0; i < size; i++) { + r[i] = ba[size - i - 1]; + } + return r; +} + GatoUUID bytearray_to_gatouuid(const QByteArray &ba) { switch (ba.size()) { @@ -28,7 +38,8 @@ GatoUUID bytearray_to_gatouuid(const QByteArray &ba) case 4: return GatoUUID(read_le<quint32>(ba.constData())); case 16: - return GatoUUID(read_le<gatouint128>(ba.constData())); + // For some reason, Bluetooth UUIDs use "reversed big endian" order. + return GatoUUID(QUuid::fromRfc4122(reverse(ba))); default: return GatoUUID(); } @@ -36,29 +47,22 @@ GatoUUID bytearray_to_gatouuid(const QByteArray &ba) QByteArray gatouuid_to_bytearray(const GatoUUID &uuid, bool use_uuid16, bool use_uuid32) { - QByteArray ba; - if (use_uuid16) { quint16 uuid16 = uuid.toUInt16(&use_uuid16); if (use_uuid16) { - ba.resize(sizeof(quint16)); - write_le(uuid16, ba.data()); - return ba; + QByteArray bytes(sizeof(quint16), Qt::Uninitialized); + write_le(uuid16, bytes.data()); + return bytes; } } if (use_uuid32) { quint32 uuid32 = uuid.toUInt32(&use_uuid32); if (use_uuid32) { - ba.resize(sizeof(quint32)); - write_le(uuid32, ba.data()); - return ba; + QByteArray bytes(sizeof(quint32), Qt::Uninitialized); + write_le(uuid32, bytes.data()); + return bytes; } } - gatouint128 uuid128 = uuid.toUInt128(); - ba.resize(sizeof(gatouint128)); - Q_ASSERT(ba.size() == 16); - write_le(uuid128, ba.data()); - - return ba; + return reverse(uuid.toRfc4122()); } |