diff options
| author | Andrew Branson <andrew.branson@cern.ch> | 2016-02-14 00:35:55 +0100 |
|---|---|---|
| committer | Andrew Branson <andrew.branson@cern.ch> | 2016-02-14 00:35:55 +0100 |
| commit | 9df90e731612efe1cd9a69ae114f566c464e3e3a (patch) | |
| tree | 19f1bbeb9baa1c0582290de5d45ce47c9c30d8fa | |
| parent | 0d5ae0b50811736713bda642489d038759883589 (diff) | |
Revived old Bluez4 code from r50.
| -rw-r--r-- | rockworkd/libpebble/bluez/bluezclient.cpp | 87 | ||||
| -rw-r--r-- | rockworkd/libpebble/bluez/bluezclient.h | 11 | ||||
| -rw-r--r-- | rockworkd/libpebble/bluez/device.cpp | 498 | ||||
| -rw-r--r-- | rockworkd/libpebble/bluez/device.h | 172 | ||||
| -rw-r--r-- | rockworkd/pebblemanager.cpp | 6 |
5 files changed, 759 insertions, 15 deletions
diff --git a/rockworkd/libpebble/bluez/bluezclient.cpp b/rockworkd/libpebble/bluez/bluezclient.cpp index 8cdf848..313c540 100644 --- a/rockworkd/libpebble/bluez/bluezclient.cpp +++ b/rockworkd/libpebble/bluez/bluezclient.cpp @@ -1,5 +1,6 @@ #include "bluezclient.h" #include "dbus-shared.h" +#include "device.h" #include <QDBusConnection> #include <QDBusReply> @@ -26,32 +27,84 @@ BluezClient::BluezClient(QObject *parent): InterfaceList ifaces = objectList.value(path); if (ifaces.contains(BLUEZ_DEVICE_IFACE)) { QString candidatePath = path.path(); + qDebug() << "have device" << candidatePath; auto properties = ifaces.value(BLUEZ_DEVICE_IFACE); addDevice(path, properties); } } + + if (m_devices.isEmpty()) { + // Try with bluez 4 + QDBusConnection system = QDBusConnection::systemBus(); + + QDBusReply<QList<QDBusObjectPath> > listAdaptersReply = system.call( + QDBusMessage::createMethodCall("org.bluez", "/", "org.bluez.Manager", + "ListAdapters")); + if (!listAdaptersReply.isValid()) { + qWarning() << listAdaptersReply.error().message(); + return; + } + + QList<QDBusObjectPath> adapters = listAdaptersReply.value(); + + if (adapters.isEmpty()) { + qWarning() << "No BT adapters found"; + return; + } + + QDBusReply<QVariantMap> adapterPropertiesReply = system.call( + QDBusMessage::createMethodCall("org.bluez", adapters[0].path(), "org.bluez.Adapter", + "GetProperties")); + if (!adapterPropertiesReply.isValid()) { + qWarning() << adapterPropertiesReply.error().message(); + return; + } + + QList<QDBusObjectPath> devices; + adapterPropertiesReply.value()["Devices"].value<QDBusArgument>() >> devices; + + foreach (QDBusObjectPath path, devices) { + QDBusReply<QVariantMap> devicePropertiesReply = system.call( + QDBusMessage::createMethodCall("org.bluez", path.path(), "org.bluez.Device", + "GetProperties")); + if (!devicePropertiesReply.isValid()) { + qCritical() << devicePropertiesReply.error().message(); + continue; + } + + const QVariantMap &dict = devicePropertiesReply.value(); + + QString name = dict["Name"].toString(); + if (name.startsWith("Pebble") && !name.startsWith("Pebble Time LE") && !name.startsWith("Pebble-LE")) { + qDebug() << "Found Pebble:" << name; + addDevice(path, dict); + } + } + } } } -QList<Device> BluezClient::pairedPebbles() const +QList<BluezDevice> BluezClient::pairedPebbles() const { - QList<Device> ret; - if (m_bluezManager.isValid()) { - foreach (const Device &dev, m_devices) { - ret << dev; - } + QList<BluezDevice> ret; + + foreach (const BluezDevice &dev, m_devices) { + ret << dev; } + return ret; + } void BluezClient::addDevice(const QDBusObjectPath &path, const QVariantMap &properties) { QString address = properties.value("Address").toString(); QString name = properties.value("Name").toString(); + qDebug() << "Adding device" << address << name; if (name.startsWith("Pebble") && !name.startsWith("Pebble Time LE") && !name.startsWith("Pebble-LE") && !m_devices.contains(address)) { qDebug() << "Found new Pebble:" << address << name; - Device device; + BluezDevice device; device.address = QBluetoothAddress(address); device.name = name; device.path = path.path(); @@ -70,6 +123,26 @@ void BluezClient::slotInterfacesAdded(const QDBusObjectPath &path, InterfaceList } } +void BluezClient::slotDevicePairingDone(bool success) +{ + qDebug() << "pairing done" << success; + if (!success) { + return; + } + + Device *device = static_cast<Device*>(sender()); + device->deleteLater(); + + if (!m_devices.contains(device->getAddress())) { + BluezDevice bluezDevice; + bluezDevice.address = QBluetoothAddress(device->getAddress()); + bluezDevice.name = device->getName(); + bluezDevice.path = device->getPath(); + m_devices.insert(device->getAddress(), bluezDevice); + emit devicesChanged(); + } +} + void BluezClient::slotInterfacesRemoved(const QDBusObjectPath &path, const QStringList &ifaces) { qDebug() << "interfaces removed" << path.path() << ifaces; diff --git a/rockworkd/libpebble/bluez/bluezclient.h b/rockworkd/libpebble/bluez/bluezclient.h index f8e5749..cbe7c0f 100644 --- a/rockworkd/libpebble/bluez/bluezclient.h +++ b/rockworkd/libpebble/bluez/bluezclient.h @@ -11,7 +11,7 @@ #include "bluez_adapter1.h" #include "bluez_agentmanager1.h" -class Device { +class BluezDevice { public: QBluetoothAddress address; QString name; @@ -26,14 +26,15 @@ public: BluezClient(QObject *parent = 0); - QList<Device> pairedPebbles() const; + QList<BluezDevice> pairedPebbles() const; private slots: void addDevice(const QDBusObjectPath &path, const QVariantMap &properties); void slotInterfacesAdded(const QDBusObjectPath&path, InterfaceList ifaces); - void slotInterfacesRemoved(const QDBusObjectPath&path, const QStringList &ifaces); - + void slotDevicePairingDone(bool success); + void slotInterfacesRemoved(const QDBusObjectPath&path, const QStringList &ifaces); + signals: void devicesChanged(); @@ -45,7 +46,7 @@ private: FreeDesktopProperties *m_bluezAdapterProperties = nullptr; - QHash<QString, Device> m_devices; + QHash<QString, BluezDevice> m_devices; }; #endif // BLUEZCLIENT_H diff --git a/rockworkd/libpebble/bluez/device.cpp b/rockworkd/libpebble/bluez/device.cpp new file mode 100644 index 0000000..9a0e9c3 --- /dev/null +++ b/rockworkd/libpebble/bluez/device.cpp @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2013-2015 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Charles Kerr <charles.kerr@canonical.com> + */ + +#include "device.h" + +#include <QDBusReply> +#include <QDebug> // qWarning() +#include <QThread> +#include <QTimer> + +#include "dbus-shared.h" + +Device::Device(const QString &path, QDBusConnection &bus) : + m_strength(Device::None) +{ + initDevice(path, bus); +} + +void Device::initDevice(const QString &path, QDBusConnection &bus) +{ + /* whenever any of the properties changes, + trigger the catch-all deviceChanged() signal */ + QObject::connect(this, SIGNAL(nameChanged()), this, SIGNAL(deviceChanged())); + QObject::connect(this, SIGNAL(iconNameChanged()), this, SIGNAL(deviceChanged())); + QObject::connect(this, SIGNAL(addressChanged()), this, SIGNAL(deviceChanged())); + QObject::connect(this, SIGNAL(pairedChanged()), this, SIGNAL(deviceChanged())); + QObject::connect(this, SIGNAL(trustedChanged()), this, SIGNAL(deviceChanged())); + QObject::connect(this, SIGNAL(typeChanged()), this, SIGNAL(deviceChanged())); + QObject::connect(this, SIGNAL(connectionChanged()), this, SIGNAL(deviceChanged())); + QObject::connect(this, SIGNAL(strengthChanged()), this, SIGNAL(deviceChanged())); + + m_bluezDevice.reset(new BluezDevice1(BLUEZ_SERVICE, path, bus)); + /* Give our calls a bit more time than the default 25 seconds to + * complete whatever they are doing. In some situations (e.g. with + * specific devices) the default doesn't seem to be enough to. */ + m_bluezDevice->setTimeout(60 * 1000 /* 60 seconds */); + + m_bluezDeviceProperties.reset(new FreeDesktopProperties(BLUEZ_SERVICE, path, bus)); + + QObject::connect(m_bluezDeviceProperties.data(), SIGNAL(PropertiesChanged(const QString&, const QVariantMap&, const QStringList&)), + this, SLOT(slotPropertiesChanged(const QString&, const QVariantMap&, const QStringList&))); + + Q_EMIT(pathChanged()); + + watchCall(m_bluezDeviceProperties->GetAll(BLUEZ_DEVICE_IFACE), [=](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply<QVariantMap> reply = *watcher; + + if (reply.isError()) { + qWarning() << "Failed to retrieve properties for device" << m_bluezDevice->path(); + watcher->deleteLater(); + return; + } + + auto properties = reply.argumentAt<0>(); + setProperties(properties); + + watcher->deleteLater(); + }); +} + +void Device::slotPropertiesChanged(const QString &interface, const QVariantMap &changedProperties, + const QStringList &invalidatedProperties) +{ + Q_UNUSED(invalidatedProperties); + + if (interface != BLUEZ_DEVICE_IFACE) + return; + + setProperties(changedProperties); +} + +void Device::setProperties(const QMap<QString,QVariant> &properties) +{ + QMapIterator<QString,QVariant> it(properties); + while (it.hasNext()) { + it.next(); + updateProperty(it.key(), it.value()); + } +} + +void Device::setConnectAfterPairing(bool value) +{ + if (m_connectAfterPairing == value) + return; + + m_connectAfterPairing = value; +} + +void Device::disconnect() +{ + setConnection(Device::Disconnecting); + + QDBusPendingCall call = m_bluezDevice->Disconnect(); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply<void> reply = *watcher; + + if (reply.isError()) { + qWarning() << "Could not disconnect device:" + << reply.error().message(); + + // Make sure we switch the connection indicator back to + // a sane state + updateConnection(); + } + + watcher->deleteLater(); + }); +} + +void Device::connectAfterPairing() +{ + if (!m_connectAfterPairing) + return; + + connect(); +} + +void Device::pair() +{ + if (m_paired) { + // If we are already paired we just have to make sure we + // trigger the connection process if we have to + connectAfterPairing(); + return; + } + + setConnection(Device::Connecting); + + m_isPairing = true; + + auto call = m_bluezDevice->asyncCall("Pair"); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply<void> reply = *watcher; + bool success = true; + + if (reply.isError()) { + qWarning() << "Failed to pair with device:" + << reply.error().message(); + updateConnection(); + success = false; + } + + m_isPairing = false; + + Q_EMIT(pairingDone(success)); + + watcher->deleteLater(); + }); +} + +void Device::cancelPairing() +{ + if (!m_isPairing) + return; + + auto call = m_bluezDevice->asyncCall("CancelPairing"); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply<void> reply = *watcher; + + if (reply.isError()) { + qWarning() << "Failed to cancel pairing attempt with device:" + << reply.error().message(); + updateConnection(); + } else { + // Only mark us a not pairing when call succeeded + m_isPairing = false; + } + + watcher->deleteLater(); + }); +} + +void Device::connect() +{ + // If we have just paired then the device switched to connected = true for + // a short moment as BlueZ opened up a RFCOMM channel to perform SDP. If + // we should connect with the device on specific profiles now we go ahead + // here even if we're marked as connected as this still doesn't mean we're + // connected on any profile. Calling org.bluez.Device1.Connect multiple + // times doesn't hurt an will not fail. + if (m_isConnected && !m_connectAfterPairing) + return; + + setConnection(Device::Connecting); + + QDBusPendingCall call = m_bluezDevice->asyncCall("Connect"); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply<void> reply = *watcher; + + if (reply.isError()) { + qWarning() << "Could not connect device:" + << reply.error().message(); + } else { + makeTrusted(true); + } + + // Regardless if the Connected property has changed or not we update + // the connection state here as the connection process is over now + // and we should have received any state change already at this + // point. + updateConnection(); + + watcher->deleteLater(); + }); +} + +void Device::slotMakeTrustedDone(QDBusPendingCallWatcher *call) +{ + QDBusPendingReply<void> reply = *call; + + if (reply.isError()) { + qWarning() << "Could not mark device as trusted:" + << reply.error().message(); + } + + call->deleteLater(); +} + +void Device::makeTrusted(bool trusted) +{ + auto call = m_bluezDeviceProperties->Set(BLUEZ_DEVICE_IFACE, "Trusted", QDBusVariant(trusted)); + + auto watcher = new QDBusPendingCallWatcher(call, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(slotMakeTrustedDone(QDBusPendingCallWatcher*))); +} + +void Device::setName(const QString &name) +{ + if (m_name != name) { + m_name = name; + Q_EMIT(nameChanged()); + } +} + +void Device::setIconName(const QString &iconName) +{ + if (m_iconName != iconName) { + m_iconName = iconName; + Q_EMIT(iconNameChanged()); + } +} + +void Device::setAddress(const QString &address) +{ + if (m_address != address) { + m_address = address; + Q_EMIT(addressChanged()); + } +} + +void Device::setType(Type type) +{ + if (m_type != type) { + m_type = type; + Q_EMIT(typeChanged()); + updateIcon(); + } +} + +void Device::setPaired(bool paired) +{ + if (m_paired != paired) { + m_paired = paired; + Q_EMIT(pairedChanged()); + } +} + +void Device::setTrusted(bool trusted) +{ + if (m_trusted != trusted) { + m_trusted = trusted; + Q_EMIT(trustedChanged()); + } +} + +void Device::setConnection(Connection connection) +{ + if (m_connection != connection) { + m_connection = connection; + Q_EMIT(connectionChanged()); + } +} + +void Device::updateIcon() +{ + /* bluez-provided icon is unreliable? In testing I'm getting + an "audio-card" icon from bluez for my NoiseHush N700 headset. + Try to guess the icon from the device type, + and use the bluez-provided icon as a fallback */ + + const auto type = getType(); + + switch (type) { + case Type::Headset: + setIconName("image://theme/audio-headset-symbolic"); + break; + case Type::Headphones: + setIconName("image://theme/audio-headphones-symbolic"); + break; + case Type::Carkit: + setIconName("image://theme/audio-carkit-symbolic"); + break; + case Type::Speakers: + case Type::OtherAudio: + setIconName("image://theme/audio-speakers-symbolic"); + break; + case Type::Mouse: + setIconName("image://theme/input-mouse-symbolic"); + break; + case Type::Keyboard: + setIconName("image://theme/input-keyboard-symbolic"); + break; + case Type::Cellular: + setIconName("image://theme/phone-cellular-symbolic"); + break; + case Type::Smartphone: + setIconName("image://theme/phone-smartphone-symbolic"); + break; + case Type::Phone: + setIconName("image://theme/phone-uncategorized-symbolic"); + break; + case Type::Computer: + setIconName("image://theme/computer-symbolic"); + break; + default: + setIconName(QString("image://theme/%1").arg(m_fallbackIconName)); + } +} + +void Device::updateConnection() +{ + Connection c; + + c = m_isConnected ? Connection::Connected : Connection::Disconnected; + + setConnection(c); +} + +void Device::updateProperty(const QString &key, const QVariant &value) +{ + if (key == "Name") { + setName(value.toString()); + } else if (key == "Address") { + setAddress(value.toString()); + } else if (key == "Connected") { + m_isConnected = value.toBool(); + updateConnection(); + } else if (key == "Class") { + setType(getTypeFromClass(value.toUInt())); + } else if (key == "Paired") { + setPaired(value.toBool()); + + if (m_paired && m_connectAfterPairing) { + connectAfterPairing(); + return; + } + + updateConnection(); + } else if (key == "Trusted") { + setTrusted(value.toBool()); + } else if (key == "Icon") { + m_fallbackIconName = value.toString(); + updateIcon (); + } else if (key == "RSSI") { + m_strength = getStrengthFromRssi(value.toInt()); + Q_EMIT(strengthChanged()); + } +} + +/* Determine the Type from the bits in the Class of Device (CoD) field. + https://www.bluetooth.org/en-us/specification/assigned-numbers/baseband */ +Device::Type Device::getTypeFromClass (quint32 c) +{ + switch ((c & 0x1f00) >> 8) { + case 0x01: + return Type::Computer; + + case 0x02: + switch ((c & 0xfc) >> 2) { + case 0x01: + return Type::Cellular; + case 0x03: + return Type::Smartphone; + case 0x04: + return Type::Modem; + default: + return Type::Phone; + } + break; + + case 0x03: + return Type::Network; + + case 0x04: + switch ((c & 0xfc) >> 2) { + case 0x01: + case 0x02: + return Type::Headset; + + case 0x05: + return Type::Speakers; + + case 0x06: + return Type::Headphones; + + case 0x08: + return Type::Carkit; + + case 0x0b: // vcr + case 0x0c: // video camera + case 0x0d: // camcorder + return Type::Video; + + default: + return Type::OtherAudio; + } + break; + + case 0x05: + switch ((c & 0xc0) >> 6) { + case 0x00: + switch ((c & 0x1e) >> 2) { + case 0x01: + case 0x02: + return Type::Joypad; + } + break; + + case 0x01: + return Type::Keyboard; + + case 0x02: + switch ((c & 0x1e) >> 2) { + case 0x05: + return Type::Tablet; + default: + return Type::Mouse; + } + } + break; + + case 0x06: + if ((c & 0x80) != 0) + return Type::Printer; + if ((c & 0x20) != 0) + return Type::Camera; + break; + + case 0x07: + if ((c & 0x4) != 0) + return Type::Watch; + break; + } + + return Type::Other; +} + +Device::Strength Device::getStrengthFromRssi(int rssi) +{ + /* Modelled similar to what Mac OS X does. + * See http://www.cnet.com/how-to/how-to-check-bluetooth-connection-strength-in-os-x/ */ + + if (rssi >= -60) + return Excellent; + else if (rssi < -60 && rssi >= -70) + return Good; + else if (rssi < -70 && rssi >= -90) + return Fair; + else if (rssi < -90) + return Poor; + + return None; +} diff --git a/rockworkd/libpebble/bluez/device.h b/rockworkd/libpebble/bluez/device.h new file mode 100644 index 0000000..bcc044b --- /dev/null +++ b/rockworkd/libpebble/bluez/device.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2013-2015 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Charles Kerr <charles.kerr@canonical.com> + */ + +#ifndef USS_BLUETOOTH_DEVICE_H +#define USS_BLUETOOTH_DEVICE_H + +#include <QDBusConnection> +#include <QDBusInterface> +#include <QDBusPendingCallWatcher> +#include <QSharedPointer> +#include <QString> + +#include "freedesktop_properties.h" +#include "bluez_device1.h" + +struct Device: QObject +{ + Q_OBJECT + + Q_PROPERTY(QString path + READ getPath + NOTIFY pathChanged) + + Q_PROPERTY(QString name + READ getName + NOTIFY nameChanged) + + Q_PROPERTY(QString iconName + READ getIconName + NOTIFY iconNameChanged) + + Q_PROPERTY(QString address + READ getAddress + NOTIFY addressChanged) + + Q_PROPERTY(Type type + READ getType + NOTIFY typeChanged) + + Q_PROPERTY(bool paired + READ isPaired + NOTIFY pairedChanged) + + Q_PROPERTY(bool trusted + READ isTrusted + WRITE makeTrusted + NOTIFY trustedChanged) + + Q_PROPERTY(Connection connection + READ getConnection + NOTIFY connectionChanged) + + Q_PROPERTY(Strength strength + READ getStrength + NOTIFY strengthChanged) + +public: + + enum Type { Other, Computer, Cellular, Smartphone, Phone, Modem, Network, + Headset, Speakers, Headphones, Video, OtherAudio, Joypad, + Keypad, Keyboard, Tablet, Mouse, Printer, Camera, Carkit, Watch }; + + enum Strength { None, Poor, Fair, Good, Excellent }; + + enum Connection { Disconnected=1, Connecting=2, + Connected=4, Disconnecting=8 }; + + Q_ENUMS(Type Strength Connection) + + Q_DECLARE_FLAGS(Connections, Connection) + +Q_SIGNALS: + void pathChanged(); + void nameChanged(); + void iconNameChanged(); + void addressChanged(); + void typeChanged(); + void pairedChanged(); + void trustedChanged(); + void connectionChanged(); + void strengthChanged(); + void deviceChanged(); // catchall for any change + void pairingDone(bool success); + +public: + const QString& getName() const { return m_name; } + const QString& getAddress() const { return m_address; } + const QString& getIconName() const { return m_iconName; } + Type getType() const { return m_type; } + bool isPaired() const { return m_paired; } + bool isTrusted() const { return m_trusted; } + Connection getConnection() const { return m_connection; } + Strength getStrength() const { return m_strength; } + QString getPath() const { return m_bluezDevice ? m_bluezDevice->path() : QString(); } + + private: + QString m_name; + QString m_state; + QString m_address; + QString m_iconName; + QString m_fallbackIconName; + Type m_type = Type::Other; + bool m_paired = false; + bool m_trusted = false; + Connection m_connection = Connection::Disconnected; + Strength m_strength = Strength::None; + bool m_isConnected = false; + bool m_connectAfterPairing = false; + QScopedPointer<BluezDevice1> m_bluezDevice; + QScopedPointer<FreeDesktopProperties> m_bluezDeviceProperties; + bool m_isPairing = false; + + protected: + void setName(const QString &name); + void setIconName(const QString &name); + void setAddress(const QString &address); + void setType(Type type); + void setPaired(bool paired); + void setTrusted(bool trusted); + void setConnection(Connection connection); + void setStrength(Strength strength); + void updateIcon(); + void updateConnection(); + + public: + Device() {} + Device(const QString &path, QDBusConnection &bus); + ~Device() {} + bool isValid() const { return getType() != Type::Other; } + void pair(); + Q_INVOKABLE void cancelPairing(); + void connect(); + void makeTrusted(bool trusted); + void disconnect(); + void setProperties(const QMap<QString,QVariant> &properties); + void setConnectAfterPairing(bool value); + + private Q_SLOTS: + void slotPropertiesChanged(const QString &interface, const QVariantMap &changedProperties, + const QStringList &invalidatedProperties); + void slotMakeTrustedDone(QDBusPendingCallWatcher *call); + + private: + void initDevice(const QString &path, QDBusConnection &bus); + void updateProperties(QSharedPointer<QDBusInterface>); + void updateProperty(const QString &key, const QVariant &value); + static Type getTypeFromClass(quint32 bluetoothClass); + Device::Strength getStrengthFromRssi(int rssi); + void connectAfterPairing(); +}; + +Q_DECLARE_METATYPE(Device*) + +Q_DECLARE_OPERATORS_FOR_FLAGS(Device::Connections) + +#endif // USS_BLUETOOTH_DEVICE_H diff --git a/rockworkd/pebblemanager.cpp b/rockworkd/pebblemanager.cpp index a119812..842dff0 100644 --- a/rockworkd/pebblemanager.cpp +++ b/rockworkd/pebblemanager.cpp @@ -26,8 +26,8 @@ QList<Pebble *> PebbleManager::pebbles() const void PebbleManager::loadPebbles() { - QList<Device> pairedPebbles = m_bluezClient->pairedPebbles(); - foreach (const Device &device, pairedPebbles) { + QList<BluezDevice> pairedPebbles = m_bluezClient->pairedPebbles(); + foreach (const BluezDevice &device, pairedPebbles) { qDebug() << "loading pebble" << device.address.toString(); Pebble *pebble = get(device.address); if (!pebble) { @@ -46,7 +46,7 @@ void PebbleManager::loadPebbles() QList<Pebble*> pebblesToRemove; foreach (Pebble *pebble, m_pebbles) { bool found = false; - foreach (const Device &dev, pairedPebbles) { + foreach (const BluezDevice &dev, pairedPebbles) { if (dev.address == pebble->address()) { found = true; break; |
