/** * @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 #include #include #include namespace HighLevelArchitecture { // // class WsInterface // WsInterface::WsInterface(std::shared_ptr 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(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