From e84ff331fa86cb302b686daea0d93fd2b3d95f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 6 Jul 2018 09:29:26 +0200 Subject: [PATCH] First working version containing rfcom connectivity --- libnymea-app-core/bluetoothinterface.cpp | 13 ++++++-- libnymea-app-core/bluetoothinterface.h | 1 + .../discovery/bluetoothservicediscovery.cpp | 25 +++++++-------- .../discovery/discoverydevice.cpp | 5 --- libnymea-app-core/discovery/discoverydevice.h | 1 - .../discovery/discoverymodel.cpp | 4 +-- libnymea-app-core/discovery/discoverymodel.h | 2 +- libnymea-app-core/jsonrpc/jsonrpcclient.cpp | 1 + libnymea-app-core/nymeaconnection.cpp | 13 ++++++-- libnymea-app-core/nymeaconnection.h | 2 ++ nymea-app/ui/ConnectPage.qml | 31 +++++++++++++------ 11 files changed, 61 insertions(+), 37 deletions(-) diff --git a/libnymea-app-core/bluetoothinterface.cpp b/libnymea-app-core/bluetoothinterface.cpp index e9ba1e83..f55261ba 100644 --- a/libnymea-app-core/bluetoothinterface.cpp +++ b/libnymea-app-core/bluetoothinterface.cpp @@ -34,6 +34,7 @@ BluetoothInterface::BluetoothInterface(QObject *parent) : QObject::connect(m_socket, &QBluetoothSocket::connected, this, &BluetoothInterface::onConnected); QObject::connect(m_socket, &QBluetoothSocket::disconnected, this, &BluetoothInterface::onDisconnected); QObject::connect(m_socket, &QBluetoothSocket::readyRead, this, &BluetoothInterface::onDataReady); + QObject::connect(m_socket, &QBluetoothSocket::stateChanged, this, &BluetoothInterface::onDataReady); } QStringList BluetoothInterface::supportedSchemes() const @@ -50,9 +51,10 @@ void BluetoothInterface::connect(const QUrl &url) QUrlQuery query(url); QString macAddressString = query.queryItemValue("mac"); + QString name = query.queryItemValue("name"); QBluetoothAddress macAddress = QBluetoothAddress(macAddressString); - qDebug() << "Connecting to bluetooth server" << macAddressString << macAddress.toString(); + qDebug() << "Connecting to bluetooth server" << name << macAddress.toString(); m_socket->connectToService(macAddress, QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b"))); } @@ -76,7 +78,8 @@ NymeaInterface::ConnectionState BluetoothInterface::connectionState() const void BluetoothInterface::sendData(const QByteArray &data) { - m_socket->write(data + '\n'); + qDebug() << "BluetoothInterface: send data:" << qUtf8Printable(data); + m_socket->write(data); } void BluetoothInterface::onServiceFound(const QBluetoothServiceInfo &service) @@ -101,8 +104,14 @@ void BluetoothInterface::onDisconnected() emit disconnected(); } +void BluetoothInterface::onStateChanged(const QBluetoothSocket::SocketState &state) +{ + qDebug() << "BluetoothInterface" << state; +} + void BluetoothInterface::onDataReady() { QByteArray data = m_socket->readAll(); + qDebug() << "BluetoothInterface: recived data:" << qUtf8Printable(data); emit dataReady(data); } diff --git a/libnymea-app-core/bluetoothinterface.h b/libnymea-app-core/bluetoothinterface.h index 7d033eb1..e41fb333 100644 --- a/libnymea-app-core/bluetoothinterface.h +++ b/libnymea-app-core/bluetoothinterface.h @@ -49,6 +49,7 @@ private slots: void onServiceFound(const QBluetoothServiceInfo &service); void onConnected(); void onDisconnected(); + void onStateChanged(const QBluetoothSocket::SocketState &state); void onDataReady(); }; diff --git a/libnymea-app-core/discovery/bluetoothservicediscovery.cpp b/libnymea-app-core/discovery/bluetoothservicediscovery.cpp index a8134651..4b481774 100644 --- a/libnymea-app-core/discovery/bluetoothservicediscovery.cpp +++ b/libnymea-app-core/discovery/bluetoothservicediscovery.cpp @@ -71,25 +71,24 @@ void BluetoothServiceDiscovery::onHostModeChanged(const QBluetoothLocalDevice::H if (mode != QBluetoothLocalDevice::HostPoweredOff && m_enabed) { qDebug() << "Bluetooth available again, continue discovery"; - m_serviceDiscovery->start(QBluetoothServiceDiscoveryAgent::FullDiscovery); + discover(); + } + + if (mode == QBluetoothLocalDevice::HostPoweredOff) { + qDebug() << "BluetoothServiceDiscovery: Bluetooth adapter disabled. Stop discovering"; + m_serviceDiscovery->stop(); } } void BluetoothServiceDiscovery::onServiceDiscovered(const QBluetoothServiceInfo &serviceInfo) { - qDebug() << "BluetoothServiceDiscovery: Service [+]" << serviceInfo.device().name() << serviceInfo.serviceName() << serviceInfo.serviceProvider(); - - qDebug() << "Discovered service on" - << serviceInfo.device().name() << serviceInfo.device().address().toString(); + qDebug() << "BluetoothServiceDiscovery: Discovered service on" << serviceInfo.device().name() << serviceInfo.device().address().toString(); + qDebug() << "\tDevive name:" << serviceInfo.device().name(); qDebug() << "\tService name:" << serviceInfo.serviceName(); - qDebug() << "\tDescription:" - << serviceInfo.attribute(QBluetoothServiceInfo::ServiceDescription).toString(); - qDebug() << "\tProvider:" - << serviceInfo.attribute(QBluetoothServiceInfo::ServiceProvider).toString(); - qDebug() << "\Documentation:" - << serviceInfo.attribute(QBluetoothServiceInfo::DocumentationUrl).toString(); - qDebug() << "\tL2CAP protocol service multiplexer:" - << serviceInfo.protocolServiceMultiplexer(); + qDebug() << "\tDescription:" << serviceInfo.attribute(QBluetoothServiceInfo::ServiceDescription).toString(); + qDebug() << "\tProvider:" << serviceInfo.attribute(QBluetoothServiceInfo::ServiceProvider).toString(); + qDebug() << "\tDocumentation:" << serviceInfo.attribute(QBluetoothServiceInfo::DocumentationUrl).toString(); + qDebug() << "\tL2CAP protocol service multiplexer:" << serviceInfo.protocolServiceMultiplexer(); qDebug() << "\tRFCOMM server channel:" << serviceInfo.serverChannel(); if (serviceInfo.serviceClassUuids().isEmpty()) diff --git a/libnymea-app-core/discovery/discoverydevice.cpp b/libnymea-app-core/discovery/discoverydevice.cpp index e0c4e00a..28588089 100644 --- a/libnymea-app-core/discovery/discoverydevice.cpp +++ b/libnymea-app-core/discovery/discoverydevice.cpp @@ -128,11 +128,6 @@ QString DiscoveryDevice::toUrl(int portConfigIndex) return ret; } -QString DiscoveryDevice::toUrl(const QString &hostAddress) -{ - return QString("rfcom://%1").arg(hostAddress); -} - PortConfigs::PortConfigs(QObject *parent): QAbstractListModel(parent) { diff --git a/libnymea-app-core/discovery/discoverydevice.h b/libnymea-app-core/discovery/discoverydevice.h index 66a27d41..47ccc7a5 100644 --- a/libnymea-app-core/discovery/discoverydevice.h +++ b/libnymea-app-core/discovery/discoverydevice.h @@ -134,7 +134,6 @@ public: PortConfigs *portConfigs() const; Q_INVOKABLE QString toUrl(int portConfigIndex); - Q_INVOKABLE QString toUrl(const QString &hostAddress); signals: void nameChanged(); diff --git a/libnymea-app-core/discovery/discoverymodel.cpp b/libnymea-app-core/discovery/discoverymodel.cpp index d295d826..303df72f 100644 --- a/libnymea-app-core/discovery/discoverymodel.cpp +++ b/libnymea-app-core/discovery/discoverymodel.cpp @@ -38,7 +38,7 @@ QVariant DiscoveryModel::data(const QModelIndex &index, int role) const DiscoveryDevice *device = m_devices.at(index.row()); switch (role) { - case TypeRole: + case DeviceTypeRole: return device->deviceType(); case UuidRole: return device->uuid(); @@ -112,7 +112,7 @@ void DiscoveryModel::clearModel() QHash DiscoveryModel::roleNames() const { QHash roles; - roles[TypeRole] = "type"; + roles[DeviceTypeRole] = "deviceType"; roles[UuidRole] = "uuid"; roles[NameRole] = "name"; roles[HostAddressRole] = "hostAddress"; diff --git a/libnymea-app-core/discovery/discoverymodel.h b/libnymea-app-core/discovery/discoverymodel.h index e2c4c13a..5cd1c8bd 100644 --- a/libnymea-app-core/discovery/discoverymodel.h +++ b/libnymea-app-core/discovery/discoverymodel.h @@ -32,7 +32,7 @@ class DiscoveryModel : public QAbstractListModel Q_PROPERTY(int count READ rowCount NOTIFY countChanged) public: enum DeviceRole { - TypeRole, + DeviceTypeRole, UuidRole, NameRole, HostAddressRole, diff --git a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp index edf18a71..ef827b37 100644 --- a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp @@ -267,6 +267,7 @@ void JsonRpcClient::onInterfaceConnectedChanged(bool connected) void JsonRpcClient::dataReceived(const QByteArray &data) { + qDebug() << "JsonRpcClient: received data:" << qUtf8Printable(data); m_receiveBuffer.append(data); int splitIndex = m_receiveBuffer.indexOf("}\n{") + 1; diff --git a/libnymea-app-core/nymeaconnection.cpp b/libnymea-app-core/nymeaconnection.cpp index b07fed90..e48d47e5 100644 --- a/libnymea-app-core/nymeaconnection.cpp +++ b/libnymea-app-core/nymeaconnection.cpp @@ -37,6 +37,7 @@ void NymeaConnection::connect(const QString &url) qWarning() << "Cannot connect to urls of scheme" << m_currentUrl.scheme() << "Supported schemes are" << m_interfaces.keys(); return; } + qDebug() << "Should connect to url" << m_currentUrl; m_currentInterface->connect(m_currentUrl); } @@ -80,13 +81,19 @@ QString NymeaConnection::hostAddress() const return m_currentUrl.host(); } +QString NymeaConnection::bluetoothAddress() const +{ + QUrlQuery query(m_currentUrl); + return query.queryItemValue("mac"); +} + void NymeaConnection::sendData(const QByteArray &data) { if (connected()) { // qDebug() << "sending data:" << data; m_currentInterface->sendData(data); } else { - qWarning() << "Not connected. Cannot send."; + qWarning() << "Connection: Not connected. Cannot send."; } } @@ -150,7 +157,7 @@ void NymeaConnection::onConnected() qWarning() << "An inactive interface is emitting signals... ignoring."; return; } - qDebug() << "connected"; + qDebug() << "NymeaConnection: connected."; emit connectedChanged(true); } @@ -161,7 +168,7 @@ void NymeaConnection::onDisconnected() return; } m_currentInterface = nullptr; - qDebug() << "disconnected"; + qDebug() << "NymeaConnection: disconnected."; emit connectedChanged(false); } diff --git a/libnymea-app-core/nymeaconnection.h b/libnymea-app-core/nymeaconnection.h index f913cf55..361a0d3f 100644 --- a/libnymea-app-core/nymeaconnection.h +++ b/libnymea-app-core/nymeaconnection.h @@ -15,6 +15,7 @@ class NymeaConnection : public QObject Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged) Q_PROPERTY(QString url READ url NOTIFY connectedChanged) Q_PROPERTY(QString hostAddress READ hostAddress NOTIFY connectedChanged) + Q_PROPERTY(QString bluetoothAddress READ bluetoothAddress NOTIFY connectedChanged) public: explicit NymeaConnection(QObject *parent = nullptr); @@ -28,6 +29,7 @@ public: QString url() const; QString hostAddress() const; + QString bluetoothAddress() const; void sendData(const QByteArray &data); diff --git a/nymea-app/ui/ConnectPage.qml b/nymea-app/ui/ConnectPage.qml index 310bf242..b39b9a51 100644 --- a/nymea-app/ui/ConnectPage.qml +++ b/nymea-app/ui/ConnectPage.qml @@ -150,6 +150,11 @@ Page { objectName: "discoveryDelegate" + index property var discoveryDevice: discovery.discoveryModel.get(index) property string defaultPortConfigIndex: { + + if (model.deviceType !== DiscoveryDevice.DeviceTypeNetwork) { + return -1 + } + var usedConfigIndex = 0; for (var i = 1; i < discoveryDevice.portConfigs.count; i++) { var oldConfig = discoveryDevice.portConfigs.get(usedConfigIndex); @@ -172,18 +177,18 @@ Page { return usedConfigIndex } - iconName: model.type === DiscoveryDevice.DeviceTypeNetwork ? "../images/network-wifi-symbolic.svg" : "../images/bluetooth.svg" + iconName: model.deviceType === DiscoveryDevice.DeviceTypeNetwork ? "../images/network-wifi-symbolic.svg" : "../images/bluetooth.svg" text: model.name - subText: model.type === DiscoveryDevice.DeviceTypeNetwork ? model.hostAddress : model.bluetoothAddress + subText: model.deviceType === DiscoveryDevice.DeviceTypeNetwork ? discoveryDevice.hostAddress : discoveryDevice.bluetoothAddress property bool hasSecurePort: { - if (model.type === DiscoveryDevice.DeviceTypeNetwork) { + if (discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork) { return discoveryDeviceDelegate.discoveryDevice.portConfigs.get(discoveryDeviceDelegate.defaultPortConfigIndex).sslEnabled } else { return false } } property bool isTrusted: { - if (model.type === DiscoveryDevice.DeviceTypeNetwork) { + if (discoveryDeviceDelegate.discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork) { Engine.connection.isTrusted(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex)) } else { return false @@ -192,13 +197,19 @@ Page { progressive: hasSecurePort secondaryIconName: "../images/network-secure.svg" secondaryIconColor: isTrusted ? app.guhAccent : Material.foreground - swipe.enabled: model.type === DiscoveryDevice.DeviceTypeNetwork + swipe.enabled: discoveryDeviceDelegate.discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork onClicked: { - if (model.type === DiscoveryDevice.DeviceTypeNetwork) { - Engine.connection.connect(discoveryDevice.toUrl(defaultPortConfigIndex)) - } else if (model.type === DiscoveryDevice.DeviceTypeBluetooth) { - Engine.connection.connect("rfcom://bluetooth.local?mac=" + model.bluetoothAddress) + switch (discoveryDeviceDelegate.discoveryDevice.deviceType) { + case DiscoveryDevice.DeviceTypeNetwork: + Engine.connection.connect(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex)) + break; + case DiscoveryDevice.DeviceTypeBluetooth: + Engine.connection.connect("rfcom://bluetooth.local?mac=" + model.bluetoothAddress + "&name=" + model.name) + break; + default: + console.warn("Could not connect, unknown type") + break; } pageStack.push(connectingPage) @@ -214,7 +225,7 @@ Page { name: "../images/info.svg" } onClicked: { - if (model.type === DiscoveryDevice.DeviceTypeNetwork) { + if (model.deviceType === DiscoveryDevice.DeviceTypeNetwork) { swipe.close() var popup = infoDialog.createObject(app,{discoveryDevice: discovery.discoveryModel.get(index)}) popup.open()