From 383eb2f6826b8af7ea933e00a997317c752336f9 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 5 Aug 2018 16:03:26 +0200 Subject: [PATCH] a lot of cleanup --- .gitmodules | 3 + .../{ => connection}/awsclient.cpp | 8 +- .../{ => connection}/awsclient.h | 2 + .../bluetoothtransport.cpp} | 40 ++--- .../bluetoothtransport.h} | 12 +- .../connection/cloudtransport.cpp | 63 ++++++++ libnymea-app-core/connection/cloudtransport.h | 31 ++++ .../{ => connection}/nymeaconnection.cpp | 57 +++----- .../{ => connection}/nymeaconnection.h | 9 +- .../nymeatransportinterface.cpp} | 4 +- .../nymeatransportinterface.h} | 11 +- .../tcpsockettransport.cpp} | 44 +++--- .../tcpsockettransport.h} | 12 +- .../websockettransport.cpp} | 37 +++-- .../websockettransport.h} | 12 +- .../discovery/bluetoothservicediscovery.cpp | 10 +- .../discovery/discoverydevice.cpp | 138 ++++++------------ libnymea-app-core/discovery/discoverydevice.h | 79 +++++----- .../discovery/nymeadiscovery.cpp | 15 +- libnymea-app-core/discovery/nymeadiscovery.h | 2 +- libnymea-app-core/discovery/upnpdiscovery.cpp | 71 +++------ .../discovery/zeroconfdiscovery.cpp | 27 ++-- libnymea-app-core/engine.cpp | 13 +- libnymea-app-core/engine.h | 2 +- libnymea-app-core/jsonrpc/jsonrpcclient.cpp | 2 +- libnymea-app-core/jsonrpc/jsonrpcclient.h | 2 +- libnymea-app-core/libnymea-app-core.h | 5 +- libnymea-app-core/libnymea-app-core.pro | 34 +++-- .../wifisetup/wirelessaccesspointsproxy.cpp | 1 + nymea-app/main.cpp | 2 +- nymea-app/nymea-app.pro | 6 +- nymea-app/stylecontroller.cpp | 2 +- nymea-app/ui/Nymea.qml | 6 +- .../ui/components/MeaListItemDelegate.qml | 15 +- nymea-app/ui/connection/ConnectPage.qml | 131 +++++++++-------- qmqtt | 1 + 36 files changed, 485 insertions(+), 424 deletions(-) rename libnymea-app-core/{ => connection}/awsclient.cpp (97%) rename libnymea-app-core/{ => connection}/awsclient.h (95%) rename libnymea-app-core/{bluetoothinterface.cpp => connection/bluetoothtransport.cpp} (77%) rename libnymea-app-core/{bluetoothinterface.h => connection/bluetoothtransport.h} (90%) create mode 100644 libnymea-app-core/connection/cloudtransport.cpp create mode 100644 libnymea-app-core/connection/cloudtransport.h rename libnymea-app-core/{ => connection}/nymeaconnection.cpp (72%) rename libnymea-app-core/{ => connection}/nymeaconnection.h (87%) rename libnymea-app-core/{nymeainterface.cpp => connection/nymeatransportinterface.cpp} (94%) rename libnymea-app-core/{nymeainterface.h => connection/nymeatransportinterface.h} (90%) rename libnymea-app-core/{tcpsocketinterface.cpp => connection/tcpsockettransport.cpp} (64%) rename libnymea-app-core/{tcpsocketinterface.h => connection/tcpsockettransport.h} (71%) rename libnymea-app-core/{websocketinterface.cpp => connection/websockettransport.cpp} (72%) rename libnymea-app-core/{websocketinterface.h => connection/websockettransport.h} (88%) create mode 160000 qmqtt diff --git a/.gitmodules b/.gitmodules index f7249b95..e2919b8b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "aws-sdk-qt"] path = aws-sdk-qt url = https://github.com/pcolby/aws-sdk-qt.git +[submodule "qmqtt"] + path = qmqtt + url = https://github.com/emqtt/qmqtt.git diff --git a/libnymea-app-core/awsclient.cpp b/libnymea-app-core/connection/awsclient.cpp similarity index 97% rename from libnymea-app-core/awsclient.cpp rename to libnymea-app-core/connection/awsclient.cpp index 2e6e5a39..84f81a1f 100644 --- a/libnymea-app-core/awsclient.cpp +++ b/libnymea-app-core/connection/awsclient.cpp @@ -93,7 +93,7 @@ void AWSClient::initiateAuthReply() qDebug() << "AWS login successful"; emit isLoggedInChanged(); - return; // Why should we call GetId? Ask Luca +// return; // Why should we call GetId? Ask Luca QUrl url("https://cognito-identity.eu-west-1.amazonaws.com/"); @@ -131,6 +131,7 @@ void AWSClient::getIdReply() void AWSClient::fetchDevices() { + qDebug() << "Fetching cloud devices"; QUrl url("https://z6368zhf2m.execute-api.eu-west-1.amazonaws.com/dev/devices"); QNetworkRequest request(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); @@ -162,3 +163,8 @@ void AWSClient::fetchDevices() }); } + +QByteArray AWSClient::accessToken() const +{ + return m_accessToken; +} diff --git a/libnymea-app-core/awsclient.h b/libnymea-app-core/connection/awsclient.h similarity index 95% rename from libnymea-app-core/awsclient.h rename to libnymea-app-core/connection/awsclient.h index 7a5f634a..eb98194c 100644 --- a/libnymea-app-core/awsclient.h +++ b/libnymea-app-core/connection/awsclient.h @@ -28,6 +28,8 @@ public: Q_INVOKABLE void fetchDevices(); + QByteArray accessToken() const; + signals: void isLoggedInChanged(); diff --git a/libnymea-app-core/bluetoothinterface.cpp b/libnymea-app-core/connection/bluetoothtransport.cpp similarity index 77% rename from libnymea-app-core/bluetoothinterface.cpp rename to libnymea-app-core/connection/bluetoothtransport.cpp index f55261ba..570b5b7a 100644 --- a/libnymea-app-core/bluetoothinterface.cpp +++ b/libnymea-app-core/connection/bluetoothtransport.cpp @@ -20,29 +20,29 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "bluetoothinterface.h" +#include "bluetoothtransport.h" #include #include #include -BluetoothInterface::BluetoothInterface(QObject *parent) : - NymeaInterface(parent) +BluetoothTransport::BluetoothTransport(QObject *parent) : + NymeaTransportInterface(parent) { m_socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol); - 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); + QObject::connect(m_socket, &QBluetoothSocket::connected, this, &BluetoothTransport::onConnected); + QObject::connect(m_socket, &QBluetoothSocket::disconnected, this, &BluetoothTransport::onDisconnected); + QObject::connect(m_socket, &QBluetoothSocket::readyRead, this, &BluetoothTransport::onDataReady); + QObject::connect(m_socket, &QBluetoothSocket::stateChanged, this, &BluetoothTransport::onDataReady); } -QStringList BluetoothInterface::supportedSchemes() const +QStringList BluetoothTransport::supportedSchemes() const { return {"rfcom"}; } -void BluetoothInterface::connect(const QUrl &url) +void BluetoothTransport::connect(const QUrl &url) { if (url.scheme() != "rfcom") { qWarning() << "BluetoothInterface: Cannot connect. Invalid scheme in url" << url.toString(); @@ -58,31 +58,31 @@ void BluetoothInterface::connect(const QUrl &url) m_socket->connectToService(macAddress, QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b"))); } -void BluetoothInterface::disconnect() +void BluetoothTransport::disconnect() { m_socket->close(); } -NymeaInterface::ConnectionState BluetoothInterface::connectionState() const +NymeaTransportInterface::ConnectionState BluetoothTransport::connectionState() const { switch (m_socket->state()) { case QBluetoothSocket::ConnectedState: - return NymeaInterface::ConnectionStateConnected; + return NymeaTransportInterface::ConnectionStateConnected; case QBluetoothSocket::ConnectingState: case QBluetoothSocket::ServiceLookupState: - return NymeaInterface::ConnectionStateConnecting; + return NymeaTransportInterface::ConnectionStateConnecting; default: - return NymeaInterface::ConnectionStateDisconnected; + return NymeaTransportInterface::ConnectionStateDisconnected; } } -void BluetoothInterface::sendData(const QByteArray &data) +void BluetoothTransport::sendData(const QByteArray &data) { qDebug() << "BluetoothInterface: send data:" << qUtf8Printable(data); m_socket->write(data); } -void BluetoothInterface::onServiceFound(const QBluetoothServiceInfo &service) +void BluetoothTransport::onServiceFound(const QBluetoothServiceInfo &service) { m_service = service; if (m_socket->isOpen()) @@ -92,24 +92,24 @@ void BluetoothInterface::onServiceFound(const QBluetoothServiceInfo &service) m_socket->connectToService(m_service); } -void BluetoothInterface::onConnected() +void BluetoothTransport::onConnected() { qDebug() << "BluetoothInterface: connected" << m_socket->peerName() << m_socket->peerAddress(); emit connected(); } -void BluetoothInterface::onDisconnected() +void BluetoothTransport::onDisconnected() { qDebug() << "BluetoothInterface: disconnected" << m_socket->peerName() << m_socket->peerAddress(); emit disconnected(); } -void BluetoothInterface::onStateChanged(const QBluetoothSocket::SocketState &state) +void BluetoothTransport::onStateChanged(const QBluetoothSocket::SocketState &state) { qDebug() << "BluetoothInterface" << state; } -void BluetoothInterface::onDataReady() +void BluetoothTransport::onDataReady() { QByteArray data = m_socket->readAll(); qDebug() << "BluetoothInterface: recived data:" << qUtf8Printable(data); diff --git a/libnymea-app-core/bluetoothinterface.h b/libnymea-app-core/connection/bluetoothtransport.h similarity index 90% rename from libnymea-app-core/bluetoothinterface.h rename to libnymea-app-core/connection/bluetoothtransport.h index e41fb333..be12acb2 100644 --- a/libnymea-app-core/bluetoothinterface.h +++ b/libnymea-app-core/connection/bluetoothtransport.h @@ -20,19 +20,19 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef BLUETOOTHINTERFACE_H -#define BLUETOOTHINTERFACE_H +#ifndef BLUETOOTHTRANSPORT_H +#define BLUETOOTHTRANSPORT_H #include #include -#include "nymeainterface.h" +#include "nymeatransportinterface.h" -class BluetoothInterface : public NymeaInterface +class BluetoothTransport: public NymeaTransportInterface { Q_OBJECT public: - explicit BluetoothInterface(QObject *parent = nullptr); + explicit BluetoothTransport(QObject *parent = nullptr); QStringList supportedSchemes() const override; @@ -53,4 +53,4 @@ private slots: void onDataReady(); }; -#endif // BLUETOOTHINTERFACE_H +#endif // BLUETOOTHTRANSPROT_H diff --git a/libnymea-app-core/connection/cloudtransport.cpp b/libnymea-app-core/connection/cloudtransport.cpp new file mode 100644 index 00000000..6301fed5 --- /dev/null +++ b/libnymea-app-core/connection/cloudtransport.cpp @@ -0,0 +1,63 @@ +#include "cloudtransport.h" + +#include "qmqtt.h" + +CloudTransport::CloudTransport(AWSClient *awsClient, QObject *parent): + NymeaTransportInterface(parent), + m_awsClient(awsClient) +{ + +} + +QStringList CloudTransport::supportedSchemes() const +{ + return {"cloud"}; +} + +void CloudTransport::connect(const QUrl &url) +{ + qDebug() << "should connect to" << url; + QString date = QDateTime::currentDateTime().toString("yyyyMMddThhmmssZ"); + QString region = "eu-west-1"; + QString service = "iotdevicegateway"; + QString credentialScope = date + '/' + region + '/' + service + '/' + "aws4_request"; + QString algorithm = "AWS4-HMAC-SHA256"; + QString canonicalQuerystring = "X-Amz-Algorithm=" + algorithm; + +// canonicalQuerystring += "&X-Amz-Credential=" + QByteArray(credentials.accessKeyId + '/' + credentialScope).toPercentageEncoded(); +// '&X-Amz-Security-Token=' + encodeURIComponent(credentials.sessionToken); + + QString requestUrl = "wss://a2addxakg5juii.iot.eu-west-1.amazonaws.com/mqtt?" + canonicalQuerystring; + m_mqttClient = new QMQTT::Client(requestUrl, 443, QWebSocketProtocol::VersionLatest, true, this); + + QObject::connect(m_mqttClient, &QMQTT::Client::connected, this, [](){ + qDebug() << "MQTT connected"; + }); + QObject::connect(m_mqttClient, &QMQTT::Client::disconnected, this, []() { + qDebug() << "MQTT disconnected"; + }); + QObject::connect(m_mqttClient, &QMQTT::Client::error, this, [](QMQTT::ClientError error) { + qDebug() << "MQTT error" << error << QMQTT::ClientError::SocketHostNotFoundError; + }); + + + m_mqttClient->setUsername("michael.zanetti@guh.io"); + m_mqttClient->setPassword("H22*gemmmmm"); + m_mqttClient->setClientId("8rjhfdlf9jf1suok2jcrltd6v"); + m_mqttClient->connectToHost(); +} + +void CloudTransport::disconnect() +{ + qDebug() << "should disconnect"; +} + +NymeaTransportInterface::ConnectionState CloudTransport::connectionState() const +{ + return ConnectionStateDisconnected; +} + +void CloudTransport::sendData(const QByteArray &data) +{ + qDebug() << "should send" << data; +} diff --git a/libnymea-app-core/connection/cloudtransport.h b/libnymea-app-core/connection/cloudtransport.h new file mode 100644 index 00000000..a549503e --- /dev/null +++ b/libnymea-app-core/connection/cloudtransport.h @@ -0,0 +1,31 @@ +#ifndef CLOUDTRANSPORT_H +#define CLOUDTRANSPORT_H + +#include "nymeatransportinterface.h" + +#include + +namespace QMQTT { +class Client; +} +class AWSClient; + +class CloudTransport : public NymeaTransportInterface +{ + Q_OBJECT +public: + explicit CloudTransport(AWSClient *awsClient, QObject *parent = nullptr); + + QStringList supportedSchemes() const override; + + void connect(const QUrl &url) override; + void disconnect() override; + ConnectionState connectionState() const override; + void sendData(const QByteArray &data) override; + +private: + QMQTT::Client *m_mqttClient = nullptr; + AWSClient *m_awsClient = nullptr; +}; + +#endif // CLOUDTRANSPORT_H diff --git a/libnymea-app-core/nymeaconnection.cpp b/libnymea-app-core/connection/nymeaconnection.cpp similarity index 72% rename from libnymea-app-core/nymeaconnection.cpp rename to libnymea-app-core/connection/nymeaconnection.cpp index e48d47e5..77322f64 100644 --- a/libnymea-app-core/nymeaconnection.cpp +++ b/libnymea-app-core/connection/nymeaconnection.cpp @@ -7,21 +7,10 @@ #include #include -#include "nymeainterface.h" -#include "tcpsocketinterface.h" -#include "websocketinterface.h" -#include "bluetoothinterface.h" +#include "nymeatransportinterface.h" NymeaConnection::NymeaConnection(QObject *parent) : QObject(parent) { - NymeaInterface *iface = new TcpSocketInterface(this); - registerInterface(iface); - - iface = new WebsocketInterface(this); - registerInterface(iface); - - iface = new BluetoothInterface(this); - registerInterface(iface); } void NymeaConnection::connect(const QString &url) @@ -32,23 +21,23 @@ void NymeaConnection::connect(const QString &url) } m_currentUrl = QUrl(url); - m_currentInterface = m_interfaces.value(m_currentUrl.scheme()); - if (!m_currentInterface) { - qWarning() << "Cannot connect to urls of scheme" << m_currentUrl.scheme() << "Supported schemes are" << m_interfaces.keys(); + m_currentTransport = m_transports.value(m_currentUrl.scheme()); + if (!m_currentTransport) { + qWarning() << "Cannot connect to urls of scheme" << m_currentUrl.scheme() << "Supported schemes are" << m_transports.keys(); return; } qDebug() << "Should connect to url" << m_currentUrl; - m_currentInterface->connect(m_currentUrl); + m_currentTransport->connect(m_currentUrl); } void NymeaConnection::disconnect() { - if (!m_currentInterface || m_currentInterface->connectionState() == NymeaInterface::ConnectionStateDisconnected) { + if (!m_currentTransport || m_currentTransport->connectionState() == NymeaTransportInterface::ConnectionStateDisconnected) { qWarning() << "not connected, cannot disconnect"; return; } - m_currentInterface->disconnect(); + m_currentTransport->disconnect(); } void NymeaConnection::acceptCertificate(const QString &url, const QByteArray &fingerprint) @@ -68,7 +57,7 @@ bool NymeaConnection::isTrusted(const QString &url) bool NymeaConnection::connected() { - return m_currentInterface && m_currentInterface->connectionState() == NymeaInterface::ConnectionStateConnected; + return m_currentTransport && m_currentTransport->connectionState() == NymeaTransportInterface::ConnectionStateConnected; } QString NymeaConnection::url() const @@ -91,7 +80,7 @@ void NymeaConnection::sendData(const QByteArray &data) { if (connected()) { // qDebug() << "sending data:" << data; - m_currentInterface->sendData(data); + m_currentTransport->sendData(data); } else { qWarning() << "Connection: Not connected. Cannot send."; } @@ -142,7 +131,7 @@ void NymeaConnection::onSslErrors(const QList &errors) qDebug() << "SSL Error:" << error.errorString() << error.certificate(); } } - m_currentInterface->ignoreSslErrors(ignoredErrors); + m_currentTransport->ignoreSslErrors(ignoredErrors); } void NymeaConnection::onError(QAbstractSocket::SocketError error) @@ -153,8 +142,8 @@ void NymeaConnection::onError(QAbstractSocket::SocketError error) void NymeaConnection::onConnected() { - if (m_currentInterface != sender()) { - qWarning() << "An inactive interface is emitting signals... ignoring."; + if (m_currentTransport != sender()) { + qWarning() << "NymeaConnection: An inactive transport is emitting signals... ignoring."; return; } qDebug() << "NymeaConnection: connected."; @@ -163,26 +152,26 @@ void NymeaConnection::onConnected() void NymeaConnection::onDisconnected() { - if (m_currentInterface != sender()) { - qWarning() << "An inactive interface is emitting signals... ignoring."; + if (m_currentTransport != sender()) { + qWarning() << "NymeaConnection: An inactive transport is emitting signals... ignoring."; return; } - m_currentInterface = nullptr; + m_currentTransport = nullptr; qDebug() << "NymeaConnection: disconnected."; emit connectedChanged(false); } -void NymeaConnection::registerInterface(NymeaInterface *iface) +void NymeaConnection::registerTransport(NymeaTransportInterface *transport) { - QObject::connect(iface, &NymeaInterface::sslErrors, this, &NymeaConnection::onSslErrors); - QObject::connect(iface, &NymeaInterface::error, this, &NymeaConnection::onError); - QObject::connect(iface, &NymeaInterface::connected, this, &NymeaConnection::onConnected); - QObject::connect(iface, &NymeaInterface::disconnected, this, &NymeaConnection::onDisconnected); + QObject::connect(transport, &NymeaTransportInterface::sslErrors, this, &NymeaConnection::onSslErrors); + QObject::connect(transport, &NymeaTransportInterface::error, this, &NymeaConnection::onError); + QObject::connect(transport, &NymeaTransportInterface::connected, this, &NymeaConnection::onConnected); + QObject::connect(transport, &NymeaTransportInterface::disconnected, this, &NymeaConnection::onDisconnected); // signal forwarding - QObject::connect(iface, &NymeaInterface::dataReady, this, &NymeaConnection::dataAvailable); + QObject::connect(transport, &NymeaTransportInterface::dataReady, this, &NymeaConnection::dataAvailable); - foreach (const QString &scheme, iface->supportedSchemes()) { - m_interfaces[scheme] = iface; + foreach (const QString &scheme, transport->supportedSchemes()) { + m_transports[scheme] = transport; } } diff --git a/libnymea-app-core/nymeaconnection.h b/libnymea-app-core/connection/nymeaconnection.h similarity index 87% rename from libnymea-app-core/nymeaconnection.h rename to libnymea-app-core/connection/nymeaconnection.h index 361a0d3f..4a18d6f5 100644 --- a/libnymea-app-core/nymeaconnection.h +++ b/libnymea-app-core/connection/nymeaconnection.h @@ -7,7 +7,7 @@ #include #include -class NymeaInterface; +class NymeaTransportInterface; class NymeaConnection : public QObject { @@ -20,6 +20,8 @@ class NymeaConnection : public QObject public: explicit NymeaConnection(QObject *parent = nullptr); + void registerTransport(NymeaTransportInterface *transport); + Q_INVOKABLE void connect(const QString &url); Q_INVOKABLE void disconnect(); Q_INVOKABLE void acceptCertificate(const QString &url, const QByteArray &fingerprint); @@ -46,11 +48,10 @@ private slots: void onDisconnected(); private: - void registerInterface(NymeaInterface *iface); private: - QHash m_interfaces; - NymeaInterface *m_currentInterface = nullptr; + QHash m_transports; + NymeaTransportInterface *m_currentTransport = nullptr; QUrl m_currentUrl; }; diff --git a/libnymea-app-core/nymeainterface.cpp b/libnymea-app-core/connection/nymeatransportinterface.cpp similarity index 94% rename from libnymea-app-core/nymeainterface.cpp rename to libnymea-app-core/connection/nymeatransportinterface.cpp index f9a809d1..522654e2 100644 --- a/libnymea-app-core/nymeainterface.cpp +++ b/libnymea-app-core/connection/nymeatransportinterface.cpp @@ -20,10 +20,10 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "nymeainterface.h" +#include "nymeatransportinterface.h" #include -NymeaInterface::NymeaInterface(QObject *parent) : +NymeaTransportInterface::NymeaTransportInterface(QObject *parent) : QObject(parent) { diff --git a/libnymea-app-core/nymeainterface.h b/libnymea-app-core/connection/nymeatransportinterface.h similarity index 90% rename from libnymea-app-core/nymeainterface.h rename to libnymea-app-core/connection/nymeatransportinterface.h index 7a9ade19..e532a975 100644 --- a/libnymea-app-core/nymeainterface.h +++ b/libnymea-app-core/connection/nymeatransportinterface.h @@ -20,14 +20,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef NYMEAINTERFACE_H -#define NYMEAINTERFACE_H +#ifndef NYMEATRANSPORTINTERFACE_H +#define NYMEATRANSPORTINTERFACE_H #include #include #include -class NymeaInterface : public QObject +class NymeaTransportInterface : public QObject { Q_OBJECT public: @@ -38,7 +38,8 @@ public: }; Q_ENUM(ConnectionState) - explicit NymeaInterface(QObject *parent = 0); + explicit NymeaTransportInterface(QObject *parent = nullptr); + virtual ~NymeaTransportInterface() = default; virtual QStringList supportedSchemes() const = 0; @@ -56,4 +57,4 @@ signals: void dataReady(const QByteArray &data); }; -#endif // NYMEAINTERFACE_H +#endif // NYMEATRANSPORTINTERFACE_H diff --git a/libnymea-app-core/tcpsocketinterface.cpp b/libnymea-app-core/connection/tcpsockettransport.cpp similarity index 64% rename from libnymea-app-core/tcpsocketinterface.cpp rename to libnymea-app-core/connection/tcpsockettransport.cpp index c2727490..25aaab8f 100644 --- a/libnymea-app-core/tcpsocketinterface.cpp +++ b/libnymea-app-core/connection/tcpsockettransport.cpp @@ -1,27 +1,27 @@ -#include "tcpsocketinterface.h" +#include "tcpsockettransport.h" #include -TcpSocketInterface::TcpSocketInterface(QObject *parent) : NymeaInterface(parent) +TcpSocketTransport::TcpSocketTransport(QObject *parent) : NymeaTransportInterface(parent) { - QObject::connect(&m_socket, &QSslSocket::connected, this, &TcpSocketInterface::onConnected); - QObject::connect(&m_socket, &QSslSocket::disconnected, this, &TcpSocketInterface::disconnected); - QObject::connect(&m_socket, &QSslSocket::encrypted, this, &TcpSocketInterface::onEncrypted); + QObject::connect(&m_socket, &QSslSocket::connected, this, &TcpSocketTransport::onConnected); + QObject::connect(&m_socket, &QSslSocket::disconnected, this, &TcpSocketTransport::disconnected); + QObject::connect(&m_socket, &QSslSocket::encrypted, this, &TcpSocketTransport::onEncrypted); typedef void (QSslSocket:: *sslErrorsSignal)(const QList &); - QObject::connect(&m_socket, static_cast(&QSslSocket::sslErrors), this, &TcpSocketInterface::sslErrors); - QObject::connect(&m_socket, &QSslSocket::readyRead, this, &TcpSocketInterface::socketReadyRead); + QObject::connect(&m_socket, static_cast(&QSslSocket::sslErrors), this, &TcpSocketTransport::sslErrors); + QObject::connect(&m_socket, &QSslSocket::readyRead, this, &TcpSocketTransport::socketReadyRead); typedef void (QSslSocket:: *errorSignal)(QAbstractSocket::SocketError); - QObject::connect(&m_socket, static_cast(&QSslSocket::error), this, &TcpSocketInterface::error); - QObject::connect(&m_socket, &QSslSocket::stateChanged, this, &TcpSocketInterface::onSocketStateChanged); + QObject::connect(&m_socket, static_cast(&QSslSocket::error), this, &TcpSocketTransport::error); + QObject::connect(&m_socket, &QSslSocket::stateChanged, this, &TcpSocketTransport::onSocketStateChanged); } -QStringList TcpSocketInterface::supportedSchemes() const +QStringList TcpSocketTransport::supportedSchemes() const { return {"nymea", "nymeas"}; } -void TcpSocketInterface::sendData(const QByteArray &data) +void TcpSocketTransport::sendData(const QByteArray &data) { qint64 ret = m_socket.write(data); if (ret != data.length()) { @@ -29,12 +29,12 @@ void TcpSocketInterface::sendData(const QByteArray &data) } } -void TcpSocketInterface::ignoreSslErrors(const QList &errors) +void TcpSocketTransport::ignoreSslErrors(const QList &errors) { m_socket.ignoreSslErrors(errors); } -void TcpSocketInterface::onConnected() +void TcpSocketTransport::onConnected() { if (m_url.scheme() == "nymea") { qDebug() << "TCP socket connected"; @@ -42,13 +42,13 @@ void TcpSocketInterface::onConnected() } } -void TcpSocketInterface::onEncrypted() +void TcpSocketTransport::onEncrypted() { qDebug() << "TCP socket encrypted"; emit connected(); } -void TcpSocketInterface::connect(const QUrl &url) +void TcpSocketTransport::connect(const QUrl &url) { m_url = url; if (url.scheme() == "nymeas") { @@ -61,20 +61,20 @@ void TcpSocketInterface::connect(const QUrl &url) } } -NymeaInterface::ConnectionState TcpSocketInterface::connectionState() const +NymeaTransportInterface::ConnectionState TcpSocketTransport::connectionState() const { switch (m_socket.state()) { case QAbstractSocket::ConnectedState: - return NymeaInterface::ConnectionStateConnected; + return NymeaTransportInterface::ConnectionStateConnected; case QAbstractSocket::ConnectingState: case QAbstractSocket::HostLookupState: - return NymeaInterface::ConnectionStateConnecting; + return NymeaTransportInterface::ConnectionStateConnecting; default: - return NymeaInterface::ConnectionStateDisconnected; + return NymeaTransportInterface::ConnectionStateDisconnected; } } -void TcpSocketInterface::disconnect() +void TcpSocketTransport::disconnect() { qDebug() << "closing socket"; m_socket.disconnectFromHost(); @@ -85,13 +85,13 @@ void TcpSocketInterface::disconnect() m_socket.abort(); } -void TcpSocketInterface::socketReadyRead() +void TcpSocketTransport::socketReadyRead() { QByteArray data = m_socket.readAll(); emit dataReady(data); } -void TcpSocketInterface::onSocketStateChanged(const QAbstractSocket::SocketState &state) +void TcpSocketTransport::onSocketStateChanged(const QAbstractSocket::SocketState &state) { qDebug() << "Socket state changed -->" << state; } diff --git a/libnymea-app-core/tcpsocketinterface.h b/libnymea-app-core/connection/tcpsockettransport.h similarity index 71% rename from libnymea-app-core/tcpsocketinterface.h rename to libnymea-app-core/connection/tcpsockettransport.h index 4e894cc0..fabee3c0 100644 --- a/libnymea-app-core/tcpsocketinterface.h +++ b/libnymea-app-core/connection/tcpsockettransport.h @@ -1,17 +1,17 @@ -#ifndef TCPSOCKETINTERFACE_H -#define TCPSOCKETINTERFACE_H +#ifndef TCPSOCKETTRANSPORT_H +#define TCPSOCKETTRANSPORT_H -#include "nymeainterface.h" +#include "nymeatransportinterface.h" #include #include #include -class TcpSocketInterface : public NymeaInterface +class TcpSocketTransport: public NymeaTransportInterface { Q_OBJECT public: - explicit TcpSocketInterface(QObject *parent = nullptr); + explicit TcpSocketTransport(QObject *parent = nullptr); QStringList supportedSchemes() const override; @@ -32,4 +32,4 @@ private: QUrl m_url; }; -#endif // TCPSOCKETINTERFACE_H +#endif // TCPSOCKETTRANSPROT_H diff --git a/libnymea-app-core/websocketinterface.cpp b/libnymea-app-core/connection/websockettransport.cpp similarity index 72% rename from libnymea-app-core/websocketinterface.cpp rename to libnymea-app-core/connection/websockettransport.cpp index 3636932e..73499ba4 100644 --- a/libnymea-app-core/websocketinterface.cpp +++ b/libnymea-app-core/connection/websockettransport.cpp @@ -18,70 +18,69 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "websocketinterface.h" -#include "engine.h" +#include "websockettransport.h" #include #include #include #include -WebsocketInterface::WebsocketInterface(QObject *parent) : - NymeaInterface(parent) +WebsocketTransport::WebsocketTransport(QObject *parent) : + NymeaTransportInterface(parent) { m_socket = new QWebSocket(QCoreApplication::applicationName(), QWebSocketProtocol::Version13, this); - QObject::connect(m_socket, &QWebSocket::connected, this, &WebsocketInterface::connected); - QObject::connect(m_socket, &QWebSocket::disconnected, this, &WebsocketInterface::disconnected); + QObject::connect(m_socket, &QWebSocket::connected, this, &WebsocketTransport::connected); + QObject::connect(m_socket, &QWebSocket::disconnected, this, &WebsocketTransport::disconnected); typedef void (QWebSocket:: *errorSignal)(QAbstractSocket::SocketError); - QObject::connect(m_socket, static_cast(&QWebSocket::error), this, &WebsocketInterface::error); - QObject::connect(m_socket, &QWebSocket::textMessageReceived, this, &WebsocketInterface::onTextMessageReceived); + QObject::connect(m_socket, static_cast(&QWebSocket::error), this, &WebsocketTransport::error); + QObject::connect(m_socket, &QWebSocket::textMessageReceived, this, &WebsocketTransport::onTextMessageReceived); typedef void (QWebSocket:: *sslErrorsSignal)(const QList &); - QObject::connect(m_socket, static_cast(&QWebSocket::sslErrors),this, &WebsocketInterface::sslErrors); + QObject::connect(m_socket, static_cast(&QWebSocket::sslErrors),this, &WebsocketTransport::sslErrors); } -QStringList WebsocketInterface::supportedSchemes() const +QStringList WebsocketTransport::supportedSchemes() const { return {"ws", "wss"}; } -void WebsocketInterface::connect(const QUrl &url) +void WebsocketTransport::connect(const QUrl &url) { m_socket->open(QUrl(url)); } -NymeaInterface::ConnectionState WebsocketInterface::connectionState() const +NymeaTransportInterface::ConnectionState WebsocketTransport::connectionState() const { switch (m_socket->state()) { case QAbstractSocket::ConnectedState: - return NymeaInterface::ConnectionStateConnected; + return NymeaTransportInterface::ConnectionStateConnected; case QAbstractSocket::ConnectingState: case QAbstractSocket::HostLookupState: - return NymeaInterface::ConnectionStateConnecting; + return NymeaTransportInterface::ConnectionStateConnecting; default: - return NymeaInterface::ConnectionStateDisconnected; + return NymeaTransportInterface::ConnectionStateDisconnected; } } -void WebsocketInterface::disconnect() +void WebsocketTransport::disconnect() { m_socket->close(); m_socket->abort(); } -void WebsocketInterface::sendData(const QByteArray &data) +void WebsocketTransport::sendData(const QByteArray &data) { m_socket->sendTextMessage(QString::fromUtf8(data)); } -void WebsocketInterface::ignoreSslErrors(const QList &errors) +void WebsocketTransport::ignoreSslErrors(const QList &errors) { m_socket->ignoreSslErrors(errors); } -void WebsocketInterface::onTextMessageReceived(const QString &data) +void WebsocketTransport::onTextMessageReceived(const QString &data) { emit dataReady(data.toUtf8()); } diff --git a/libnymea-app-core/websocketinterface.h b/libnymea-app-core/connection/websockettransport.h similarity index 88% rename from libnymea-app-core/websocketinterface.h rename to libnymea-app-core/connection/websockettransport.h index e5b6f386..461b406d 100644 --- a/libnymea-app-core/websocketinterface.h +++ b/libnymea-app-core/connection/websockettransport.h @@ -18,19 +18,19 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef WEBSOCKETINTERFACE_H -#define WEBSOCKETINTERFACE_H +#ifndef WEBSOCKETTRANSPORT_H +#define WEBSOCKETTRANSPORT_H #include #include -#include "nymeainterface.h" +#include "nymeatransportinterface.h" -class WebsocketInterface : public NymeaInterface +class WebsocketTransport: public NymeaTransportInterface { Q_OBJECT public: - explicit WebsocketInterface(QObject *parent = 0); + explicit WebsocketTransport(QObject *parent = nullptr); QStringList supportedSchemes() const override; @@ -47,4 +47,4 @@ private slots: void onTextMessageReceived(const QString &data); }; -#endif // WEBSOCKETINTERFACE_H +#endif // WEBSOCKETTRANSPORT_H diff --git a/libnymea-app-core/discovery/bluetoothservicediscovery.cpp b/libnymea-app-core/discovery/bluetoothservicediscovery.cpp index 4fd928ff..4eccf798 100644 --- a/libnymea-app-core/discovery/bluetoothservicediscovery.cpp +++ b/libnymea-app-core/discovery/bluetoothservicediscovery.cpp @@ -36,7 +36,7 @@ void BluetoothServiceDiscovery::discover() { m_enabed = true; if (!m_localDevice->isValid() || m_localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) { - qWarning() << "BluetoothServiceDiscovery: Not restart discovery, the bluetooth device is not available"; + qWarning() << "BluetoothServiceDiscovery: Bluetooth device not available. Not starting discovery."; return; } @@ -45,7 +45,7 @@ void BluetoothServiceDiscovery::discover() if (m_discovering) return; - qDebug() << "BluetoothServiceDiscovery: Start scanning for service" << m_nymeaServiceUuid.toString(); + qDebug() << "BluetoothServiceDiscovery: Service scan started for service: " << m_nymeaServiceUuid.toString(); setDiscovering(true); m_serviceDiscovery->setUuidFilter(m_nymeaServiceUuid); @@ -73,15 +73,13 @@ void BluetoothServiceDiscovery::setDiscovering(const bool &discovering) void BluetoothServiceDiscovery::onHostModeChanged(const QBluetoothLocalDevice::HostMode &mode) { - qDebug() << "BluetoothServiceDiscovery: Host mode changed" << mode; - if (mode != QBluetoothLocalDevice::HostPoweredOff && m_enabed) { - qDebug() << "Bluetooth available again, continue discovery"; + qDebug() << "BluetoothServiceDiscovery: Bluetooth device available. Starting discovery."; discover(); } if (mode == QBluetoothLocalDevice::HostPoweredOff) { - qDebug() << "BluetoothServiceDiscovery: Bluetooth adapter disabled. Stop discovering"; + qDebug() << "BluetoothServiceDiscovery: Bluetooth adapter disabled. Stopping discovering"; m_serviceDiscovery->stop(); } } diff --git a/libnymea-app-core/discovery/discoverydevice.cpp b/libnymea-app-core/discovery/discoverydevice.cpp index eaeee7bd..835b178b 100644 --- a/libnymea-app-core/discovery/discoverydevice.cpp +++ b/libnymea-app-core/discovery/discoverydevice.cpp @@ -23,9 +23,9 @@ #include DiscoveryDevice::DiscoveryDevice(QObject *parent): - QObject(parent) + QObject(parent), + m_connections(new Connections(this)) { - m_portConfigs = new PortConfigs(this); } QUuid DiscoveryDevice::uuid() const @@ -64,143 +64,101 @@ void DiscoveryDevice::setVersion(const QString &version) } } -PortConfigs* DiscoveryDevice::portConfigs() const +Connections* DiscoveryDevice::connections() const { - return m_portConfigs; + return m_connections; } -QString DiscoveryDevice::toUrl(int portConfigIndex) -{ - PortConfig *pc = m_portConfigs->get(portConfigIndex); - if (!pc) { - qWarning() << "No portconfig for index" << portConfigIndex; - return QString(); - } - QString ret = pc->protocol() == PortConfig::ProtocolNymeaRpc ? "nymea" : "ws"; - ret += pc->sslEnabled() ? "s" : ""; - ret += "://"; - if (pc->hostAddress().protocol() == QAbstractSocket::IPv4Protocol) { - ret += pc->hostAddress().toString(); - } else if (pc->hostAddress().protocol() == QAbstractSocket::IPv6Protocol){ - ret += "[" + pc->hostAddress().toString() + "]"; - } - ret += ":"; - ret += QString::number(pc->port()); - return ret; -} - -PortConfigs::PortConfigs(QObject *parent): QAbstractListModel(parent) +Connections::Connections(QObject *parent): + QAbstractListModel(parent) { } -int PortConfigs::rowCount(const QModelIndex &parent) const +int Connections::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) - return m_portConfigs.count(); + return m_connections.count(); } -QVariant PortConfigs::data(const QModelIndex &index, int role) const +QVariant Connections::data(const QModelIndex &index, int role) const { switch (role) { - case RoleAddress: - return m_portConfigs.at(index.row())->hostAddressString(); - case RolePort: - return m_portConfigs.at(index.row())->port(); - case RoleProtocol: - return m_portConfigs.at(index.row())->protocol(); - case RoleSSLEnabled: - return m_portConfigs.at(index.row())->sslEnabled(); + case RoleUrl: + return m_connections.at(index.row())->url(); + case RoleName: + return m_connections.at(index.row())->displayName(); + case RoleBearerType: + return m_connections.at(index.row())->bearerType(); + case RoleSecure: + return m_connections.at(index.row())->secure(); } return QVariant(); } -PortConfig *PortConfigs::find(int port) +Connection* Connections::find(const QUrl &url) const { - foreach (PortConfig* pc, m_portConfigs) { - if (pc->port() == port) { - return pc; + foreach (Connection *conn, m_connections) { + if (conn->url() == url) { + return conn; } } return nullptr; } -void PortConfigs::insert(PortConfig *portConfig) +void Connections::addConnection(Connection *connection) { - portConfig->setParent(this); - beginInsertRows(QModelIndex(), m_portConfigs.count(), m_portConfigs.count()); - m_portConfigs.append(portConfig); + connection->setParent(this); + beginInsertRows(QModelIndex(), m_connections.count(), m_connections.count()); + m_connections.append(connection); endInsertRows(); emit countChanged(); } -PortConfig* PortConfigs::get(int index) const +Connection* Connections::get(int index) const { - if (index < 0 || index >= m_portConfigs.count()) - return nullptr; - - return m_portConfigs.at(index); + if (index >= 0 && index < m_connections.count()) { + return m_connections.at(index); + } + return nullptr; } -QHash PortConfigs::roleNames() const +QHash Connections::roleNames() const { QHash roles; - roles.insert(RoleAddress, "address"); - roles.insert(RolePort, "port"); - roles.insert(RoleProtocol, "protocol"); - roles.insert(RoleSSLEnabled, "sslEnabled"); + roles.insert(RoleUrl, "url"); + roles.insert(RoleBearerType, "bearerType"); + roles.insert(RoleName, "name"); + roles.insert(RoleSecure, "secure"); return roles; } -PortConfig::PortConfig(const QHostAddress &hostAddress, int port, QObject *parent): +Connection::Connection(const QUrl &url, Connection::BearerType bearerType, bool secure, const QString &displayName, QObject *parent): QObject(parent), - m_port(port), - m_hostAddress(hostAddress) + m_url(url), + m_bearerType(bearerType), + m_secure(secure), + m_displayName(displayName) { } -int PortConfig::port() const +QUrl Connection::url() const { - return m_port; + return m_url; } -PortConfig::Protocol PortConfig::protocol() const +Connection::BearerType Connection::bearerType() const { - return m_protocol; + return m_bearerType; } -void PortConfig::setProtocol(PortConfig::Protocol protocol) +bool Connection::secure() const { - if (m_protocol != protocol) { - m_protocol = protocol; - emit protocolChanged(); - } + return m_secure; } -QHostAddress PortConfig::hostAddress() const +QString Connection::displayName() const { - return m_hostAddress; -} - -QString PortConfig::hostAddressString() const -{ - if (m_hostAddress.protocol() == QAbstractSocket::IPv6Protocol){ - return "[" + m_hostAddress.toString() + "]"; - } - - return m_hostAddress.toString(); -} - -bool PortConfig::sslEnabled() const -{ - return m_sslEnabled; -} - -void PortConfig::setSslEnabled(bool sslEnabled) -{ - if (m_sslEnabled != sslEnabled) { - m_sslEnabled = sslEnabled; - emit sslEnabledChanged(); - } + return m_displayName; } diff --git a/libnymea-app-core/discovery/discoverydevice.h b/libnymea-app-core/discovery/discoverydevice.h index dc04c2a9..4a340d5c 100644 --- a/libnymea-app-core/discovery/discoverydevice.h +++ b/libnymea-app-core/discovery/discoverydevice.h @@ -29,65 +29,56 @@ #include #include -class PortConfig: public QObject -{ +class Connection: public QObject { Q_OBJECT - Q_PROPERTY(int port READ port CONSTANT) - Q_PROPERTY(Protocol protocol READ protocol NOTIFY protocolChanged) - Q_PROPERTY(QString hostAddress READ hostAddressString NOTIFY hostAddressChanged) - Q_PROPERTY(bool sslEnabled READ sslEnabled NOTIFY sslEnabledChanged) + Q_PROPERTY(QUrl url READ url CONSTANT) + Q_PROPERTY(BearerType bearerType READ bearerType CONSTANT) + Q_PROPERTY(bool secure READ secure CONSTANT) + Q_PROPERTY(QString displayName READ displayName CONSTANT) public: - enum Protocol { - ProtocolNymeaRpc, - ProtocolWebSocket + enum BearerType { + BearerTypeUnknown, + BearerTypeWifi, + BearerTypeEthernet, + BearerTypeBluetooth, + BearerTypeCloud }; - Q_ENUM(Protocol) - PortConfig(const QHostAddress &hostAddress, int port, QObject *parent = nullptr); + Q_ENUM(BearerType) - int port() const; + Connection(const QUrl &url, BearerType bearerType, bool secure, const QString &displayName, QObject *parent = nullptr); - Protocol protocol() const; - void setProtocol(Protocol protocol); - - QHostAddress hostAddress() const; - QString hostAddressString() const; - void setHostAddress(const QString &hostAddress); - - bool sslEnabled() const; - void setSslEnabled(bool sslEnabled); - -signals: - void protocolChanged(); - void hostAddressChanged(); - void sslEnabledChanged(); + QUrl url() const; + BearerType bearerType() const; + bool secure() const; + QString displayName() const; private: - int m_port = -1; - QHostAddress m_hostAddress; - Protocol m_protocol = ProtocolNymeaRpc; - bool m_sslEnabled = false; + QUrl m_url; + BearerType m_bearerType = BearerTypeUnknown; + bool m_secure = false; + QString m_displayName; }; -class PortConfigs: public QAbstractListModel +class Connections: public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ rowCount NOTIFY countChanged) public: enum Roles { - RoleAddress, - RolePort, - RoleProtocol, - RoleSSLEnabled + RoleUrl, + RoleName, + RoleBearerType, + RoleSecure }; Q_ENUM(Roles) - PortConfigs(QObject* parent = nullptr); + Connections(QObject* parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; - PortConfig* find(int port); - void insert(PortConfig* portConfig); + void addConnection(Connection *connection); - Q_INVOKABLE PortConfig *get(int index) const; + Q_INVOKABLE Connection* find(const QUrl &url) const; + Q_INVOKABLE Connection* get(int index) const; signals: void countChanged(); @@ -96,7 +87,7 @@ protected: QHash roleNames() const override; private: - QList m_portConfigs; + QList m_connections; }; @@ -106,7 +97,7 @@ class DiscoveryDevice: public QObject Q_PROPERTY(QUuid uuid READ uuid CONSTANT) Q_PROPERTY(QString name READ name NOTIFY nameChanged) Q_PROPERTY(QString version READ version NOTIFY versionChanged) - Q_PROPERTY(PortConfigs* portConfigs READ portConfigs CONSTANT) + Q_PROPERTY(Connections* connections READ connections CONSTANT) public: explicit DiscoveryDevice(QObject *parent = nullptr); @@ -120,9 +111,7 @@ public: QString version() const; void setVersion(const QString &version); - PortConfigs *portConfigs() const; - - Q_INVOKABLE QString toUrl(int portConfigIndex); + Connections *connections() const; signals: void nameChanged(); @@ -132,7 +121,7 @@ private: QUuid m_uuid; QString m_name; QString m_version; - PortConfigs *m_portConfigs = nullptr; + Connections *m_connections = nullptr; }; #endif // DISCOVERYDEVICE_H diff --git a/libnymea-app-core/discovery/nymeadiscovery.cpp b/libnymea-app-core/discovery/nymeadiscovery.cpp index 32a66893..c72692eb 100644 --- a/libnymea-app-core/discovery/nymeadiscovery.cpp +++ b/libnymea-app-core/discovery/nymeadiscovery.cpp @@ -3,7 +3,7 @@ #include "upnpdiscovery.h" #include "zeroconfdiscovery.h" #include "bluetoothservicediscovery.h" -#include "awsclient.h" +#include "connection/awsclient.h" #include #include @@ -59,10 +59,21 @@ DiscoveryModel *NymeaDiscovery::discoveryModel() const void NymeaDiscovery::cloudDevicesFetched(const QList &devices) { + qDebug() << "Cloud devices fetched"; foreach (const AWSDevice &d, devices) { DiscoveryDevice *device = m_discoveryModel->find(d.id); if (!device) { - + device = new DiscoveryDevice(); + device->setUuid(d.id); + device->setName(d.name); + m_discoveryModel->addDevice(device); + } + QUrl url; + url.setScheme("cloud"); + url.setHost(d.id); + if (!device->connections()->find(url)) { + Connection *conn = new Connection(url, Connection::BearerTypeCloud, true, d.id); + device->connections()->addConnection(conn); } } } diff --git a/libnymea-app-core/discovery/nymeadiscovery.h b/libnymea-app-core/discovery/nymeadiscovery.h index b138cff6..215656b2 100644 --- a/libnymea-app-core/discovery/nymeadiscovery.h +++ b/libnymea-app-core/discovery/nymeadiscovery.h @@ -3,7 +3,7 @@ #include -#include "awsclient.h" +#include "connection/awsclient.h" class DiscoveryModel; class UpnpDiscovery; diff --git a/libnymea-app-core/discovery/upnpdiscovery.cpp b/libnymea-app-core/discovery/upnpdiscovery.cpp index c2da5f56..c35d02f9 100644 --- a/libnymea-app-core/discovery/upnpdiscovery.cpp +++ b/libnymea-app-core/discovery/upnpdiscovery.cpp @@ -51,10 +51,10 @@ UpnpDiscovery::UpnpDiscovery(DiscoveryModel *discoveryModel, QObject *parent) : } if (port == 65535 || socket->state() != QUdpSocket::BoundState) { socket->deleteLater(); - qWarning() << "UPnP discovery could not bind to interface" << netAddressEntry.ip(); + qWarning() << "UPnP: Discovery could not bind to interface" << netAddressEntry.ip(); continue; } - qDebug() << "Discovering on" << netAddressEntry.ip() << port; + qDebug() << "UPnP: Discovering on" << netAddressEntry.ip() << port; m_sockets.append(socket); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); connect(socket, &QUdpSocket::readyRead, this, &UpnpDiscovery::readData); @@ -76,11 +76,11 @@ bool UpnpDiscovery::available() const void UpnpDiscovery::discover() { if (!available()) { - qWarning() << "Could not discover. UPnP not available."; + qWarning() << "UPnP: UPnP not available. Discovery not started."; return; } - qDebug() << "start discovering..."; + qDebug() << "UPNP: Discovery started..."; m_repeatTimer.start(); m_foundDevices.clear(); writeDiscoveryPacket(); @@ -89,7 +89,7 @@ void UpnpDiscovery::discover() void UpnpDiscovery::stopDiscovery() { - qDebug() << "stop discovering"; + qDebug() << "UPNP: Discovery stopped."; m_repeatTimer.stop(); emit discoveringChanged(); } @@ -106,7 +106,7 @@ void UpnpDiscovery::writeDiscoveryPacket() foreach (QUdpSocket* socket, m_sockets) { qint64 ret = socket->writeDatagram(ssdpSearchMessage, QHostAddress("239.255.255.250"), 1900); if (ret != ssdpSearchMessage.length()) { - qWarning() << "Error sending SSDP query on socket" << socket->localAddress(); + qWarning() << "UPnP: Error sending SSDP query on socket" << socket->localAddress(); } } @@ -115,7 +115,7 @@ void UpnpDiscovery::writeDiscoveryPacket() void UpnpDiscovery::error(QAbstractSocket::SocketError error) { QUdpSocket* socket = static_cast(sender()); - qWarning() << "UPnP socket error:" << error << socket->errorString(); + qWarning() << "UPnP: Socket error:" << error << socket->errorString(); } void UpnpDiscovery::readData() @@ -180,7 +180,7 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (reply->error() != QNetworkReply::NoError || status != 200) { - qWarning() << "Error fetching UPnP discovery data:" << status << reply->error() << reply->errorString(); + qWarning() << "UPnP: Error fetching discovery data:" << status << reply->error() << reply->errorString(); return; } @@ -189,7 +189,7 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) QString name; QString version; QUuid uuid; - QList portConfigList; + QList connections; // parse XML data QXmlStreamReader xml(data); @@ -203,30 +203,11 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) if (xml.isStartElement()) { // Check for old style websocketURL and nymeaRpcURL - if (xml.name().toString() == "websocketURL") { + if (xml.name().toString() == "websocketURL" || + xml.name().toString() == "nymeaRpcURL" || + xml.name().toString() == "guhRpcURL") { QUrl u(xml.readElementText()); - PortConfig *pc = new PortConfig(discoveredAddress, u.port()); - pc->setProtocol(PortConfig::ProtocolWebSocket); - pc->setSslEnabled(u.scheme() == "wss"); - portConfigList.append(pc); - } - - if (xml.name().toString() == "nymeaRpcURL") { - QUrl u(xml.readElementText()); - qDebug() << "have url" << u << u.scheme(); - PortConfig *pc = new PortConfig(discoveredAddress, u.port()); - pc->setProtocol(PortConfig::ProtocolNymeaRpc); - pc->setSslEnabled(u.scheme() == "nymeas"); - portConfigList.append(pc); - } - - if (xml.name().toString() == "guhRpcURL") { - QUrl u(xml.readElementText()); - qDebug() << "have url" << u << u.scheme(); - PortConfig *pc = new PortConfig(discoveredAddress, u.port()); - pc->setProtocol(PortConfig::ProtocolNymeaRpc); - pc->setSslEnabled(u.scheme() == "guhs"); - portConfigList.append(pc); + connections.append(u); } // But also for new style serviceList @@ -238,10 +219,7 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) xml.readNext(); if (xml.name().toString() == "SCPDURL") { QUrl u(xml.readElementText()); - PortConfig *pc = new PortConfig(discoveredAddress, u.port()); - pc->setProtocol(u.scheme().startsWith("nymea") ? PortConfig::ProtocolNymeaRpc : PortConfig::ProtocolWebSocket); - pc->setSslEnabled(u.scheme() == "nymeas" || u.scheme() == "wss"); - portConfigList.append(pc); + connections.append(u); } } } @@ -260,27 +238,24 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply) } } - qDebug() << "discovered device" << uuid << name << discoveredAddress << version; +// qDebug() << "discovered device" << uuid << name << discoveredAddress << version << connections << data; DiscoveryDevice* device = m_discoveryModel->find(uuid); if (!device) { device = new DiscoveryDevice(m_discoveryModel); device->setUuid(uuid); - qDebug() << "Adding new host to model"; + qDebug() << "UPnP: Adding new host to model"; m_discoveryModel->addDevice(device); } device->setName(name); device->setVersion(version); - foreach (PortConfig *pc, portConfigList) { - PortConfig *portConfig = device->portConfigs()->find(pc->port()); - if (portConfig) { - qDebug() << "Updating port config" << portConfig->port() << portConfig->sslEnabled() << portConfig->protocol(); - portConfig->setProtocol(pc->protocol()); - portConfig->setSslEnabled(pc->sslEnabled()); - pc->deleteLater(); - } else { - qDebug() << "adding new port config" << pc->port() << pc->sslEnabled() << pc->protocol(); - device->portConfigs()->insert(pc); + foreach (const QUrl &url, connections) { + if (!device->connections()->find(url)) { + qDebug() << "UPnP: Adding new connection to host:" << device->name() << url; + bool sslEnabled = url.scheme() == "nymeas" || url.scheme() == "wss"; + QString displayName = QString("%1:%2").arg(url.host()).arg(url.port()); + Connection *conn = new Connection(url, Connection::BearerTypeWifi, sslEnabled, displayName); + device->connections()->addConnection(conn); } } } diff --git a/libnymea-app-core/discovery/zeroconfdiscovery.cpp b/libnymea-app-core/discovery/zeroconfdiscovery.cpp index e3ceae26..f69f3490 100644 --- a/libnymea-app-core/discovery/zeroconfdiscovery.cpp +++ b/libnymea-app-core/discovery/zeroconfdiscovery.cpp @@ -13,13 +13,13 @@ ZeroconfDiscovery::ZeroconfDiscovery(DiscoveryModel *discoveryModel, QObject *pa connect(m_zeroconfJsonRPC, &QZeroConf::serviceAdded, this, &ZeroconfDiscovery::serviceEntryAdded); connect(m_zeroconfJsonRPC, &QZeroConf::serviceUpdated, this, &ZeroconfDiscovery::serviceEntryAdded); m_zeroconfJsonRPC->startBrowser("_jsonrpc._tcp", QAbstractSocket::AnyIPProtocol); - qDebug() << "created service browser for _jsonrpc._tcp:" << m_zeroconfJsonRPC->browserExists(); + qDebug() << "ZeroConf: Created service browser for _jsonrpc._tcp:" << m_zeroconfJsonRPC->browserExists(); m_zeroconfWebSocket = new QZeroConf(this); connect(m_zeroconfWebSocket, &QZeroConf::serviceAdded, this, &ZeroconfDiscovery::serviceEntryAdded); connect(m_zeroconfWebSocket, &QZeroConf::serviceUpdated, this, &ZeroconfDiscovery::serviceEntryAdded); m_zeroconfWebSocket->startBrowser("_ws._tcp", QAbstractSocket::AnyIPProtocol); - qDebug() << "created service browser for _ws._tcp:" << m_zeroconfWebSocket->browserExists(); + qDebug() << "TeroConf: Created service browser for _ws._tcp:" << m_zeroconfWebSocket->browserExists(); #else qDebug() << "Zeroconf support not compiled in. Zeroconf will not be available."; #endif @@ -73,18 +73,25 @@ void ZeroconfDiscovery::serviceEntryAdded(const QZeroConfService &entry) if (!device) { device = new DiscoveryDevice(m_discoveryModel); device->setUuid(uuid); - qDebug() << "ZeroConf: Adding new host to model"; + qDebug() << "ZeroConf: Adding new host:" << serverName << uuid; m_discoveryModel->addDevice(device); } device->setName(serverName); device->setVersion(version); - PortConfig *portConfig = device->portConfigs()->find(entry.port()); - if (!portConfig) { - qDebug() << "ZeroConf: Adding new port config"; - portConfig = new PortConfig(!entry.ip().isNull() ? entry.ip() : entry.ipv6(), entry.port()); - device->portConfigs()->insert(portConfig); + QUrl url; + if (entry.type() == "_jsonrpc._tcp") { + url.setScheme(sslEnabled ? "nymeas" : "nymea"); + } else { + url.setScheme(sslEnabled ? "wss" : "ws"); + } +// entry + url.setHost(!entry.ip().isNull() ? entry.ip().toString() : entry.ipv6().toString()); + url.setPort(entry.port()); + if (!device->connections()->find(url)){ + qDebug() << "Zeroconf: Adding new connection to host:" << device->name() << url.toString(); + QString displayName = QString("%1:%2").arg(url.host()).arg(url.port()); + Connection *connection = new Connection(url, Connection::BearerTypeWifi, sslEnabled, displayName); + device->connections()->addConnection(connection); } - portConfig->setProtocol(entry.type() == "_ws._tcp" ? PortConfig::ProtocolWebSocket : PortConfig::ProtocolNymeaRpc); - portConfig->setSslEnabled(sslEnabled); } #endif diff --git a/libnymea-app-core/engine.cpp b/libnymea-app-core/engine.cpp index 6bc0f93d..01501134 100644 --- a/libnymea-app-core/engine.cpp +++ b/libnymea-app-core/engine.cpp @@ -20,12 +20,16 @@ #include "engine.h" -#include "tcpsocketinterface.h" #include "rulemanager.h" #include "logmanager.h" #include "tagsmanager.h" #include "basicconfiguration.h" -#include "awsclient.h" +#include "connection/awsclient.h" + +#include "connection/tcpsockettransport.h" +#include "connection/websockettransport.h" +#include "connection/bluetoothtransport.h" +#include "connection/cloudtransport.h" Engine* Engine::s_instance = nullptr; @@ -94,6 +98,11 @@ Engine::Engine(QObject *parent) : m_bluetoothDiscovery(new BluetoothDiscovery(this)), m_aws(new AWSClient(this)) { + m_connection->registerTransport(new TcpSocketTransport(this)); + m_connection->registerTransport(new WebsocketTransport(this)); + m_connection->registerTransport(new BluetoothTransport(this)); + m_connection->registerTransport(new CloudTransport(m_aws, this)); + connect(m_jsonRpcClient, &JsonRpcClient::connectedChanged, this, &Engine::onConnectedChanged); connect(m_jsonRpcClient, &JsonRpcClient::authenticationRequiredChanged, this, &Engine::onConnectedChanged); diff --git a/libnymea-app-core/engine.h b/libnymea-app-core/engine.h index 9c079e65..87a6cd51 100644 --- a/libnymea-app-core/engine.h +++ b/libnymea-app-core/engine.h @@ -24,7 +24,7 @@ #include #include "devicemanager.h" -#include "nymeainterface.h" +#include "connection/nymeatransportinterface.h" #include "jsonrpc/jsonrpcclient.h" #include "wifisetup/bluetoothdiscovery.h" diff --git a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp index 0d45b0a5..e903ac32 100644 --- a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp @@ -19,7 +19,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "jsonrpcclient.h" -#include "nymeaconnection.h" +#include "connection/nymeaconnection.h" #include "types/param.h" #include "types/params.h" diff --git a/libnymea-app-core/jsonrpc/jsonrpcclient.h b/libnymea-app-core/jsonrpc/jsonrpcclient.h index df7f8570..a81554c3 100644 --- a/libnymea-app-core/jsonrpc/jsonrpcclient.h +++ b/libnymea-app-core/jsonrpc/jsonrpcclient.h @@ -26,7 +26,7 @@ #include #include -#include "nymeaconnection.h" +#include "connection/nymeaconnection.h" #include "jsonhandler.h" class JsonRpcReply; diff --git a/libnymea-app-core/libnymea-app-core.h b/libnymea-app-core/libnymea-app-core.h index d2ee7652..d9f3efa9 100644 --- a/libnymea-app-core/libnymea-app-core.h +++ b/libnymea-app-core/libnymea-app-core.h @@ -50,7 +50,7 @@ #include "ruletemplates/stateevaluatortemplate.h" #include "ruletemplates/statedescriptortemplate.h" #include "ruletemplates/ruleactiontemplate.h" -#include "awsclient.h" +#include "connection/awsclient.h" #include @@ -150,8 +150,7 @@ void registerQmlTypes() { qmlRegisterType(uri, 1, 0, "NymeaDiscovery"); qmlRegisterUncreatableType(uri, 1, 0, "DiscoveryModel", "Get it from NymeaDiscovery"); qmlRegisterUncreatableType(uri, 1, 0, "DiscoveryDevice", "Get it from DiscoveryModel"); - qmlRegisterUncreatableType(uri, 1, 0, "PortConfigs", "Get it from DiscoveryDevice"); - qmlRegisterUncreatableType(uri, 1, 0, "PortConfig", "Get it from DiscoveryDevice"); + qmlRegisterUncreatableType(uri, 1, 0, "Connection", "Get it from DiscoveryDevice"); qmlRegisterType(uri, 1, 0, "EventDescriptorParamsFilterModel"); diff --git a/libnymea-app-core/libnymea-app-core.pro b/libnymea-app-core/libnymea-app-core.pro index d6bd148b..55c1cddb 100644 --- a/libnymea-app-core/libnymea-app-core.pro +++ b/libnymea-app-core/libnymea-app-core.pro @@ -10,19 +10,28 @@ include(../config.pri) DEFINES += WITH_ZEROCONF include(../QtZeroConf/qtzeroconf.pri) } +DEFINES += QT_STATIC +include(../qmqtt/src/mqtt/mqtt.pri) +HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS QT -= gui QT += network websockets bluetooth LIBS += -lssl -lcrypto -INCLUDEPATH += $$top_srcdir/libnymea-common $$top_srcdir/QtZeroConf +INCLUDEPATH += $$top_srcdir/libnymea-common \ + $$top_srcdir/QtZeroConf \ + $$top_srcdir/qmqtt/src/mqtt/ SOURCES += \ engine.cpp \ - nymeainterface.cpp \ + connection/nymeaconnection.cpp \ + connection/nymeatransportinterface.cpp \ + connection/websockettransport.cpp \ + connection/tcpsockettransport.cpp \ + connection/bluetoothtransport.cpp \ + connection/awsclient.cpp \ devicemanager.cpp \ - websocketinterface.cpp \ jsonrpc/jsontypes.cpp \ jsonrpc/jsonrpcclient.cpp \ jsonrpc/jsonhandler.cpp \ @@ -36,8 +45,6 @@ SOURCES += \ devicediscovery.cpp \ vendorsproxy.cpp \ pluginsproxy.cpp \ - tcpsocketinterface.cpp \ - nymeaconnection.cpp \ interfacesmodel.cpp \ discovery/zeroconfdiscovery.cpp \ discovery/discoverydevice.cpp \ @@ -69,16 +76,18 @@ SOURCES += \ ruletemplates/ruleactiontemplate.cpp \ ruletemplates/stateevaluatortemplate.cpp \ ruletemplates/statedescriptortemplate.cpp \ - bluetoothinterface.cpp \ discovery/bluetoothservicediscovery.cpp \ - awsclient.cpp \ - connection/srp.c + connection/cloudtransport.cpp HEADERS += \ engine.h \ - nymeainterface.h \ + connection/nymeaconnection.h \ + connection/nymeatransportinterface.h \ + connection/websockettransport.h \ + connection/tcpsockettransport.h \ + connection/bluetoothtransport.h \ + connection/awsclient.h \ devicemanager.h \ - websocketinterface.h \ jsonrpc/jsontypes.h \ jsonrpc/jsonrpcclient.h \ jsonrpc/jsonhandler.h \ @@ -92,8 +101,6 @@ HEADERS += \ devicediscovery.h \ vendorsproxy.h \ pluginsproxy.h \ - tcpsocketinterface.h \ - nymeaconnection.h \ interfacesmodel.h \ discovery/zeroconfdiscovery.h \ discovery/discoverydevice.h \ @@ -126,9 +133,8 @@ HEADERS += \ ruletemplates/ruleactiontemplate.h \ ruletemplates/stateevaluatortemplate.h \ ruletemplates/statedescriptortemplate.h \ - bluetoothinterface.h \ discovery/bluetoothservicediscovery.h \ - awsclient.h + connection/cloudtransport.h unix { target.path = /usr/lib diff --git a/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.cpp b/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.cpp index ea625403..1a80e31a 100644 --- a/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.cpp +++ b/libnymea-app-core/wifisetup/wirelessaccesspointsproxy.cpp @@ -49,6 +49,7 @@ void WirelessAccessPointsProxy::setAccessPoints(WirelessAccessPoints *accessPoin bool WirelessAccessPointsProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { Q_UNUSED(source_parent) + Q_UNUSED(source_row) // Filter out the current selected network // WirelessAccessPoint *accessPoint = m_accessPoints->get(source_row); diff --git a/nymea-app/main.cpp b/nymea-app/main.cpp index b3d51767..871f32b6 100644 --- a/nymea-app/main.cpp +++ b/nymea-app/main.cpp @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) foreach (const QFileInfo &fi, QDir(":/ui/fonts/").entryInfoList()) { int id = QFontDatabase::addApplicationFont(fi.absoluteFilePath()); - qDebug() << "Added font" << fi.absoluteFilePath() << QFontDatabase::applicationFontFamilies(id); +// qDebug() << "Added font" << fi.absoluteFilePath() << QFontDatabase::applicationFontFamilies(id); } QFont applicationFont; diff --git a/nymea-app/nymea-app.pro b/nymea-app/nymea-app.pro index 1ae44e84..4e8dd38a 100644 --- a/nymea-app/nymea-app.pro +++ b/nymea-app/nymea-app.pro @@ -7,7 +7,8 @@ QT += network qml quick quickcontrols2 svg websockets bluetooth INCLUDEPATH += $$top_srcdir/libnymea-common \ $$top_srcdir/libnymea-app-core LIBS += -L$$top_builddir/libnymea-app-core/ -lnymea-app-core \ - -L$$top_builddir/libnymea-common/ -lnymea-common + -L$$top_builddir/libnymea-common/ -lnymea-common \ + LIBS += -lssl -lcrypto win32:Debug:LIBS += -L$$top_builddir/libnymea-app-core/debug \ @@ -93,6 +94,3 @@ BR=$$BRANDING target.path = /usr/bin INSTALLS += target - -DISTFILES += \ - ui/magic/NewThingMagicPage.qml diff --git a/nymea-app/stylecontroller.cpp b/nymea-app/stylecontroller.cpp index 84fa4672..7c64363d 100644 --- a/nymea-app/stylecontroller.cpp +++ b/nymea-app/stylecontroller.cpp @@ -40,6 +40,6 @@ void StyleController::setCurrentStyle(const QString ¤tStyle) QStringList StyleController::allStyles() const { QDir dir(":/styles/"); - qDebug() << "styles:" << dir.entryList(); +// qDebug() << "styles:" << dir.entryList(); return dir.entryList(QDir::Dirs); } diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index c41c6440..96373b7c 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -116,9 +116,9 @@ ApplicationWindow { objectName: "pageStack" anchors.fill: parent initialItem: Page {} - onDepthChanged: { - print("stackview depth changed", pageStack.depth) - } +// onDepthChanged: { +// print("stackview depth changed", pageStack.depth) +// } } onClosing: { diff --git a/nymea-app/ui/components/MeaListItemDelegate.qml b/nymea-app/ui/components/MeaListItemDelegate.qml index b97eda4c..41be3c54 100644 --- a/nymea-app/ui/components/MeaListItemDelegate.qml +++ b/nymea-app/ui/components/MeaListItemDelegate.qml @@ -1,6 +1,7 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 +import QtQuick.Controls.Material 2.2 SwipeDelegate { id: root @@ -9,6 +10,9 @@ SwipeDelegate { property bool progressive: true property bool canDelete: false + property bool wrapTexts: true + property bool prominentSubText: true + property string iconName property int iconSize: app.iconSize property color iconColor: app.accentColor @@ -37,8 +41,8 @@ SwipeDelegate { Layout.fillWidth: true Layout.fillHeight: true text: root.text - wrapMode: Text.WordWrap - maximumLineCount: 2 + wrapMode: root.wrapTexts ? Text.WordWrap : Text.NoWrap + maximumLineCount: root.wrapTexts ? 2 : 1 elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } @@ -46,9 +50,10 @@ SwipeDelegate { Layout.fillWidth: true Layout.fillHeight: true text: root.subText - font.pixelSize: app.smallFont - wrapMode: Text.WordWrap - maximumLineCount: 2 + font.pixelSize: root.prominentSubText ? app.smallFont : app.extraSmallFont + color: root.prominentSubText ? Material.foreground : Material.color(Material.Grey) + wrapMode: root.wrapTexts ? Text.WordWrap : Text.NoWrap + maximumLineCount: root.wrapTexts ? 2 : 1 elide: Text.ElideRight verticalAlignment: Text.AlignVCenter visible: root.subText.length > 0 diff --git a/nymea-app/ui/connection/ConnectPage.qml b/nymea-app/ui/connection/ConnectPage.qml index 106ccb5b..2e116be5 100644 --- a/nymea-app/ui/connection/ConnectPage.qml +++ b/nymea-app/ui/connection/ConnectPage.qml @@ -85,9 +85,9 @@ Page { header: FancyHeader { title: qsTr("Connect %1").arg(app.systemName) model: ListModel { - ListElement { iconSource: "../images/network-vpn.svg"; text: qsTr("Manual connection"); page: "connection/ManualConnectPage.qml" } - ListElement { iconSource: "../images/bluetooth.svg"; text: qsTr("Wireless setup"); page: "connection/BluetoothDiscoveryPage.qml"; } - ListElement { iconSource: "../images/cloud.svg"; text: qsTr("Cloud login"); page: "connection/CloudLoginPage.qml" } + ListElement { iconSource: "../images/network-vpn.svg"; text: qsTr("Manual connection"); page: "ManualConnectPage.qml" } + ListElement { iconSource: "../images/bluetooth.svg"; text: qsTr("Wireless setup"); page: "BluetoothDiscoveryPage.qml"; } + ListElement { iconSource: "../images/cloud.svg"; text: qsTr("Cloud login"); page: "CloudLoginPage.qml" } ListElement { iconSource: "../images/stock_application.svg"; text: qsTr("App settings"); page: "AppSettingsPage.qml" } } onClicked: { @@ -145,58 +145,68 @@ Page { height: app.delegateHeight objectName: "discoveryDelegate" + index property var discoveryDevice: discovery.discoveryModel.get(index) - property string defaultPortConfigIndex: { - - if (model.deviceType !== DiscoveryDevice.DeviceTypeNetwork) { - return -1 - } - + property string defaultConnectionIndex: { var usedConfigIndex = 0; - for (var i = 1; i < discoveryDevice.portConfigs.count; i++) { - var oldConfig = discoveryDevice.portConfigs.get(usedConfigIndex); - var newConfig = discoveryDevice.portConfigs.get(i); + for (var i = 1; i < discoveryDevice.connections.count; i++) { + var oldConfig = discoveryDevice.connections.get(usedConfigIndex); + var newConfig = discoveryDevice.connections.get(i); - // prefer secure over insecure - if (!oldConfig.sslEnabled && newConfig.sslEnabled) { + // Preference of bearerType + var bearerPreference = [Connection.BearerTypeEthernet, Connection.BearerTypeWifi, Connection.BearerTypeBluetooth, Connection.BearerTypeCloud] + var oldBearerPriority = bearerPreference.indexOf(oldConfig.bearerType); + var newBearerPriority = bearerPreference.indexOf(newConfig.bearerType); + if (newBearerPriority > oldBearerPriority) { usedConfigIndex = i; continue; } - if (oldConfig.sslEnabled && !newConfig.sslEnabled) { + if (oldBearerPriority > newBearerPriority) { + continue; // discard new one the one we have is on a better bearer type + } + + // prefer secure over insecure + if (!oldConfig.secure && newConfig.secure) { + usedConfigIndex = i; + continue; + } + if (oldConfig.secure && !newConfig.secure) { continue; // discard new one as the one we already have is more secure } - // both options are new either secure or insecure, prefer nymearpc over websocket for less overhead - if (oldConfig.protocol === PortConfig.ProtocolWebSocket && newConfig.protocol === PortConfig.ProtocolNymeaRpc) { + // both options are now on the same bearer and either secure or insecure, prefer nymearpc over websocket for less overhead + if (oldConfig.url.toString().startsWith("ws") && newConfig.url.toString().startsWith("nymea")) { usedConfigIndex = i; } } return usedConfigIndex } - iconName: model.deviceType === DiscoveryDevice.DeviceTypeNetwork ? "../images/network-wifi-symbolic.svg" : "../images/bluetooth.svg" + iconName: { + switch (discoveryDevice.connections.get(defaultConnectionIndex).bearerType) { + case Connection.BearerTypeWifi: + return "../images/network-wifi-symbolic.svg"; + case Connection.BearerTypeEthernet: + return "../images/network-wired-symbolic.svg" + case Connection.BearerTypeBluetooth: + return "../images/bluetooth.svg"; + case Connection.BearerTypeCloud: + return "../images/cloud.svg" + } + return "" + } + text: model.name - subText: model.deviceType === DiscoveryDevice.DeviceTypeNetwork ? discoveryDevice.hostAddress : discoveryDevice.bluetoothAddress - property bool hasSecurePort: { - if (discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork) { - return discoveryDeviceDelegate.discoveryDevice.portConfigs.get(discoveryDeviceDelegate.defaultPortConfigIndex).sslEnabled - } else { - return false - } - } - property bool isTrusted: { - if (discoveryDeviceDelegate.discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork) { - Engine.connection.isTrusted(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex)) - } else { - return false - } - } - progressive: true - secondaryIconName: "../images/network-secure.svg" + subText: discoveryDevice.connections.get(defaultConnectionIndex).url + wrapTexts: false + prominentSubText: false + progressive: false + property bool isSecure: discoveryDevice.connections.get(defaultConnectionIndex).secure + property bool isTrusted: Engine.connection.isTrusted(discoveryDeviceDelegate.discoveryDevice.connections.get(defaultConnectionIndex).url) + secondaryIconName: isSecure ? "../images/network-secure.svg" : "" secondaryIconColor: isTrusted ? app.accentColor : Material.foreground swipe.enabled: discoveryDeviceDelegate.discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork onClicked: { - Engine.connection.connect(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex)) + Engine.connection.connect(discoveryDeviceDelegate.discoveryDevice.connections.get(defaultConnectionIndex).url) var page = pageStack.push(Qt.resolvedUrl("ConnectingPage.qml")) page.cancel.connect(function() { Engine.connection.disconnect() @@ -484,35 +494,34 @@ Page { id: contentColumn width: parent.width Repeater { - model: dialog.discoveryDevice.portConfigs - ItemDelegate { + model: dialog.discoveryDevice.connections + delegate: MeaListItemDelegate { Layout.fillWidth: true - contentItem: RowLayout { - ColumnLayout { - Layout.fillWidth: true - Label { - Layout.fillWidth: true - elide: Text.ElideMiddle - text: "%1:%2".arg(model.address).arg(model.port) - } - Label { - text: model.protocol === PortConfig.ProtocolNymeaRpc ? "nymea-rpc" : "websocket" - Layout.fillWidth: true - font.pixelSize: app.smallFont - } - } - - ColorIcon { - Layout.preferredHeight: app.iconSize - Layout.preferredWidth: height - visible: model.sslEnabled - name: "../images/network-secure.svg" - property bool isTrusted: Engine.connection.isTrusted(dialog.discoveryDevice.toUrl(index)) - color: isTrusted ? app.accentColor : keyColor + wrapTexts: false + progressive: false + text: model.name + subText: model.url + prominentSubText: false + iconName: { + switch (model.bearerType) { + case Connection.BearerTypeWifi: + return "../images/network-wifi-symbolic.svg"; + case Connection.BearerTypeEthernet: + return "../images/network-wired-symbolic.svg" + case Connection.BearerTypeBluetooth: + return "../images/bluetooth.svg"; + case Connection.BearerTypeCloud: + return "../images/cloud.svg" } + return "" } + + secondaryIconName: model.secure ? "../images/network-secure.svg" : "" + secondaryIconColor: isTrusted ? app.accentColor : "gray" + readonly property bool isTrusted: Engine.connection.isTrusted(url) + onClicked: { - Engine.connection.connect(dialog.discoveryDevice.toUrl(index)) + Engine.connection.connect(dialog.discoveryDevice.connections.get(index).url) dialog.close() } } diff --git a/qmqtt b/qmqtt new file mode 160000 index 00000000..0defd80f --- /dev/null +++ b/qmqtt @@ -0,0 +1 @@ +Subproject commit 0defd80f002a4bcb7b92605393708d4c68c89988