Add class DeviceControllerDiag to supervise DeviceController state
This commit is contained in:
		@@ -71,6 +71,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
 | 
			
		||||
HEADERS += \
 | 
			
		||||
    include/interfaces.h \
 | 
			
		||||
    src/ATBAPP/ATBAPPplugin.h \
 | 
			
		||||
    src/ATBAPP/DeviceControllerDiag.h \
 | 
			
		||||
    src/ATBAPP/DeviceControllerInterface.h \
 | 
			
		||||
    src/ATBAPP/ATBHealthEvent.h \
 | 
			
		||||
    src/ATBAPP/ATBMachineEvent.h \
 | 
			
		||||
@@ -81,6 +82,7 @@ SOURCES += \
 | 
			
		||||
    src/ATBAPP/ATBHealthEvent.cpp \
 | 
			
		||||
    src/ATBAPP/ATBMachineEvent.cpp \
 | 
			
		||||
    src/ATBAPP/ATBDeviceControllerPlugin.cpp \
 | 
			
		||||
    src/ATBAPP/DeviceControllerDiag.cpp \
 | 
			
		||||
    src/ATBAPP/Utils.cpp
 | 
			
		||||
 | 
			
		||||
DISTFILES += \
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,8 @@
 | 
			
		||||
 | 
			
		||||
#include "src/ATBAPP/DeviceControllerInterface.h"
 | 
			
		||||
#include "src/ATBAPP/ATBAPPplugin.h"
 | 
			
		||||
#include "src/ATBAPP/DeviceControllerDiag.h"
 | 
			
		||||
 | 
			
		||||
#include "version.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -94,6 +96,9 @@ private:
 | 
			
		||||
 | 
			
		||||
   hwinf* hw;
 | 
			
		||||
 | 
			
		||||
   DeviceControllerDiag* diag;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   QTextCodec *codec;
 | 
			
		||||
 | 
			
		||||
   bool private_loadCashAgentLib(QString pluginName);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										373
									
								
								src/ATBAPP/DeviceControllerDiag.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										373
									
								
								src/ATBAPP/DeviceControllerDiag.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,373 @@
 | 
			
		||||
#include "DeviceControllerDiag.h"
 | 
			
		||||
 | 
			
		||||
#include <QCoreApplication>
 | 
			
		||||
#include <QUuid>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
 | 
			
		||||
