/** * @RDE_HEADER@ * Display Panel Simulator TCP Server; observes the given port and emits the incoming messages * $Id$ * $HeadURL$ * $Author$ * Created by Florian Schult, SLSE, 2016-03-18 */ //===Include specifications================================================== #include "displayPanelSimulatorTcpServer.h" #include #include #include //===DisplayPanelSimulatorTcpServer========================================== //---Constructors/Destructors------------------------------------------------ /** * Constructor. */ DisplayPanelSimulatorTcpServer::DisplayPanelSimulatorTcpServer(QObject *parent) : QObject(parent) , mp_server(new QTcpServer(this)) , mp_socket(nullptr) , m_port(0) , m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("DispSim.DisplayPanelSimulatorWidget")) { } /** * Destructor. */ DisplayPanelSimulatorTcpServer::~DisplayPanelSimulatorTcpServer() { delete mp_server; } //---Private slots----------------------------------------------------------- /** * Handles the 'newConnection' signal of the TCP server. */ void DisplayPanelSimulatorTcpServer::handleServerNewConnection() { mp_socket = mp_server->nextPendingConnection(); connect(mp_socket, &QTcpSocket::readyRead, this, &DisplayPanelSimulatorTcpServer::handleSocketReadyRead); emit debugMessage(m_port, QStringLiteral("Socket connected!"), MSGLVL_DEBUG); } /** * Handles the 'readyRead' signal of the TCP socket. */ void DisplayPanelSimulatorTcpServer::handleSocketReadyRead() { evaluateData(mp_socket->readAll()); } //---Private methods--------------------------------------------------------- /** * Evaluates the received data from the TCP socket. */ void DisplayPanelSimulatorTcpServer::evaluateData(const QByteArray &data) { QByteArray page; QString message; bool ackRequested = false; bool dataOk = false; if (data.isEmpty()) return; char cs = data.at(data.size() - 1); char csCalc = calculateChecksum(data); if (data.size() >= 5) ackRequested = data[4] & 0x08; if (data.size() < 10) { message = tr("Message to small!"); ERROR_LOG(m_logger) << "Error in message data evaluation"; } else if (data[0] != 0) { message = tr("No SYNC in Message!"); ERROR_LOG(m_logger) << "Error in message data evaluation"; } else if (cs != csCalc) { const QByteArray ba = "Wrong Checksum: 0x" + QByteArray::number(cs, 16) + " <-> 0x" + QByteArray::number(csCalc, 16); qDebug() << ba.data(); message = QString::fromLatin1(ba); ERROR_LOG(m_logger) << "Error in message data evaluation"; } else { page = data.mid(5, 3); const QByteArray ba = data.mid(11, (data.size() - 13)); message = QString::fromUtf8(ba.data(), ba.size()); emit plainMessage(message); emit debugMessage(m_port, tr("New message received: %1").arg(message), MSGLVL_INFO); INFO_LOG(m_logger) << "New message received"; dataOk = true; } if (!dataOk/* || page == "001"*/) { emit debugMessage(m_port, message, MSGLVL_ERROR); ERROR_LOG(m_logger) << "Error in message data evaluation"; } if (ackRequested) { if (dataOk) { mp_socket->write("\x06"); // ACK } else { mp_socket->write("\x15"); // NAK } } } /** * Calculates the checksum of the received data from the TCP socket. */ char DisplayPanelSimulatorTcpServer::calculateChecksum(const QByteArray &data) { char checksum = 0; for (const auto c : data) checksum ^= c; return checksum; } //---Public methods---------------------------------------------------------- /** * Starts the TCP server. */ void DisplayPanelSimulatorTcpServer::start(int port) { m_port = port; connect(mp_server, &QTcpServer::newConnection, this, &DisplayPanelSimulatorTcpServer::handleServerNewConnection); emit debugMessage(m_port, tr("Waiting for connection"), MSGLVL_DEBUG); if (!mp_server->listen(QHostAddress::Any, port)) { emit debugMessage(m_port, tr("Opening socket failed! May be in use!"), MSGLVL_ERROR); ERROR_LOG(m_logger) << "Opening socket failed; Port: " << port; } } //===========================================================================