From e34f49ff20f2227ffca0515201e7493fd55ef64a Mon Sep 17 00:00:00 2001 From: Javier Date: Sat, 26 Jul 2014 22:59:39 +0200 Subject: add "requireencryption" connection option (ABI broken!) --- gatoaddress.cpp | 3 +-- gatoattclient.cpp | 10 ++++++++-- gatoattclient.h | 3 ++- gatocentralmanager.h | 6 +++--- gatoperipheral.cpp | 9 +++++++-- gatoperipheral.h | 12 +++++++++++- gatosocket.cpp | 38 ++++++++++++++++++++++++++++++++++++++ gatosocket.h | 1 + rpm/libgato.spec | 2 +- rpm/libgato.yaml | 2 +- 10 files changed, 73 insertions(+), 13 deletions(-) diff --git a/gatoaddress.cpp b/gatoaddress.cpp index 3aeb355..b99a977 100644 --- a/gatoaddress.cpp +++ b/gatoaddress.cpp @@ -36,10 +36,9 @@ struct GatoAddressPrivate : QSharedData GatoAddress::GatoAddress() : d(new GatoAddressPrivate) { + d->addr.u64 = 0; } - - GatoAddress::GatoAddress(quint64 addr) : d(new GatoAddressPrivate) { diff --git a/gatoattclient.cpp b/gatoattclient.cpp index 6cf6d69..0bf5877 100644 --- a/gatoattclient.cpp +++ b/gatoattclient.cpp @@ -75,7 +75,8 @@ static QByteArray remove_method_signature(const char *sig) } GatoAttClient::GatoAttClient(QObject *parent) : - QObject(parent), socket(new GatoSocket(this)), cur_mtu(ATT_DEFAULT_LE_MTU), next_id(1) + QObject(parent), socket(new GatoSocket(this)), cur_mtu(ATT_DEFAULT_LE_MTU), next_id(1), + required_sec(GatoSocket::SecurityLow) { connect(socket, SIGNAL(connected()), SLOT(handleSocketConnected())); connect(socket, SIGNAL(disconnected()), SLOT(handleSocketDisconnected())); @@ -91,8 +92,9 @@ GatoSocket::State GatoAttClient::state() const return socket->state(); } -bool GatoAttClient::connectTo(const GatoAddress &addr) +bool GatoAttClient::connectTo(const GatoAddress &addr, GatoSocket::SecurityLevel sec_level) { + required_sec = sec_level; return socket->connectTo(addr, ATT_CID); } @@ -540,6 +542,10 @@ QList GatoAttClient::parseAttributeGroupData( void GatoAttClient::handleSocketConnected() { + if (socket->securityLevel() < required_sec) { + socket->setSecurityLevel(required_sec); + } + requestExchangeMTU(ATT_MAX_LE_MTU, this, SLOT(handleServerMTU(quint16))); emit connected(); } diff --git a/gatoattclient.h b/gatoattclient.h index 834178e..64df313 100644 --- a/gatoattclient.h +++ b/gatoattclient.h @@ -16,7 +16,7 @@ public: GatoSocket::State state() const; - bool connectTo(const GatoAddress& addr); + bool connectTo(const GatoAddress& addr, GatoSocket::SecurityLevel sec_level); void close(); struct InformationData @@ -93,6 +93,7 @@ private: quint16 cur_mtu; uint next_id; QQueue pending_requests; + GatoSocket::SecurityLevel required_sec; }; #endif // GATOATTCLIENT_H diff --git a/gatocentralmanager.h b/gatocentralmanager.h index 857b9cc..7ebe2cf 100644 --- a/gatocentralmanager.h +++ b/gatocentralmanager.h @@ -16,15 +16,15 @@ class LIBGATO_EXPORT GatoCentralManager : public QObject Q_FLAGS(PeripheralScanOptions) public: + explicit GatoCentralManager(QObject *parent = 0); + ~GatoCentralManager(); + enum PeripheralScanOption { PeripheralScanOptionActive = 1 << 0, PeripheralScanOptionAllowDuplicates = 1 << 1 }; Q_DECLARE_FLAGS(PeripheralScanOptions, PeripheralScanOption) - explicit GatoCentralManager(QObject *parent = 0); - ~GatoCentralManager(); - GatoPeripheral *getPeripheral(const GatoAddress& address); public slots: diff --git a/gatoperipheral.cpp b/gatoperipheral.cpp index 2225672..21244b8 100644 --- a/gatoperipheral.cpp +++ b/gatoperipheral.cpp @@ -149,7 +149,7 @@ bool GatoPeripheral::advertisesService(const GatoUUID &uuid) const return d->service_uuids.contains(uuid); } -void GatoPeripheral::connectPeripheral() +void GatoPeripheral::connectPeripheral(PeripheralConnectOptions options) { Q_D(GatoPeripheral); if (d->att->state() != GatoSocket::StateDisconnected) { @@ -157,7 +157,12 @@ void GatoPeripheral::connectPeripheral() return; } - d->att->connectTo(d->addr); + GatoSocket::SecurityLevel sec_level = GatoSocket::SecurityLow; + if (options & PeripheralConnectOptionRequireEncryption) { + sec_level = GatoSocket::SecurityMedium; + } + + d->att->connectTo(d->addr, sec_level); } void GatoPeripheral::disconnectPeripheral() diff --git a/gatoperipheral.h b/gatoperipheral.h index 4b757df..5a7f463 100644 --- a/gatoperipheral.h +++ b/gatoperipheral.h @@ -17,6 +17,7 @@ class LIBGATO_EXPORT GatoPeripheral : public QObject Q_DECLARE_PRIVATE(GatoPeripheral) Q_ENUMS(State) Q_ENUMS(WriteType) + Q_FLAGS(PeripheralConnectOptions) Q_PROPERTY(GatoAddress address READ address) Q_PROPERTY(QString name READ name NOTIFY nameChanged) @@ -24,6 +25,11 @@ public: GatoPeripheral(const GatoAddress& addr, QObject *parent = 0); ~GatoPeripheral(); + enum PeripheralConnectOption { + PeripheralConnectOptionRequireEncryption = 1 << 0 + }; + Q_DECLARE_FLAGS(PeripheralConnectOptions, PeripheralConnectOption) + enum State { StateDisconnected, StateConnecting, @@ -44,13 +50,15 @@ public: bool advertisesService(const GatoUUID &uuid) const; public slots: - void connectPeripheral(); + void connectPeripheral(PeripheralConnectOptions options); void disconnectPeripheral(); + void discoverServices(); void discoverServices(const QList& serviceUUIDs); void discoverCharacteristics(const GatoService &service); void discoverCharacteristics(const GatoService &service, const QList& characteristicUUIDs); void discoverDescriptors(const GatoCharacteristic &characteristic); + void readValue(const GatoCharacteristic &characteristic); void readValue(const GatoDescriptor &descriptor); void writeValue(const GatoCharacteristic &characteristic, const QByteArray &data, WriteType type = WriteWithResponse); @@ -60,10 +68,12 @@ public slots: signals: void connected(); void disconnected(); + void nameChanged(); void servicesDiscovered(); void characteristicsDiscovered(const GatoService &service); void descriptorsDiscovered(const GatoCharacteristic &characteristic); + void valueUpdated(const GatoCharacteristic &characteristic, const QByteArray &value); void descriptorValueUpdated(const GatoDescriptor &descriptor, const QByteArray &value); diff --git a/gatosocket.cpp b/gatosocket.cpp index e814e8c..73567b5 100644 --- a/gatosocket.cpp +++ b/gatosocket.cpp @@ -126,6 +126,11 @@ GatoSocket::SecurityLevel GatoSocket::securityLevel() const bt_security bt_sec; socklen_t len = sizeof(bt_sec); + if (s == StateDisconnected) { + qWarning() << "Socket not connected"; + return SecurityNone; + } + if (::getsockopt(fd, SOL_BLUETOOTH, BT_SECURITY, &bt_sec, &len) == 0) { switch (bt_sec.level) { case BT_SECURITY_SDP: @@ -144,6 +149,39 @@ GatoSocket::SecurityLevel GatoSocket::securityLevel() const return SecurityNone; } +bool GatoSocket::setSecurityLevel(SecurityLevel level) +{ + bt_security bt_sec; + socklen_t len = sizeof(bt_sec); + + if (s == StateDisconnected) { + qWarning() << "Socket not connected"; + return SecurityNone; + } + + switch (level) { + case SecurityNone: + case SecurityLow: + bt_sec.level = BT_SECURITY_LOW; + break; + case SecurityMedium: + bt_sec.level = BT_SECURITY_MEDIUM; + break; + case SecurityHigh: + // Will this even work in BT LE? + bt_sec.level = BT_SECURITY_HIGH; + break; + } + bt_sec.key_size = 0; + + if (::setsockopt(fd, SOL_BLUETOOTH, BT_SECURITY, &bt_sec, len) == 0) { + return true; + } else { + qErrnoWarning("Could not set security level in L2 socket"); + return false; + } +} + bool GatoSocket::transmit(const QByteArray &pkt) { int written = ::write(fd, pkt.constData(), pkt.size()); diff --git a/gatosocket.h b/gatosocket.h index c1c025f..56760ee 100644 --- a/gatosocket.h +++ b/gatosocket.h @@ -47,6 +47,7 @@ public: void send(const QByteArray &pkt); SecurityLevel securityLevel() const; + bool setSecurityLevel(SecurityLevel level); signals: void connected(); diff --git a/rpm/libgato.spec b/rpm/libgato.spec index ff3e7cd..7ca7e60 100644 --- a/rpm/libgato.spec +++ b/rpm/libgato.spec @@ -13,7 +13,7 @@ Name: libgato %{!?qtc_make:%define qtc_make make} %{?qtc_builddir:%define _builddir %qtc_builddir} Summary: A GATT library to connect with Bluetooth Smart devices -Version: 0.1.2 +Version: 0.1.4 Release: 1 Group: Qt/Qt License: GPL2 diff --git a/rpm/libgato.yaml b/rpm/libgato.yaml index f31c25e..3f603da 100644 --- a/rpm/libgato.yaml +++ b/rpm/libgato.yaml @@ -1,6 +1,6 @@ Name: libgato Summary: A GATT library to connect with Bluetooth Smart devices -Version: 0.1.2 +Version: 0.1.4 Release: 1 Group: Qt/Qt URL: https://gitorious.org/gato/ -- cgit v1.2.3