summaryrefslogtreecommitdiff
path: root/daemon/watchconnector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/watchconnector.cpp')
-rw-r--r--daemon/watchconnector.cpp132
1 files changed, 99 insertions, 33 deletions
diff --git a/daemon/watchconnector.cpp b/daemon/watchconnector.cpp
index d9cdd67..09006c0 100644
--- a/daemon/watchconnector.cpp
+++ b/daemon/watchconnector.cpp
@@ -1,6 +1,12 @@
#include <QDateTime>
#include <QMetaEnum>
#include <QDebugStateSaver>
+#include <QBluetoothLocalDevice>
+#include <QDBusConnection>
+#include <QDBusMessage>
+#include <QDBusReply>
+#include <QDBusArgument>
+#include <QDBusObjectPath>
#include "unpacker.h"
#include "watchconnector.h"
@@ -64,12 +70,13 @@ bool WatchConnector::WatchVersions::isEmpty() const
}
WatchConnector::WatchConnector(QObject *parent) :
- QObject(parent), l(metaObject()->className()), socket(nullptr), is_connected(false)
+ QObject(parent), l(metaObject()->className()),
+ socket(nullptr), is_connected(false), currentPebble(0), _last_address(0)
{
reconnectTimer.setSingleShot(true);
- connect(&reconnectTimer, SIGNAL(timeout()), SLOT(reconnect()));
+ QObject::connect(&reconnectTimer, SIGNAL(timeout()), SLOT(connect()));
timeSyncTimer.setSingleShot(true);
- connect(&timeSyncTimer, SIGNAL(timeout()), SLOT(time()));
+ QObject::connect(&timeSyncTimer, SIGNAL(timeout()), SLOT(time()));
timeSyncTimer.setInterval(4 * 60 * 60 * 1000); // sync time every 4 hours
firmwareMapping.insert(UNKNOWN, "unknown");
@@ -128,28 +135,71 @@ WatchConnector::~WatchConnector()
{
}
-void WatchConnector::deviceDiscovered(const QBluetoothDeviceInfo &device)
+//dbus-send --system --dest=org.bluez --print-reply / org.bluez.Manager.ListAdapters
+//dbus-send --system --dest=org.bluez --print-reply $path org.bluez.Adapter.GetProperties
+//dbus-send --system --dest=org.bluez --print-reply $devpath org.bluez.Device.GetProperties
+//dbus-send --system --dest=org.bluez --print-reply $devpath org.bluez.Input.Connect
+bool WatchConnector::findPebbles()
{
- //FIXME TODO: Configurable
- if (device.name().startsWith("Pebble")) {
- qCDebug(l) << "Found Pebble:" << device.name() << '(' << device.address().toString() << ')';
- handleWatch(device.name(), device.address().toString());
- } else {
- qCDebug(l) << "Found other device:" << device.name() << '(' << device.address().toString() << ')';
+ pebbles.clear();
+ currentPebble = 0;
+
+ QDBusConnection system = QDBusConnection::systemBus();
+
+ QDBusReply<QList<QDBusObjectPath>> ListAdaptersReply = system.call(
+ QDBusMessage::createMethodCall("org.bluez", "/", "org.bluez.Manager",
+ "ListAdapters"));
+ if (not ListAdaptersReply.isValid()) {
+ qCCritical(l) << ListAdaptersReply.error().message();
+ return false;
}
-}
-void WatchConnector::deviceConnect(const QString &name, const QString &address)
-{
- if (name.startsWith("Pebble")) handleWatch(name, address);
-}
+ QList<QDBusObjectPath> adapters = ListAdaptersReply.value();
-void WatchConnector::reconnect()
-{
- qCDebug(l) << "reconnect" << _last_name;
- if (!_last_name.isEmpty() && !_last_address.isEmpty()) {
- deviceConnect(_last_name, _last_address);
+ if (adapters.isEmpty()) {
+ qCDebug(l) << "No BT adapters found";
+ return false;
+ }
+
+ QDBusReply<QVariantMap> AdapterPropertiesReply = system.call(
+ QDBusMessage::createMethodCall("org.bluez", adapters[0].path(), "org.bluez.Adapter",
+ "GetProperties"));
+ if (not AdapterPropertiesReply.isValid()) {
+ qCCritical(l) << AdapterPropertiesReply.error().message();
+ return false;
+ }
+
+ 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 (not DevicePropertiesReply.isValid()) {
+ qCCritical(l) << DevicePropertiesReply.error().message();
+ continue;
+ }
+
+ const QVariantMap &dict = DevicePropertiesReply.value();
+
+ QString tmp = dict["Name"].toString();
+ qCDebug(l) << "Found BT device:" << tmp;
+ if (tmp.startsWith("Pebble")) {
+ qCDebug(l) << "Found Pebble:" << tmp;
+ QBluetoothAddress addr(dict["Address"].toString());
+ QBluetoothLocalDevice dev;
+ if (dev.pairingStatus(addr) == QBluetoothLocalDevice::AuthorizedPaired) {
+ pebbles.insert(dict["Name"].toString(), addr);
+ }
+ }
}
+
+ if (pebbles.size()) {
+ scheduleReconnect();
+ }
+
+ return true;
}
void WatchConnector::disconnect()
@@ -162,11 +212,23 @@ void WatchConnector::disconnect()
qCDebug(l) << "stopped timers";
}
-void WatchConnector::handleWatch(const QString &name, const QString &address)
+void WatchConnector::connect()
{
- qCDebug(l) << "handleWatch" << name << address;
+ if (currentPebble >= pebbles.count()) {
+ currentPebble = 0;
+ }
+
+ QString _name = pebbles.keys().at(currentPebble);
+ QBluetoothAddress _address = pebbles.value(_name);
+
+ qCDebug(l) << "connect watch" << currentPebble << _name << _address.toString();
reconnectTimer.stop();
+ if (_address.isNull()) {
+ qCWarning(l) << "No known pebble";
+ return;
+ }
+
// Check if bluetooth is on
QBluetoothLocalDevice host;
bool btOff = host.hostMode() == QBluetoothLocalDevice::HostPoweredOff;
@@ -181,20 +243,18 @@ void WatchConnector::handleWatch(const QString &name, const QString &address)
socket->deleteLater();
}
- _last_name = name;
- _last_address = address;
_versions.clear();
qCDebug(l) << "Creating socket";
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
- connect(socket, SIGNAL(readyRead()), SLOT(onReadSocket()));
- connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(onBytesWritten(qint64)));
- connect(socket, SIGNAL(connected()), SLOT(onConnected()));
- connect(socket, SIGNAL(disconnected()), SLOT(onDisconnected()));
- connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(onError(QBluetoothSocket::SocketError)));
+ QObject::connect(socket, SIGNAL(readyRead()), SLOT(onReadSocket()));
+ QObject::connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(onBytesWritten(qint64)));
+ QObject::connect(socket, SIGNAL(connected()), SLOT(onConnected()));
+ QObject::connect(socket, SIGNAL(disconnected()), SLOT(onDisconnected()));
+ QObject::connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(onError(QBluetoothSocket::SocketError)));
// FIXME: Assuming port 1 (with Pebble)
- socket->connectToService(QBluetoothAddress(address), 1);
+ socket->connectToService(_address, 1);
}
QString WatchConnector::decodeEndpoint(uint val)
@@ -319,7 +379,9 @@ void WatchConnector::onConnected()
}
sendMessage(watchVERSION, QByteArray(1, 0));
emit connectedChanged();
- if (name() != _last_name) emit nameChanged();
+ quint64 new_address = address().toUInt64();
+ if (new_address != _last_address) emit pebbleChanged();
+ _last_address = new_address;
time();
}
}
@@ -358,7 +420,11 @@ void WatchConnector::scheduleReconnect()
void WatchConnector::onError(QBluetoothSocket::SocketError error)
{
if (error == QBluetoothSocket::UnknownSocketError) {
- qCDebug(l) << error << socket->errorString();
+ QString errorString = socket->errorString();
+ qCDebug(l) << error << errorString;
+ if (errorString.endsWith(" down")) {
+ currentPebble++;
+ }
} else {
qCCritical(l) << "error connecting Pebble:" << error << socket->errorString();
}
@@ -369,7 +435,7 @@ void WatchConnector::sendData(const QByteArray &data)
writeData.append(data);
if (socket == nullptr) {
qCDebug(l) << "no socket - reconnecting";
- reconnect();
+ connect();
} else if (is_connected) {
qCDebug(l) << "writing" << data.length() << "bytes to socket";
if (PROTOCOL_DEBUG) qCDebug(l) << data.toHex();