File indexing completed on 2024-04-21 14:45:04

0001 /* EkosLive Node
0002 
0003     SPDX-FileCopyrightText: 2023 Jasem Mutlaq <mutlaqja@ikarustech.com>
0004 
0005     Communication Node
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "node.h"
0011 #include "version.h"
0012 #include "Options.h"
0013 #include "ekos_debug.h"
0014 
0015 #include <QWebSocket>
0016 #include <QUrlQuery>
0017 #include <QTimer>
0018 #include <QJsonDocument>
0019 
0020 #include <KActionCollection>
0021 #include <basedevice.h>
0022 #include <QUuid>
0023 
0024 namespace EkosLive
0025 {
0026 Node::Node(const QString &name) : m_Name(name)
0027 {
0028     connect(&m_WebSocket, &QWebSocket::connected, this, &Node::onConnected);
0029     connect(&m_WebSocket, &QWebSocket::disconnected, this, &Node::onDisconnected);
0030     connect(&m_WebSocket, static_cast<void(QWebSocket::*)(QAbstractSocket::SocketError)>(&QWebSocket::error), this,
0031             &Node::onError);
0032 
0033     m_Path = "/" + m_Name + "/ekos";
0034 }
0035 
0036 void Node::connectServer()
0037 {
0038     QUrl requestURL(m_URL);
0039 
0040     QUrlQuery query;
0041     query.addQueryItem("username", m_AuthResponse["username"].toString());
0042     query.addQueryItem("token", m_AuthResponse["token"].toString());
0043     if (m_AuthResponse.contains("remoteToken"))
0044         query.addQueryItem("remoteToken", m_AuthResponse["remoteToken"].toString());
0045     query.addQueryItem("cloudEnabled", Options::ekosLiveCloud() ? "true" : "false");
0046     query.addQueryItem("email", m_AuthResponse["email"].toString());
0047     query.addQueryItem("from_date", m_AuthResponse["from_date"].toString());
0048     query.addQueryItem("to_date", m_AuthResponse["to_date"].toString());
0049     query.addQueryItem("plan_id", m_AuthResponse["plan_id"].toString());
0050     query.addQueryItem("type", m_AuthResponse["type"].toString());
0051     query.addQueryItem("version", KSTARS_VERSION);
0052 
0053     requestURL.setPath(m_Path);
0054     requestURL.setQuery(query);
0055 
0056     m_WebSocket.open(requestURL);
0057 
0058     qCInfo(KSTARS_EKOS) << "Connecting to " << m_Name << "Websocket server at" << requestURL.toDisplayString();
0059 }
0060 
0061 void Node::disconnectServer()
0062 {
0063     m_WebSocket.close();
0064 }
0065 
0066 void Node::onConnected()
0067 {
0068     //qCInfo(KSTARS_EKOS) << "Connected to" << m_Name << "Websocket server at" << m_URL.toDisplayString();
0069 
0070     m_isConnected = true;
0071     m_ReconnectTries = 0;
0072 
0073     connect(&m_WebSocket, &QWebSocket::textMessageReceived,  this, &Node::onTextReceived, Qt::UniqueConnection);
0074     connect(&m_WebSocket, &QWebSocket::binaryMessageReceived,  this, &Node::onBinaryReceived, Qt::UniqueConnection);
0075 
0076     emit connected();
0077 }
0078 
0079 void Node::onDisconnected()
0080 {
0081     qCInfo(KSTARS_EKOS) << "Disconnected from" << m_Name << "Websocket server at" << m_URL.toDisplayString();
0082     m_isConnected = false;
0083 
0084     disconnect(&m_WebSocket, &QWebSocket::textMessageReceived,  this, &Node::onTextReceived);
0085     disconnect(&m_WebSocket, &QWebSocket::binaryMessageReceived,  this, &Node::onBinaryReceived);
0086 
0087     emit disconnected();
0088 }
0089 
0090 void Node::onError(QAbstractSocket::SocketError error)
0091 {
0092     qCritical(KSTARS_EKOS) << m_Name << "Websocket connection error from" << m_URL.toDisplayString() << ":" <<
0093                            m_WebSocket.errorString();
0094     if (error == QAbstractSocket::RemoteHostClosedError ||
0095             error == QAbstractSocket::ConnectionRefusedError)
0096     {
0097         if (m_ReconnectTries++ < RECONNECT_MAX_TRIES)
0098             QTimer::singleShot(RECONNECT_INTERVAL, this, &Node::connectServer);
0099     }
0100 }
0101 
0102 
0103 ///////////////////////////////////////////////////////////////////////////////////////////
0104 ///
0105 ///////////////////////////////////////////////////////////////////////////////////////////
0106 void Node::sendResponse(const QString &command, const QJsonObject &payload)
0107 {
0108     if (m_isConnected == false)
0109         return;
0110 
0111     m_WebSocket.sendTextMessage(QJsonDocument({{"type", command}, {"payload", payload}}).toJson(QJsonDocument::Compact));
0112 }
0113 
0114 ///////////////////////////////////////////////////////////////////////////////////////////
0115 ///
0116 ///////////////////////////////////////////////////////////////////////////////////////////
0117 void Node::sendResponse(const QString &command, const QJsonArray &payload)
0118 {
0119     if (m_isConnected == false)
0120         return;
0121 
0122     m_WebSocket.sendTextMessage(QJsonDocument({{"type", command}, {"payload", payload}}).toJson(QJsonDocument::Compact));
0123 }
0124 
0125 ///////////////////////////////////////////////////////////////////////////////////////////
0126 ///
0127 ///////////////////////////////////////////////////////////////////////////////////////////
0128 void Node::sendResponse(const QString &command, const QString &payload)
0129 {
0130     if (m_isConnected == false)
0131         return;
0132 
0133     m_WebSocket.sendTextMessage(QJsonDocument({{"type", command}, {"payload", payload}}).toJson(QJsonDocument::Compact));
0134 }
0135 
0136 ///////////////////////////////////////////////////////////////////////////////////////////
0137 ///
0138 ///////////////////////////////////////////////////////////////////////////////////////////
0139 void Node::sendResponse(const QString &command, bool payload)
0140 {
0141     if (m_isConnected == false)
0142         return;
0143 
0144     m_WebSocket.sendTextMessage(QJsonDocument({{"type", command}, {"payload", payload}}).toJson(QJsonDocument::Compact));
0145 }
0146 
0147 ///////////////////////////////////////////////////////////////////////////////////////////
0148 ///
0149 ///////////////////////////////////////////////////////////////////////////////////////////
0150 void Node::sendTextMessage(const QString &message)
0151 {
0152     if (m_isConnected == false)
0153         return;
0154     m_WebSocket.sendTextMessage(message);
0155 }
0156 
0157 ///////////////////////////////////////////////////////////////////////////////////////////
0158 ///
0159 ///////////////////////////////////////////////////////////////////////////////////////////
0160 void Node::sendBinaryMessage(const QByteArray &message)
0161 {
0162     if (m_isConnected == false)
0163         return;
0164     m_WebSocket.sendBinaryMessage(message);
0165 }
0166 
0167 }