From a7161d92f965848049dbb2eaa80cce0aa178c0ed Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Fri, 6 Dec 2013 23:07:49 +0100 Subject: Improve MTU exchange --- gatoaddress.h | 7 +++++++ gatoattclient.cpp | 37 +++++++++++++++++++++++++------------ gatoattclient.h | 8 +++++--- gatocentralmanager.cpp | 3 --- gatouuid.cpp | 36 ++++++++++++++++++++++++++++++++++++ gatouuid.h | 8 +++----- libgato.pro | 9 --------- 7 files changed, 76 insertions(+), 32 deletions(-) diff --git a/gatoaddress.h b/gatoaddress.h index f30ec43..2ae2cc0 100644 --- a/gatoaddress.h +++ b/gatoaddress.h @@ -1,6 +1,7 @@ #ifndef GATOADDRESS_H #define GATOADDRESS_H +#include #include #include "libgato_global.h" @@ -26,6 +27,12 @@ private: QSharedDataPointer d; }; +inline QDebug operator<<(QDebug debug, const GatoAddress &a) +{ + debug << a.toString().toLatin1().constData(); + return debug.space(); +} + LIBGATO_EXPORT bool operator==(const GatoAddress &a, const GatoAddress &b); LIBGATO_EXPORT uint qHash(const GatoAddress &a); diff --git a/gatoattclient.cpp b/gatoattclient.cpp index 4310cd1..4af69ce 100644 --- a/gatoattclient.cpp +++ b/gatoattclient.cpp @@ -29,6 +29,7 @@ #define ATT_PSM 31 #define ATT_DEFAULT_LE_MTU 23 +#define ATT_MAX_LE_MTU 0x200 enum AttOpcode { AttOpNone = 0, @@ -73,7 +74,7 @@ static QByteArray remove_method_signature(const char *sig) } GatoAttClient::GatoAttClient(QObject *parent) : - QObject(parent), socket(new GatoSocket(this)), mtu(ATT_DEFAULT_LE_MTU), next_id(1) + QObject(parent), socket(new GatoSocket(this)), cur_mtu(ATT_DEFAULT_LE_MTU), next_id(1) { connect(socket, SIGNAL(connected()), SLOT(handleSocketConnected())); connect(socket, SIGNAL(disconnected()), SLOT(handleSocketDisconnected())); @@ -99,6 +100,11 @@ void GatoAttClient::close() socket->close(); } +int GatoAttClient::mtu() const +{ + return cur_mtu; +} + uint GatoAttClient::request(int opcode, const QByteArray &data, QObject *receiver, const char *member) { Request req; @@ -131,9 +137,13 @@ void GatoAttClient::cancelRequest(uint id) } } -uint GatoAttClient::requestExchangeMTU(quint8 client_mtu, QObject *receiver, const char *member) +uint GatoAttClient::requestExchangeMTU(quint16 client_mtu, QObject *receiver, const char *member) { - QByteArray data(1, client_mtu); + QByteArray data; + QDataStream s(&data, QIODevice::WriteOnly); + s.setByteOrder(QDataStream::LittleEndian); + s << client_mtu; + return request(AttOpExchangeMTURequest, data, receiver, member); } @@ -281,14 +291,14 @@ bool GatoAttClient::handleResponse(const Request &req, const QByteArray &respons if (req.receiver) { QMetaObject::invokeMethod(req.receiver, req.member.constData(), Q_ARG(uint, req.id), - Q_ARG(quint8, response[1])); + Q_ARG(quint16, read_le(response.constData() + 1))); } return true; } else if (response[0] == AttOpErrorResponse && response[1] == AttOpExchangeMTURequest) { if (req.receiver) { QMetaObject::invokeMethod(req.receiver, req.member.constData(), Q_ARG(uint, req.id), - Q_ARG(quint8, response[1])); + Q_ARG(quint16, 0)); } return true; } else { @@ -540,7 +550,7 @@ QList GatoAttClient::parseAttributeGroupData( void GatoAttClient::handleSocketConnected() { - requestExchangeMTU(ATT_DEFAULT_LE_MTU, this, SLOT(handleServerMTU(quint8))); + requestExchangeMTU(ATT_MAX_LE_MTU, this, SLOT(handleServerMTU(quint16))); emit connected(); } @@ -574,16 +584,19 @@ void GatoAttClient::handleSocketReadyRead() } } - qDebug() << "No idea what this packet is"; + qDebug() << "No idea what this packet (" + << QString("0x%1").arg(uint(pkt.at(0)), 2, 16, QLatin1Char('0')) + << ") is"; } } -void GatoAttClient::handleServerMTU(uint req, quint8 server_mtu) +void GatoAttClient::handleServerMTU(uint req, quint16 server_mtu) { Q_UNUSED(req); - if (server_mtu != 0) { - mtu = server_mtu; + if (server_mtu) { + cur_mtu = server_mtu; + if (cur_mtu < ATT_DEFAULT_LE_MTU) { + cur_mtu = ATT_DEFAULT_LE_MTU; + } } } - - diff --git a/gatoattclient.h b/gatoattclient.h index e373a27..aaa214b 100644 --- a/gatoattclient.h +++ b/gatoattclient.h @@ -41,8 +41,10 @@ public: QByteArray value; }; + int mtu() const; + uint request(int opcode, const QByteArray &data, QObject *receiver, const char *member); - uint requestExchangeMTU(quint8 client_mtu, QObject *receiver, const char *member); + uint requestExchangeMTU(quint16 client_mtu, QObject *receiver, const char *member); uint requestFindInformation(GatoHandle start, GatoHandle end, QObject *receiver, const char *member); uint requestFindByTypeValue(GatoHandle start, GatoHandle end, const GatoUUID &uuid, const QByteArray& value, QObject *receiver, const char *member); uint requestReadByType(GatoHandle start, GatoHandle end, const GatoUUID &uuid, QObject *receiver, const char *member); @@ -86,11 +88,11 @@ private slots: void handleSocketDisconnected(); void handleSocketReadyRead(); - void handleServerMTU(uint req, quint8 server_mtu); + void handleServerMTU(uint req, quint16 server_mtu); private: GatoSocket *socket; - quint8 mtu; + quint16 cur_mtu; uint next_id; QQueue pending_requests; }; diff --git a/gatocentralmanager.cpp b/gatocentralmanager.cpp index 3073d34..00dd531 100644 --- a/gatocentralmanager.cpp +++ b/gatocentralmanager.cpp @@ -90,8 +90,6 @@ void GatoCentralManager::scanForPeripheralsWithServices(const QList &u return; } - qDebug() << "LE Scan in progress"; - d->notifier = new QSocketNotifier(d->hci, QSocketNotifier::Read); connect(d->notifier, SIGNAL(activated(int)), this, SLOT(_q_readNotify())); @@ -117,7 +115,6 @@ void GatoCentralManager::stopScan() { Q_D(GatoCentralManager); if (d->scanning()) { - qDebug() << "Stopping LE scan"; delete d->notifier; setsockopt(d->hci, SOL_HCI, HCI_FILTER, &d->hci_of, sizeof(d->hci_of)); hci_le_set_scan_enable(d->hci, 0, 0, d->timeout); diff --git a/gatouuid.cpp b/gatouuid.cpp index a1a3866..f87831a 100644 --- a/gatouuid.cpp +++ b/gatouuid.cpp @@ -86,6 +86,20 @@ bool GatoUUID::isNull() const return d->uuid.type == bt_uuid_t::BT_UUID_UNSPEC; } +int GatoUUID::minimumSize() const +{ + switch (d->uuid.type) { + case bt_uuid_t::BT_UUID_UNSPEC: + return 0; + case bt_uuid_t::BT_UUID16: + return 2; + case bt_uuid_t::BT_UUID32: + return 4; + default: + return 16; + } +} + quint16 GatoUUID::toUInt16(bool *ok) const { if (d->uuid.type == bt_uuid_t::BT_UUID16) { @@ -143,6 +157,28 @@ bool operator!=(const GatoUUID &a, const GatoUUID &b) return bt_uuid_cmp(&a.d->uuid, &b.d->uuid) != 0; } +QDebug operator<<(QDebug debug, const GatoUUID &uuid) +{ + quint16 uuid16; + quint32 uuid32; + bool ok = false; + + uuid16 = uuid.toUInt16(&ok); + if (ok) { + debug.nospace() << "0x" << uuid16; + return debug.space(); + } + + uuid32 = uuid.toUInt32(&ok); + if (ok) { + debug.nospace() << "0x" << uuid32; + return debug.space(); + } + + debug.nospace() << "{" << uuid.toString().toLatin1().constData() << "}"; + return debug.space(); +} + QDataStream & operator<<(QDataStream &s, const gatouint128 &u) { if (static_cast(s.byteOrder()) == QSysInfo::ByteOrder) { diff --git a/gatouuid.h b/gatouuid.h index e091512..d94d7ae 100644 --- a/gatouuid.h +++ b/gatouuid.h @@ -82,6 +82,8 @@ public: bool isNull() const; + int minimumSize() const; + quint16 toUInt16(bool *ok = 0) const; quint32 toUInt32(bool *ok = 0) const; gatouint128 toUInt128() const; @@ -95,11 +97,7 @@ private: QSharedDataPointer d; }; -inline QDebug operator<<(QDebug debug, const GatoUUID &uuid) -{ - debug << uuid.toString(); - return debug; -} +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); diff --git a/libgato.pro b/libgato.pro index a12c494..8230a75 100644 --- a/libgato.pro +++ b/libgato.pro @@ -44,12 +44,3 @@ publicheaders.files = libgato_global.h gato.h \ gatouuid.h gatoaddress.h publicheaders.path = /usr/include/gato INSTALLS += publicheaders - -OTHER_FILES += \ - qtc_packaging/debian_harmattan/rules \ - qtc_packaging/debian_harmattan/README \ - qtc_packaging/debian_harmattan/manifest.aegis \ - qtc_packaging/debian_harmattan/copyright \ - qtc_packaging/debian_harmattan/control \ - qtc_packaging/debian_harmattan/compat \ - qtc_packaging/debian_harmattan/changelog -- cgit v1.2.3