C
Message Proxy: Testing Qt Safe Renderer Messaging Interface
// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial // This file is part of the Qt Safe Renderer module #include <QTcpSocket> #include <QtCore> #include <QtSafeRenderer/qsafeevent.h> #include "server.h" Server::Server(const quint16 port, QObject *parent) : QObject(parent) { runServer(port); } void Server::runServer(const quint16 port) { m_tcpServer = new QTcpServer(this); if (!m_tcpServer->listen(QHostAddress::Any, port)) { qCritical() << "Unable to start the server: " << m_tcpServer->errorString(); return; } connect(m_tcpServer, &QTcpServer::newConnection, this, &Server::newConnection); QString ipAddress; QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses(); // use the first non-localhost IPv4 address for (int i = 0U; i < ipAddressesList.size(); ++i) { if (ipAddressesList.at(i) != QHostAddress::LocalHost && ipAddressesList.at(i).toIPv4Address()) { ipAddress = ipAddressesList.at(i).toString(); break; } } // if we did not find one, use IPv4 localhost if (ipAddress.isEmpty()) ipAddress = QHostAddress(QHostAddress::LocalHost).toString(); qDebug() << "The server is running on: " << ipAddress << ":" << m_tcpServer->serverPort(); } void Server::newConnection() { QTcpSocket *clientConnection = m_tcpServer->nextPendingConnection(); connect(clientConnection, &QAbstractSocket::disconnected, clientConnection, &QObject::deleteLater); connect(clientConnection, &QAbstractSocket::readyRead, this, &Server::readData); } static bool sendReply(QTcpSocket &clientConnection, const SafeRenderer::QSafeEvent &reply) { bool success = false; const quint64 bytesWritten = clientConnection.write(reinterpret_cast<const char*>(reply.rawData()), reply.messageLength); if (bytesWritten == reply.messageLength) { success = true; } else { qDebug() << "Failed to send reply to client"; } return success; } void Server::handleVerificationRequest(const SafeRenderer::QSafeEvent &request, QTcpSocket &clientConnection) { SafeRenderer::QSafeEvent reply; SafeRenderer::QSafeEventSender::QSafeEventSenderStatus status = m_messageSender.sendEvent(request, reply); if (status == SafeRenderer::QSafeEventSender::Success) { sendReply(clientConnection, reply); } else { qDebug() << "Failed to send request to renderer."; } } void Server::readData() { QTcpSocket *clientConnection = qobject_cast<QTcpSocket *>(QObject::sender()); if (clientConnection) { unsigned char dataBuffer[SafeRenderer::QSafeEvent::messageLength]; quint32 datalength = 0U; do { QByteArray data = clientConnection->read(SafeRenderer::QSafeEvent::messageLength); datalength = data.length(); if (datalength == SafeRenderer::QSafeEvent::messageLength) { memcpy (&dataBuffer[0], data.data(), SafeRenderer::QSafeEvent::messageLength); SafeRenderer::QSafeEvent event(dataBuffer); if (event.getEventId() == SafeRenderer::EventOutputVerificationStatusRequest) { handleVerificationRequest(event, *clientConnection); } else { m_messageSender.sendEvent(event); } } } while (datalength > 0U); } }