C

Monitor: Verifying the Rendering Output

// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial

// This file is part of the Qt Safe Renderer module
#include <QThread>
#include <QDebug>
#include <signal.h>

extern "C" {
#include <QtSafeMonitor/message.h>
#include <QtSafeMonitor/eventProcessor.h>
#include <QtSafeMonitor/errorcode.h>
#include <QtSafeMonitor/qsafeglobal.h>
#include "controller.h"
#include "sendevent.h"
}

#define MONITOR_MSG_BUF_SIZE 128U
static volatile sig_atomic_t running = 1;

static void ctrlCHandler(qint32 receivedSignal)
{
    if (receivedSignal == SIGINT) {
        running = 0;
    } else {
        /* Nothing */
    }
}

static void defaultErrorHandler(ErrorCode errorType, int64_t arg1, int64_t arg2)
{
    qWarning() << "Error:" << errorCodeToString(errorType);
    qWarning() << "Error arguments:" << arg1 << "," << arg2;
}

static void requestOutpuVerificationUpdate(qchar *msgBuf, const size_t len, errorFunc errorHandler)
{
    quint32 index = 0U;

    while (getEventOutputVerificationVerifyItem(index, msgBuf, len) != NULL) {
        if (sendEvent(msgBuf, len) < 0) {
            errorHandler(FailedToSendRequest, 0, __LINE__);
            break;
        } else {
            index++;
        }
    }
}

static qint32 verifyEventOutput(qchar *msgBuf, const size_t len, errorFunc errorHandler)
{
    qint32 ret = -1;

    getEventOutputVerificationRequest(msgBuf, len);

    // Send the event and then receive a reply. Use sendEventWithReply for this.
    if (sendEventWithReply(msgBuf, len, msgBuf, len) == 0) {
        // Successful reply received.
        ret = processEvent(msgBuf, len, errorHandler);
    } else {
        errorHandler(FailedToReceiveMessage, (int64_t)ret, __LINE__);
    }

    return ret;
}

static void changeState(qchar *msgBuf, const size_t len, errorFunc errorHandler)
{
    qint32 ret = -1;

    getNextEventStateMessage(msgBuf, len);

    ret = sendEvent(msgBuf, len);
    if (ret < 0) {
        errorHandler(FailedToSendRequest, (int64_t)ret, __LINE__);
    } else {
        /* Nothing */
    }
}

static void monitorLoop(void)
{
    qchar msgBuf[MONITOR_MSG_BUF_SIZE];
    qint32 ret;

    while (running > 0) {
        requestOutpuVerificationUpdate(msgBuf, sizeof(msgBuf), &defaultErrorHandler);
        QThread::sleep(1);

        do {
            ret = verifyEventOutput(msgBuf, sizeof(msgBuf), &defaultErrorHandler);
        } while (ret > 0);

        changeState(msgBuf, sizeof(msgBuf), &defaultErrorHandler);
        QThread::sleep(1);
    }
}

qint32 main(qint32 argc, char *argv[])
{
    qint32 c = 0;
    qint32 ret = 0;

    if (signal(SIGINT, &ctrlCHandler) == SIG_ERR) { /* polyspace MISRA-C:20.8 [Not a defect:Low] "The code has been manually verified to be OK" */
        ret = 3;
    } else {
        monitorLoop();
    }
    return ret;
}