251 lines
7.4 KiB
C++
Executable File
251 lines
7.4 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Websocket Server to connect to NGSConnector
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "ngs_handler.h"
|
|
#include "ngs_connector.h"
|
|
#include "web_socket_interface.h"
|
|
#include "ws_telegrams.h"
|
|
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QJsonParseError>
|
|
|
|
#include <QTimer>
|
|
|
|
namespace HighLevelArchitecture
|
|
{
|
|
|
|
//
|
|
// class WsInterface
|
|
//
|
|
WsInterface::WsInterface(std::shared_ptr<NgsHandler> ngsHandler, QObject *parent)
|
|
: QObject(parent)
|
|
, m_wsServer(new QWebSocketServer(QStringLiteral("GNA"), QWebSocketServer::NonSecureMode, this))
|
|
, m_ngsHandler(ngsHandler)
|
|
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("HlaTestTool.WsInterface"))
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
WsInterface::~WsInterface()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
for (auto client : qAsConst(m_clients))
|
|
{
|
|
client->disconnect(this);
|
|
client->close();
|
|
}
|
|
qDeleteAll(m_clients);
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
bool WsInterface::init(quint16 listenPort)
|
|
{
|
|
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, listenPort=" << listenPort;
|
|
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, listenPort=" << listenPort;
|
|
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, listenPort=" << listenPort;
|
|
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, listenPort=" << listenPort;
|
|
|
|
if (!m_wsServer->listen(QHostAddress::Any, listenPort))
|
|
{
|
|
WARNING_LOG(m_logger) << "Cannot listen on port " << listenPort << " - aborting";
|
|
return false;
|
|
}
|
|
DEBUG_LOG(m_logger) << "Listening on port " << listenPort;
|
|
connect(m_wsServer, &QWebSocketServer::newConnection,
|
|
this, &WsInterface::onNewConnection);
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, listenPort=" << listenPort;
|
|
return true;
|
|
|
|
}
|
|
|
|
void WsInterface::onNewConnection()
|
|
{
|
|
QWebSocket *clientSocket = m_wsServer->nextPendingConnection();
|
|
if (!clientSocket)
|
|
return;
|
|
|
|
connect(clientSocket, &QWebSocket::textMessageReceived,
|
|
this, &WsInterface::onTextMessageReceived);
|
|
connect(clientSocket, &QWebSocket::disconnected,
|
|
this, &WsInterface::onWebSocketDisconnected);
|
|
|
|
NOTICE_LOG(m_logger) << "Websocket connection established, ptr: " << clientSocket;
|
|
m_clients += clientSocket;
|
|
}
|
|
|
|
void WsInterface::onWebSocketDisconnected()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
QWebSocket *ws = qobject_cast<QWebSocket *>(sender());
|
|
if (!ws)
|
|
return;
|
|
NOTICE_LOG(m_logger) << "Websocket connection closed, ptr: " << ws;
|
|
m_clients.remove(ws);
|
|
ws->deleteLater();
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
void WsInterface::onError(QAbstractSocket::SocketError error)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " Error occured, QAbstractSocket::SocketError = " << error;
|
|
}
|
|
|
|
void WsInterface::onTextMessageReceived(const QString &msg)
|
|
{
|
|
NOTICE_LOG(m_logger) << LOGFUNCTION << " START, msg='" << msg << "'";
|
|
|
|
if (msg.isEmpty())
|
|
{
|
|
ERROR_LOG(m_logger) << "Empty message received";
|
|
return;
|
|
}
|
|
DEBUG_LOG(m_logger) << "incoming telegram: " << msg;
|
|
|
|
const QByteArray baJson = msg.toUtf8();
|
|
processMessage(baJson);
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
void WsInterface::processMessage(const QByteArray baJson)
|
|
{
|
|
NOTICE_LOG(m_logger) << LOGFUNCTION << " START";
|
|
|
|
QJsonParseError parseError;
|
|
QJsonDocument doc = QJsonDocument::fromJson(baJson, &parseError);
|
|
|
|
if (parseError.error != QJsonParseError::NoError)
|
|
{
|
|
ERROR_LOG(m_logger) << "Could not parse JSON "
|
|
<< ". Reason: "
|
|
<< parseError.errorString()
|
|
<< "; baJson: '"
|
|
<< baJson << "'";
|
|
return;
|
|
}
|
|
|
|
NOTICE_LOG(m_logger) << "doc1 " << doc.toJson();
|
|
NOTICE_LOG(m_logger) << "doc2 " << doc.toJson(QJsonDocument::Compact) << "<<<";
|
|
|
|
const QJsonObject obj = doc.object();
|
|
const int typeId = obj.value(QStringLiteral("typeId")).toInt();
|
|
const QJsonObject data = obj.value(QStringLiteral("data")).toObject();
|
|
NOTICE_LOG(m_logger) << "Telegram with '" << typeId << "' received";
|
|
|
|
switch (typeId)
|
|
{
|
|
/*
|
|
python:
|
|
|
|
import websocket
|
|
import json
|
|
import time
|
|
ws = websocket.create_connection("ws://192.168.133.73:23456")
|
|
|
|
epoch_time = int(time.time())*1000
|
|
print(epoch_time)
|
|
d = { 'typeId' : 8011, 'data': {'objectId': 4711, 'name': 'myname', 'timestamp': epoch_time, 'activationTime': 12345678, 'isDeactivated': True, 'duration': 10, 'centerPoint':{'lat':52.477,'lon':11.597} } }
|
|
|
|
ws.send(json.dumps(d))
|
|
|
|
# d = { 'typeId' : 8010, 'data': {'objectId': 4711, 'name': 'removeAesObject', 'timestamp': epoch_time} }
|
|
|
|
|
|
|
|
ws.close()
|
|
*/
|
|
|
|
case 8001: // Dummy - neu definieren?
|
|
{
|
|
try
|
|
{
|
|
WsTelegramPosition pos = WsTelegramPosition::fromJson(data);
|
|
|
|
NOTICE_LOG(m_logger) << "type= " << pos.type();
|
|
NOTICE_LOG(m_logger) << "objectId= " << pos.objectId;
|
|
NOTICE_LOG(m_logger) << "name= '" << pos.name << "'";
|
|
NOTICE_LOG(m_logger) << "timestamp= " << pos.timestamp;
|
|
NOTICE_LOG(m_logger) << "lat= " << pos.position.lat;
|
|
NOTICE_LOG(m_logger) << "lon= " << pos.position.lon;
|
|
}
|
|
catch (const JsonException &ex)
|
|
{
|
|
ERROR_LOG(m_logger) << "Could not parse json telegram: "
|
|
<< ", error: " << ex.what();
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 8010: // remove AesObj - neu definieren?
|
|
{
|
|
WsTelegramRemoveAesObject tele;
|
|
try
|
|
{
|
|
tele = WsTelegramRemoveAesObject::fromJson(data);
|
|
|
|
NOTICE_LOG(m_logger) << "type= " << tele.type();
|
|
NOTICE_LOG(m_logger) << "objectId= " << tele.objectId;
|
|
NOTICE_LOG(m_logger) << "name= '" << tele.name << "'";
|
|
NOTICE_LOG(m_logger) << "timestamp= " << tele.timestamp;
|
|
}
|
|
catch (const JsonException &ex)
|
|
{
|
|
ERROR_LOG(m_logger) << "Could not parse json telegram: "
|
|
<< ", error: " << ex.what();
|
|
return;
|
|
}
|
|
// WsTelegramXYObject to ngs/hla
|
|
if (m_ngsHandler && m_ngsHandler->ngsConnector())
|
|
m_ngsHandler->ngsConnector()->removeAesItem(tele.objectId);
|
|
|
|
break;
|
|
}
|
|
|
|
case 8011: // create/updateMineField - neu definieren?
|
|
{
|
|
WsTelegramMineFieldObject mf;
|
|
try
|
|
{
|
|
mf = WsTelegramMineFieldObject::fromJson(data);
|
|
|
|
NOTICE_LOG(m_logger) << "type= " << mf.type();
|
|
NOTICE_LOG(m_logger) << "objectId= " << mf.objectId;
|
|
NOTICE_LOG(m_logger) << "name= '" << mf.name << "'";
|
|
NOTICE_LOG(m_logger) << "timestamp= " << std::setprecision(15) << mf.timestamp;
|
|
NOTICE_LOG(m_logger) << "activationTime= " << std::setprecision(15) << mf.activationTime;
|
|
NOTICE_LOG(m_logger) << "duration= " << mf.duration;
|
|
NOTICE_LOG(m_logger) << "isDeactivated= " << mf.isDeactivated;
|
|
NOTICE_LOG(m_logger) << "lat= " << mf.area2D.centerPoint.lat << " - lon= " << mf.area2D.centerPoint.lon;
|
|
NOTICE_LOG(m_logger) << "width= " << mf.area2D.width << " - height= " << mf.area2D.height;
|
|
}
|
|
catch (const JsonException &ex)
|
|
{
|
|
ERROR_LOG(m_logger) << "Could not parse json telegram: "
|
|
<< ", error: " << ex.what();
|
|
return;
|
|
}
|
|
|
|
// WsTelegramXYObject to ngs/hla
|
|
if (m_ngsHandler && m_ngsHandler->ngsConnector())
|
|
m_ngsHandler->ngsConnector()->guezMineField(mf);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
ERROR_LOG(m_logger) << "Telegram with typeId '" << typeId << "' not handled in switch"
|
|
<< ", doc= " << doc.toJson(QJsonDocument::Compact) << "<<<";
|
|
}
|
|
} // switch
|
|
}
|
|
|
|
} // HighLevelArchitecture
|