From 3e258549ced81e86de3d43f217bc41891b0d6214 Mon Sep 17 00:00:00 2001
From: "denis.sumin" <denis.smolov@demlabs.net>
Date: Tue, 3 Sep 2024 16:44:53 +0700
Subject: [PATCH] added a new class for sending data and a tcp server for local
 distribution on port 8040

---
 .gitignore                                    |  3 +-
 CMakeLists.txt                                |  3 +
 .../DiagDataSendingWorker.cpp                 | 87 +++++++++++++++++++
 CellframeNodeDiagtool/DiagDataSendingWorker.h | 45 ++++++++++
 CellframeNodeDiagtool/DiagnosticWorker.cpp    | 25 +-----
 CellframeNodeDiagtool/DiagnosticWorker.h      |  9 +-
 6 files changed, 141 insertions(+), 31 deletions(-)
 create mode 100644 CellframeNodeDiagtool/DiagDataSendingWorker.cpp
 create mode 100644 CellframeNodeDiagtool/DiagDataSendingWorker.h

diff --git a/.gitignore b/.gitignore
index 860229f..97a3828 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,5 @@ moc_*
 .qmake_stash
 qrc_*
 rcc/*
-node_build
\ No newline at end of file
+node_build
+build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dee6566..020ecce 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,7 @@ if(UNIX)
         add_definitions(-DCLI_PATH="./cellframe-node-cli")
         add_executable(${PROJECT_NAME}
             ./CellframeNodeDiagtool/DiagnosticWorker.cpp
+            ./CellframeNodeDiagtool/DiagDataSendingWorker.cpp
             ./CellframeNodeDiagtool/AbstractDiagnostic.cpp
             ./CellframeNodeDiagtool/MacDiagnostic.cpp
             ./CellframeNodeDiagtool/NotifyWorker.cpp
@@ -35,6 +36,7 @@ if(UNIX)
         add_definitions(-DCLI_PATH="/opt/cellframe-node/bin/cellframe-node-cli")
         add_executable(${PROJECT_NAME}
             ./CellframeNodeDiagtool/DiagnosticWorker.cpp
+            ./CellframeNodeDiagtool/DiagDataSendingWorker.cpp
             ./CellframeNodeDiagtool/AbstractDiagnostic.cpp
             ./CellframeNodeDiagtool/LinuxDiagnostic.cpp
             ./CellframeNodeDiagtool/NotifyWorker.cpp
@@ -51,6 +53,7 @@ if(WIN32)
     add_definitions(-DCLI_PATH="cellframe-node-cli.exe")
     add_executable(${PROJECT_NAME} WIN32
         ./CellframeNodeDiagtool/DiagnosticWorker.cpp
+        ./CellframeNodeDiagtool/DiagDataSendingWorker.cpp
         ./CellframeNodeDiagtool/AbstractDiagnostic.cpp
         ./CellframeNodeDiagtool/registry.c
         ./CellframeNodeDiagtool/WinDiagnostic.cpp
diff --git a/CellframeNodeDiagtool/DiagDataSendingWorker.cpp b/CellframeNodeDiagtool/DiagDataSendingWorker.cpp
new file mode 100644
index 0000000..59fba0c
--- /dev/null
+++ b/CellframeNodeDiagtool/DiagDataSendingWorker.cpp
@@ -0,0 +1,87 @@
+#include "DiagDataSendingWorker.h"
+
+static quint64 port = 8040;
+
+DiagDataSendingWorker::DiagDataSendingWorker(QTcpServer *parent)
+    : QTcpServer{parent}
+{
+    s_timer_restart = new QTimer(this);
+    connect(s_timer_restart, &QTimer::timeout,
+            this, &DiagDataSendingWorker::startServer,
+            Qt::QueuedConnection);
+
+    startServer();
+
+    m_urls = QStringList()<<"https://telemetry.cellframe.net/diag_report"<< "https://engine-minkowski.kelvpn.com/diag_report";
+    m_netMngr = new QNetworkAccessManager(this);
+    connect(m_netMngr, &QNetworkAccessManager::finished, this, [=](QNetworkReply*r) {
+        qDebug() <<"Data sent. " << r->error();
+    });
+}
+
+void DiagDataSendingWorker::startServer()
+{
+    if( !listen(QHostAddress::Any, port) )
+    {
+        s_timer_restart->stop();
+        s_timer_restart->start(5000);
+
+        qWarning()<<"Unable start diagtool server" << errorString();
+    }
+    else{
+        connect(this, &QTcpServer::newConnection,
+                this, &DiagDataSendingWorker::onNewConnection,
+                Qt::QueuedConnection);
+
+        serverStatus = true;
+        qInfo()<<"Diagtool server is started";
+    }
+}
+
+void DiagDataSendingWorker::onNewConnection()
+{
+    qDebug()<<"New connection...";
+    QTcpSocket * _socket = nextPendingConnection();
+
+    if(_socket->state() != QAbstractSocket::ConnectedState)
+        return;
+
+    s_tcpSocketList.push_back(_socket);
+
+    connect(_socket, &QTcpSocket::disconnected,
+            this, &DiagDataSendingWorker::onClientDisconnect,
+            Qt::QueuedConnection);
+
+    qDebug()<<"Client's count:" << s_tcpSocketList.length();
+}
+
+void DiagDataSendingWorker::onClientDisconnect()
+{
+    qDebug()<<"Client disconnected";
+    QTcpSocket* _socket = dynamic_cast<QTcpSocket*>(sender());
+    s_tcpSocketList.removeOne(_socket);
+    qDebug()<<"Client's count:" << s_tcpSocketList.length();
+}
+
+
+void DiagDataSendingWorker::sendData(QJsonDocument diagdata, QString mac)
+{
+    if(serverStatus && s_tcpSocketList.length())
+    {
+        for(auto client: qAsConst(s_tcpSocketList))
+            client->write(diagdata.toJson());
+    }
+
+    for (const auto &url_s : qAsConst(m_urls))
+    {
+        QUrl url = QUrl(url_s);
+
+        auto req = QNetworkRequest(url);
+        req.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
+        QJsonObject obj = diagdata.object();
+        obj.insert("mac",mac);
+        diagdata.setObject(obj);
+        m_netMngr->post(req, diagdata.toJson());
+        qDebug()<<"Post request by url: " << url.toString();
+    }
+}
diff --git a/CellframeNodeDiagtool/DiagDataSendingWorker.h b/CellframeNodeDiagtool/DiagDataSendingWorker.h
new file mode 100644
index 0000000..af0d2af
--- /dev/null
+++ b/CellframeNodeDiagtool/DiagDataSendingWorker.h
@@ -0,0 +1,45 @@
+#ifndef DIAGDATASENDINGWORKER_H
+#define DIAGDATASENDINGWORKER_H
+
+#include <QObject>
+#include <QTcpServer>
+#include <QTcpSocket>
+#include <QTextCodec>
+#include <QUrl>
+#include <QTimer>
+
+#include <QJsonDocument>
+#include <QJsonObject>
+
+#include <QNetworkAccessManager>
+#include <QHttpPart>
+#include <QHttpMultiPart>
+#include <QNetworkReply>
+
+class DiagDataSendingWorker : public QTcpServer
+{
+    Q_OBJECT
+public:
+    explicit DiagDataSendingWorker(QTcpServer *parent = nullptr);
+
+    void sendData(QJsonDocument diagdata, QString mac);
+
+private slots:
+    void startServer();
+    void onNewConnection();
+    void onClientDisconnect();
+
+
+private:
+    QTimer *s_timer_restart;
+    QList<QTcpSocket*> s_tcpSocketList;
+
+    QStringList m_urls;
+    QNetworkAccessManager *m_netMngr;
+
+public:
+    bool serverStatus{false};
+
+};
+
+#endif // DIAGDATASENDINGWORKER_H
diff --git a/CellframeNodeDiagtool/DiagnosticWorker.cpp b/CellframeNodeDiagtool/DiagnosticWorker.cpp
index 2426425..e1c07c9 100644
--- a/CellframeNodeDiagtool/DiagnosticWorker.cpp
+++ b/CellframeNodeDiagtool/DiagnosticWorker.cpp
@@ -18,11 +18,7 @@ DiagnosticWorker::~DiagnosticWorker()
 
 void DiagnosticWorker::init()
 {
-    m_urls = QStringList()<<"https://telemetry.cellframe.net/diag_report"<< "https://engine-minkowski.kelvpn.com/diag_report";
-    m_netMngr = new QNetworkAccessManager(this);
-    connect(m_netMngr, &QNetworkAccessManager::finished, this, [=](QNetworkReply*r) {
-        qDebug() <<"Data sent. " << r->error();
-    });
+    s_diagDataWorker = new DiagDataSendingWorker();
 
     s_uptime_timer = new QTimer(this);
     connect(s_uptime_timer, &QTimer::timeout,
@@ -130,27 +126,10 @@ void DiagnosticWorker::slot_diagnostic_data(QJsonDocument data)
     data.setObject(obj);
     m_lastSendedPack = data;
 
-    write_data(data);
+    s_diagDataWorker->sendData(data, m_diagnostic->s_mac.toString());
 }
 
 void DiagnosticWorker::slot_uptime()
 {
     s_uptime = m_diagnostic->get_uptime_string(s_elapsed_timer->elapsed()/1000);
 }
-
-void DiagnosticWorker::write_data(QJsonDocument data)
-{
-    for (auto url_s : m_urls)
-    {
-        QUrl url = QUrl(url_s);
-
-        auto req = QNetworkRequest(url);
-        req.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
-        QString key = m_diagnostic->s_mac.toString();
-        QJsonObject obj = data.object();
-        obj.insert("mac",key);
-        data.setObject(obj);
-        m_netMngr->post(req, data.toJson());
-        qDebug()<<"Post request by url: " << url.toString();
-    }
-}
diff --git a/CellframeNodeDiagtool/DiagnosticWorker.h b/CellframeNodeDiagtool/DiagnosticWorker.h
index ab027f3..7bce4a1 100644
--- a/CellframeNodeDiagtool/DiagnosticWorker.h
+++ b/CellframeNodeDiagtool/DiagnosticWorker.h
@@ -9,17 +9,13 @@
 #include <QDesktopServices>
 #include <QSettings>
 
-#include <QNetworkAccessManager>
-#include <QHttpPart>
-#include <QHttpMultiPart>
-#include <QNetworkReply>
-
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
 #include "NotifyWorker.h"
+#include "DiagDataSendingWorker.h"
 
 #ifdef Q_OS_LINUX
     #include "LinuxDiagnostic.h"
@@ -61,8 +57,7 @@ private:
 
     QJsonDocument m_lastSendedPack;
 
-    QStringList m_urls;
-    QNetworkAccessManager *m_netMngr;
+    DiagDataSendingWorker *s_diagDataWorker;
 
     bool m_initStatus{false};
     bool m_isSendData{true};
-- 
GitLab