DeviceControllerDiag::DeviceControllerDiag(QObject *parent)
 | 
			
		||||
    : QObject(parent)
 | 
			
		||||
    , eventReceiver(nullptr)
 | 
			
		||||
    , isRequestRunning(false)
 | 
			
		||||
    , flagInterruptDiag(false)
 | 
			
		||||
{
 | 
			
		||||
    diagRequestTimeoutTimer = new QTimer(this);
 | 
			
		||||
    diagRequestTimeoutTimer->setInterval(1000*20);  // 20s
 | 
			
		||||
    diagRequestTimeoutTimer->setSingleShot(true);
 | 
			
		||||
    connect(diagRequestTimeoutTimer, &QTimer::timeout, this, &DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void DeviceControllerDiag::init(hwinf *hw, QObject* eventReceiver)
 | 
			
		||||
{
 | 
			
		||||
    this->hw = hw;
 | 
			
		||||
    this->eventReceiver = eventReceiver;
 | 
			
		||||
 | 
			
		||||
    // make a system check on startup:
 | 
			
		||||
    QTimer::singleShot(2000, this, &DeviceControllerDiag::diagRequest);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void DeviceControllerDiag::diagRequest()
 | 
			
		||||
{
 | 
			
		||||
    qCritical() << "DeviceControllerDiag::diagRequest()";
 | 
			
		||||
 | 
			
		||||
    if (this->isRequestRunning) {
 | 
			
		||||
        qCritical() << "DeviceControllerDiag::diagRequest() is already running";
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    this->isRequestRunning = true;
 | 
			
		||||
    this->diagRequestTimeoutTimer->start();
 | 
			
		||||
 | 
			
		||||
    this->private_startDiag();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout()
 | 
			
		||||
{
 | 
			
		||||
    qCritical() << "DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout()";
 | 
			
		||||
    this->flagInterruptDiag = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DeviceControllerDiag::private_startDiag()
 | 
			
		||||
{
 | 
			
		||||
    // check for DiagRequestTimeoutTimerTimeout:
 | 
			
		||||
    if (this->flagInterruptDiag) {
 | 
			
		||||
        qCritical() << "DeviceControllerDiag::private_startDiag() interrupted!";
 | 
			
		||||
        this->private_finishedDiag(0xff);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool result;
 | 
			
		||||
    result = hw->sys_areDCdataValid();
 | 
			
		||||
 | 
			
		||||
    if (result) {
 | 
			
		||||
        QTimer::singleShot(200, this, &DeviceControllerDiag::sys_superviseSystem);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        qCritical() << "DeviceControllerDiag::private_startDiag() DCdata is not valid";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        this->private_finishedDiag(0xfe);
 | 
			
		||||
 | 
			
		||||
        // try it again
 | 
			
		||||
        // -> this results in a seg. fault after ~10 loops!
 | 
			
		||||
        //QTimer::singleShot(200, this, &DeviceControllerDiag::private_startDiag);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DeviceControllerDiag::sys_superviseSystem()
 | 
			
		||||
{    // this function proofs if vending is possible depending of doors state
 | 
			
		||||
 | 
			
		||||
    struct T_dynamicCondition *dynMaCond=0;
 | 
			
		||||
    struct T_moduleCondition *modCond=0;
 | 
			
		||||
 | 
			
		||||
    // check for DiagRequestTimeoutTimerTimeout:
 | 
			
		||||
    if (this->flagInterruptDiag) {
 | 
			
		||||
        qCritical() << "DeviceControllerDiag::sys_superviseSystem() interrupted!";
 | 
			
		||||
        this->private_finishedDiag(0xff);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!hw->sys_areDCdataValid())
 | 
			
		||||
    {
 | 
			
		||||
        // es gibt keinerlei gültige Daten vom DC
 | 
			
		||||
        qCritical() << "DeviceControllerDiag::sys_superviseSystem() no valid data!";
 | 
			
		||||
        this->private_finishedDiag(0xfe);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // jetzt sind die DC-Daten aktuell, also reinholen:
 | 
			
		||||
    hw->sys_getDynMachineConditions(dynMaCond);
 | 
			
		||||
    hw->sys_getDeviceConditions(modCond);
 | 
			
		||||
 | 
			
		||||
    if (!modCond->allModulesChecked)
 | 
			
		||||
    {
 | 
			
		||||
        // noch keine Testergebnisse
 | 
			
		||||
        if (dynMaCond->startupTestIsRunning) {
 | 
			
		||||
            // TODO?
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        QTimer::singleShot(200, this, &DeviceControllerDiag::sys_superviseSystem);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // all doors: 99: undefined  0:closed  1:open
 | 
			
		||||
    if (dynMaCond->lowerDoor || dynMaCond->upperDoor) {
 | 
			
		||||
        // Service or battery door is open, goto INTRUSION MODE
 | 
			
		||||
        qCritical() << "DeviceControllerDiag::sys_superviseSystem() Service or battery door is open, goto INTRUSION MODE";
 | 
			
		||||
        this->private_finishedDiag(0xFD);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (dynMaCond->middleDoor) {
 | 
			
		||||
        // vault door is open, goto INTRUSION MODE
 | 
			
		||||
        qCritical() << "DeviceControllerDiag::sys_superviseSystem() vault door is open, goto INTRUSION MODE";
 | 
			
		||||
        this->private_finishedDiag(0xFE);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t proposedError = sub_componentAssessment();
 | 
			
		||||
    if (proposedError) {
 | 
			
		||||
        // All doors are closed but errors found, goto OOO MODE (out-of-order)
 | 
			
		||||
        qCritical() << "DeviceControllerDiag::sys_superviseSystem() All doors are closed but errors found, goto OOO MODE (out-of-order)";
 | 
			
		||||
        this->private_finishedDiag(proposedError);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // everything fine
 | 
			
		||||
    qCritical() << "DeviceControllerDiag::sys_superviseSystem() everything fine";
 | 
			
		||||
    this->private_finishedDiag(0x00);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t DeviceControllerDiag::sub_componentAssessment()
 | 
			
		||||
{
 | 
			
		||||
    // this function decides if vending mode is possible, independant from door
 | 
			
		||||
    // return >0 in case of error
 | 
			
		||||
 | 
			
		||||
    struct T_moduleCondition *modCond=0;
 | 
			
		||||
    hw->sys_getDeviceConditions(modCond);
 | 
			
		||||
 | 
			
		||||
    struct T_dynamicCondition *dynMaCond=0;
 | 
			
		||||
    hw->sys_getDynMachineConditions(dynMaCond);
 | 
			
		||||
 | 
			
		||||
    struct T_devices *devPara=0;
 | 
			
		||||
    if (modCond->rtc>=200)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if (modCond->printer==200 || modCond->printer==201)   // 200: not connected  201: printer-HW-error  202: no paper
 | 
			
		||||
        return 2;
 | 
			
		||||
    if (modCond->printer==202)
 | 
			
		||||
        return 3;
 | 
			
		||||
 | 
			
		||||
    if (modCond->coinBlocker>=200)
 | 
			
		||||
        return 4;
 | 
			
		||||
    if (modCond->mdbBus>=200)
 | 
			
		||||
        return 5;
 | 
			
		||||
    if (modCond->intEe>=200)
 | 
			
		||||
        return 6;
 | 
			
		||||
 | 
			
		||||
    if (devPara->kindOfCoinChecker==1 || devPara->kindOfCoinChecker==2)  // 0: without  1=EMP820   2=EMP900    3=currenza c²	(MW)
 | 
			
		||||
    {
 | 
			
		||||
        if (modCond->coinChecker>=200 || modCond->coinEscrow>=200)
 | 
			
		||||
        {
 | 
			
		||||
            // Fehler Münzver.
 | 
			
		||||
            return 7;
 | 
			
		||||
        }
 | 
			
		||||
        if (modCond->coinSafe>200)           // 200: kasse fehlt 201: voll  100:fast voll  1:ok
 | 
			
		||||
        {
 | 
			
		||||
            return 8;
 | 
			
		||||
        }
 | 
			
		||||
    } else
 | 
			
		||||
    if (devPara->kindOfCoinChecker==3)
 | 
			
		||||
    {
 | 
			
		||||
        if (modCond->changer>=200)
 | 
			
		||||
        {
 | 
			
		||||
            // Fehler Münzver.
 | 
			
		||||
            return 7;
 | 
			
		||||
        }
 | 
			
		||||
        if (modCond->coinSafe>200)           // 200: kasse fehlt 201: voll  100:fast voll  1:ok
 | 
			
		||||
        {
 | 
			
		||||
            return 8;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( modCond->billReader>=200 && devPara->BillAcceptor>0)
 | 
			
		||||
    {
 | 
			
		||||
        // Fehler BNA
 | 
			
		||||
        return 9;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (dynMaCond->onAlarm>0)
 | 
			
		||||
        return 10;
 | 
			
		||||
 | 
			
		||||
    if (dynMaCond->modeAbrech>0)
 | 
			
		||||
        return 11;
 | 
			
		||||
 | 
			
		||||
    if (dynMaCond->nowCardTest>0)
 | 
			
		||||
        return 12;
 | 
			
		||||
 | 
			
		||||
    if (dynMaCond->startupTestIsRunning>0)
 | 
			
		||||
        return 13;
 | 
			
		||||
 | 
			
		||||
    if (modCond->voltage>=200)
 | 
			
		||||
        return 14;
 | 
			
		||||
    if (modCond->temper>=200)
 | 
			
		||||
        return 15;
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t DeviceControllerDiag::sys_getSystemErrors()
 | 
			
		||||
{
 | 
			
		||||
    // 0: everything fine  1..15: errors
 | 
			
		||||
    /*  1: real time clock error
 | 
			
		||||
        2: printer error
 | 
			
		||||
        3: no paper
 | 
			
		||||
        4: coin blocker
 | 
			
		||||
        5: mdb error
 | 
			
		||||
        6: mem error int.ee.
 | 
			
		||||
        7: error coin validator
 | 
			
		||||
        8: coin safe missed or full
 | 
			
		||||
        9: bill acceptor error
 | 
			
		||||
        10: alarm / intrusion
 | 
			
		||||
        11: cash box change is ongoing
 | 
			
		||||
        12: card test running
 | 
			
		||||
        13: startup-test is running
 | 
			
		||||
        14: voltage error
 | 
			
		||||
        15: temperature error
 | 
			
		||||
    */
 | 
			
		||||
    return this->sub_componentAssessment();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief DeviceControllerDiag::private_finishedDiag
 | 
			
		||||
 * @param result - result value from 'sub_componentAssessment()',
 | 
			
		||||
 *               - 0xFF on timer interrupt
 | 
			
		||||
 *               - 0xFE no valid data from DeviceController
 | 
			
		||||
 *               - 0xFD Service or battery door is open
 | 
			
		||||
 *               - 0xFE vault door is open
 | 
			
		||||
 */
 | 
			
		||||
void DeviceControllerDiag::private_finishedDiag(uint8_t result)
 | 
			
		||||
{
 | 
			
		||||
    this->diagRequestTimeoutTimer->stop();
 | 
			
		||||
    this->isRequestRunning  = false;
 | 
			
		||||
    this->flagInterruptDiag = false;
 | 
			
		||||
 | 
			
		||||
    if (result == 0) return;
 | 
			
		||||
 | 
			
		||||
    qCritical() << "DeviceControllerDiag::private_finishedDiag() result: " << result;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (this->eventReceiver == nullptr) {
 | 
			
		||||
        qCritical() << "DeviceControllerDiag: no eventReceiver";
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (result > 15 && result != 0xFE) return;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Errors are in this range 1...15:
 | 
			
		||||
    QString eventId = QUuid::createUuid().toString(QUuid::WithoutBraces).mid(0, 8);
 | 
			
		||||
    QString eventName;
 | 
			
		||||
    EVENT_CLASS eventClass = EVENT_CLASS::STATE;
 | 
			
		||||
    QString parameter;
 | 
			
		||||
    switch (result) {
 | 
			
		||||
    case 1:    // real time clock error
 | 
			
		||||
        eventName  = "E001";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "real time clock error";
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:    // printer error
 | 
			
		||||
        eventName  = "E002";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "printer error";
 | 
			
		||||
        break;
 | 
			
		||||
    case 3:    // no paper
 | 
			
		||||
        eventName  = "E003";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "no paper";
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:    // coin blocker
 | 
			
		||||
        eventName  = "E004";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "coin blocker";
 | 
			
		||||
        break;
 | 
			
		||||
    case 5:    // mdb error
 | 
			
		||||
        eventName  = "E005";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "mdb error";
 | 
			
		||||
        break;
 | 
			
		||||
    case 6:    // mem error int.ee.
 | 
			
		||||
        eventName  = "E006";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "mem error int.ee.";
 | 
			
		||||
        break;
 | 
			
		||||
    case 7:    // error coin validator
 | 
			
		||||
        eventName  = "E007";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "error coin validator";
 | 
			
		||||
        break;
 | 
			
		||||
    case 8:    // coin safe missed or full
 | 
			
		||||
        eventName  = "E008";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "coin safe missed or full";
 | 
			
		||||
        break;
 | 
			
		||||
    case 9:    // bill acceptor error
 | 
			
		||||
        eventName  = "E009";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "bill acceptor error";
 | 
			
		||||
        break;
 | 
			
		||||
    case 10:   // alarm / intrusion
 | 
			
		||||
        eventName  = "E010";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "alarm / intrusion";
 | 
			
		||||
        break;
 | 
			
		||||
    case 11:   // cash box change is ongoing
 | 
			
		||||
        eventName  = "E011";
 | 
			
		||||
        eventClass = EVENT_CLASS::STATE;
 | 
			
		||||
        parameter  = "cash box change is ongoing";
 | 
			
		||||
        break;
 | 
			
		||||
    case 12:   // card test running
 | 
			
		||||
        eventName  = "E012";
 | 
			
		||||
        eventClass = EVENT_CLASS::STATE;
 | 
			
		||||
        parameter  = "card test running";
 | 
			
		||||
        break;
 | 
			
		||||
    case 13:   // startup-test is running
 | 
			
		||||
        eventName  = "E013";
 | 
			
		||||
        eventClass = EVENT_CLASS::STATE;
 | 
			
		||||
        parameter  = "startup-test is running";
 | 
			
		||||
        break;
 | 
			
		||||
    case 14:   // voltage error
 | 
			
		||||
        eventName  = "E014";
 | 
			
		||||
        eventClass = EVENT_CLASS::ERROR;
 | 
			
		||||
        parameter  = "voltage error";
 | 
			
		||||
        break;
 | 
			
		||||
    case 15:   // temperature error
 | 
			
		||||
        eventName  = "E015";
 | 
			
		||||
        eventClass = EVENT_CLASS::STATE;
 | 
			
		||||
        parameter  = "temperature error";
 | 
			
		||||
        break;
 | 
			
		||||
    case 0xFE:   // no valid data from DeviceController
 | 
			
		||||
        eventName  = "E254";
 | 
			
		||||
        eventClass = EVENT_CLASS::STATE;
 | 
			
		||||
        parameter  = "no valid data from DeviceController";
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ATBMachineEvent *machineEvent = new ATBMachineEvent(
 | 
			
		||||
                eventId,
 | 
			
		||||
                "DC",
 | 
			
		||||
                eventClass,
 | 
			
		||||
                eventName,
 | 
			
		||||
                1,
 | 
			
		||||
                parameter,
 | 
			
		||||
                ""         // second level info
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
    //emit diagResponse(machineEvent);
 | 
			
		||||
 | 
			
		||||
    QCoreApplication::postEvent(eventReceiver, machineEvent);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/ATBAPP/DeviceControllerDiag.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/ATBAPP/DeviceControllerDiag.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
#ifndef DEVICECONTROLLERDIAG_H
 | 
			
		||||
#define DEVICECONTROLLERDIAG_H
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
 | 
			
		||||
#include "ATBMachineEvent.h"
 | 
			
		||||
#include "interfaces.h"
 | 
			
		||||
 | 
			
		||||
class DeviceControllerDiag : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    DeviceControllerDiag(QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
    void init(hwinf* hw, QObject* eventReceiver);
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void diagRequest();
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void diagResponse(ATBMachineEvent* machineEvent);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QObject *eventReceiver;
 | 
			
		||||
    hwinf* hw;
 | 
			
		||||
 | 
			
		||||
    bool isRequestRunning;
 | 
			
		||||
    bool flagInterruptDiag;
 | 
			
		||||
 | 
			
		||||
    QTimer *diagRequestTimeoutTimer;
 | 
			
		||||
 | 
			
		||||
    uint8_t sub_componentAssessment();
 | 
			
		||||
    uint8_t sys_getSystemErrors();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void onDiagRequestTimeoutTimerTimeout();
 | 
			
		||||
 | 
			
		||||
    void private_startDiag();                   // diag entry method
 | 
			
		||||
    void private_finishedDiag(uint8_t result);  // diag exit method
 | 
			
		||||
 | 
			
		||||
    void sys_superviseSystem();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // DEVICECONTROLLERDIAG_H
 | 
			
		||||
		Reference in New Issue
	
	Block a user