/*! * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * \copyright \n * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, \n * IN PART OR IN WHOLE, \n * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. \n * * \file main.cpp * \date 2019/09/30 * \author Behrouz NematiPour * */ /*! * \mainpage UI Software Design Description * \section Detailed Description * This document has been generated by Doxygen.\n * This document describes the detail description of the UI Application Software design.\n * UI Application starts by Application Initialization which happens in \ref main.cpp "Initialization section".\n */ // Qt #include #include #include #include #include #include #include // Project #include "maintimer.h" #include "caninterface.h" #include "frameinterface.h" #include "messageacknowmodel.h" #include "messagedispatcher.h" #include "applicationcontroller.h" #include "guicontroller.h" #include "logger.h" #include "DriveWatcher.h" #include "threads.h" // kernel #include /*! * \brief signalhandler * \details When application terminates it quits gracefully. * \param sig - The Linux signal causes the termination. */ void signalhandler(int sig) { if (sig == SIGINT) { qDebug() << QObject::tr("Application terminated by SIGINT"); qApp->quit(); } else if (sig == SIGTERM) { qDebug() << QObject::tr("Application terminated by SIGTERM"); qApp->quit(); } } int gFakeInterval = 0 ; QByteArray gFakeData = "" ; const char *gFakeData_default = "00" ; bool gSendEmptyKeepAwake = false ; bool gFakeSeqAtBegin = false ; bool gDisableUnhandledReport = false ; bool gConsoleoutFrameInterface = false ; bool gConsoleoutCanInterface = false ; /*! * \brief commandlineParse * \details parses the command line arguments \n * Usage: ./denali [options] \n * Denali \n * \n * Options: \n * -h, --help Displays this help. \n * -v, --version Displays version information. \n * -c, --canOut Show the Can Frame Output \n * -m, --msgOut Show the Message Output \n * -0, --enable-keep-awake Enable send low priority, empty message on \n * the CANBus just to keep UI board CAN driver \n * awake \n * -i, --fake-interval Test fake message interval(ms) \n * -f, --fake-message Test fake message data \n * will use default sequenced long fake message \n * if set to 00(default) \n * will used only if correct intger value \n * assigned for interval option \n */ void commandlineParse() { QCommandLineParser parser; parser.setApplicationDescription(QApplication::applicationName()); parser.addHelpOption(); parser.addVersionOption(); // --- -c : canOut QCommandLineOption optionConsoleoutCanInterface( QStringList() << "c" << "canOut", QCoreApplication::translate("main", "Show the Can Frame Output")); parser.addOption(optionConsoleoutCanInterface); // --- -m : msgOut QCommandLineOption optionConsoleoutFrameInterface( QStringList() << "m" << "msgOut", QCoreApplication::translate("main", "Show the Message Output")); parser.addOption(optionConsoleoutFrameInterface); // --- -0 : enable-keep-awake (the fast mode) QCommandLineOption optionSendEmptyKeepAwake(QStringList() << "0" << "enable-keep-awake", QCoreApplication::translate("main", "Enable send low priority, empty message on the CANBus just to keep UI board CAN driver awake")); parser.addOption(optionSendEmptyKeepAwake); // --- -i : fake-interval QCommandLineOption optionFakeInterval( QStringList() << "i" << "fake-interval", QCoreApplication::translate("main", "Test fake message interval(ms)"), QCoreApplication::translate("main", "interval")); parser.addOption(optionFakeInterval); // --- -f : fake-message QCommandLineOption optionFakeData( QStringList() << "f" << "fake-message", QCoreApplication::translate("main", "Test fake message data\n" "will use default sequenced long fake message if set to 00(default)\n" "will used only if correct intger value assigned for interval option"), QCoreApplication::translate("main", "data")); parser.addOption(optionFakeData); // --- -b : fake-message-seq-atbegin QCommandLineOption optionFakeSeqAtBegin( QStringList() << "b" << "fake-message-seq-atbegin", QCoreApplication::translate("main", "Test fake message sequence at the beginning of the frame")); parser.addOption(optionFakeSeqAtBegin); // --- -u : disable-unhandled-report QCommandLineOption optionDisableUnhandledReport(QStringList() << "u" << "disable-unhandled-report", QCoreApplication::translate("main", "Disable unhandled messages report as an error in the log")); parser.addOption(optionDisableUnhandledReport); // --- parse command lines parser.process(*qApp); gConsoleoutCanInterface = parser.isSet(optionConsoleoutCanInterface ); gConsoleoutFrameInterface = parser.isSet(optionConsoleoutFrameInterface ); gDisableUnhandledReport = parser.isSet(optionDisableUnhandledReport ); if (parser.isSet(optionSendEmptyKeepAwake)) gSendEmptyKeepAwake = true; bool ok = false; if (parser.isSet(optionFakeInterval)) { int interval = parser.value(optionFakeInterval).toInt(&ok); if (ok) { gFakeInterval = interval; if (parser.isSet(optionFakeData)) { gFakeData = parser.value(optionFakeData).toLatin1(); } else { gFakeData = gFakeData_default; } if (parser.isSet(optionFakeSeqAtBegin)) { gFakeSeqAtBegin = true; } gFakeData = QByteArray::fromHex(gFakeData); } } } /*! * \brief setApplicationVersion * \details sets up the application version regarding the environment valiables * which are set by bamboo and if those are not set value of 0 will be used * and revision(build) version will be set to current date/time. */ void setApplicationVersion() { QString ver_major = QString("%1").arg(VER_MAJOR); if (ver_major.isEmpty()) { ver_major = VER_MAJOR_DEV; } QString ver_minor = QString("%1").arg(VER_MINOR); if (ver_minor.isEmpty()) { ver_minor = VER_MINOR_DEV; } QString ver_micro = QString("%1").arg(VER_MICRO); if (ver_micro.isEmpty()) { ver_micro = VER_MICRO_DEV; } QString ver_revis = QString("%1").arg(VER_REVIS); if (ver_revis.isEmpty()) { ver_revis = VER_REVIS_DEV; } QCoreApplication::setApplicationVersion(QString("%1.%2.%3.%4") .arg(ver_major) .arg(ver_minor) .arg(ver_micro) .arg(ver_revis)); } #ifdef UNIT_TEST #include TEST_CLASS_INCLUDE QTEST_MAIN(TEST_CLASS_NAME) #else /*! \brief Application Initialization\n * Some part of the application need to be initialized out of any thread. * So is initialized here to be initialized in the main thread. * this section also includes: */ int main(int argc, char *argv[]) { #ifndef SQUISH_COCO_BULD signal(SIGINT , signalhandler); signal(SIGTERM, signalhandler); #endif //! - Qt Application initialization and parameters settings // Qt Core Application parameters settings QApplication::setApplicationName(QLatin1String("Denali")); QApplication::setOrganizationName(QLatin1String("Diality Inc.")); //! - Check the required font(s) present and can be loaded QApplication::setFont(QFont("Barlow")); // Qt Core Application Initialization QApplication app(argc, argv); app.thread()->setObjectName("Main Thread"); //! - Setting the application version regarding the Bamboo build number. setApplicationVersion(); //! - Parse the command line arguments commandlineParse(); //! - Translation initialization QTranslator translator; bool trLoaded = translator.load(QLocale(), app.applicationName(), QLatin1String("_"), QLatin1String(":/translations")); if (trLoaded) { app.installTranslator(&translator); } //! - Initializing required thread types Threads::registerTypes(); //! - Initializing Logger _Logger.init(Threads::_Logger_Thread); LOG_EVENT("UI," + QObject::tr("Application %1 Started,%2") .arg(app.applicationName ()) .arg(app.applicationVersion()) ); if (gFakeInterval) { QString msg = " ~~ !!!!! APPLICATION RUNNING IN THE TEST MODE !!!!! ~~ "; qDebug() << msg; LOG_EVENT(" \n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ " " \n " + msg + " \n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "); } //! - Initializing USB Watcher _DriveWatcher.init(Threads::_DriveWatcher_Thread); //! - Initializing CanBus Interface if (_CanInterface.init(Threads::_CanFrame_Thread)) { _CanInterface.enableConsoleOut(gConsoleoutCanInterface); } //! - Initializing CanBus Message Handler _FrameInterface.init(Threads::_CanFrame_Thread); //! - Initializing the CanBus Message Acknowledgment Model _MessageAcknowModel.init(Threads::_CanAcknow_Thread); //! - Initializing CanBus Message Dispatcher if (_MessageDispatcher.init(Threads::_CanMessage_Thread)) { _MessageDispatcher.enableConsoleOut(gConsoleoutFrameInterface); } //! - Initializing Application Controller _ApplicationController.init(Threads::_Application_Thread); ////! - Initializing GUI Controller _GuiController.init(Threads::_Application_Thread); //! - Initializing Main Timer _MainTimer.init(); //! - Initialize the Qml Viewer and starts GUI int app_exec = -1; if ( startGui() ) { app_exec = app.exec(); } // Due to Qt Error the CAN Device cannot be disable/enable from withing another thread // (other than main thread which is the owner of the CanDevice). // So it needs to be done here in main thread. _CanInterface.quitDevice(); Threads::quitThreads(); return app_exec; } #endif